NCBI C++ ToolKit
ncbi_http_session.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef CONNECT___NCBI_HTTP_SESSION__HPP
2 #define CONNECT___NCBI_HTTP_SESSION__HPP
3 
4 /* $Id: ncbi_http_session.hpp 100542 2023-08-10 16:43:43Z grichenk $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Author: Aleksey Grichenko
30  *
31  * File Description:
32  * CHttpSession class supporting different types of requests/responses,
33  * headers/cookies/sessions management etc.
34  *
35  */
36 
37 #include <corelib/ncbi_cookies.hpp>
39 
40 
41 /** @addtogroup HttpSession
42  *
43  * @{
44  */
45 
46 
48 
49 
50 // Default retries value.
52 {
53  unsigned short operator()(void) const;
54 };
55 
56 /// Nullable retries for CHttpRequest
58 
59 
61 {
62 public:
63  /// Create empty headers list.
64  CHttpHeaders(void) {}
65 
66  /// Some standard HTTP headers.
67  enum EHeaderName {
68  eCacheControl = 0,
79  eHost
80  };
81 
82  /// Helper class allowing to use both strings and enums as header names.
83  /// The class should not be used explicitly - all conversions are automatic.
85  public:
86  CHeaderNameConverter(const char* name)
87  : m_Name(name) {}
88  CHeaderNameConverter(const string& name)
89  : m_Name(name) {}
91  : m_Name(name) {}
93  : m_Name(CHttpHeaders::GetHeaderName(name)) {}
94  CTempString GetName(void) { return m_Name; }
95  private:
97  };
98 
99  /// List of header values (may be required for headers with multiple values
100  /// like Cookie).
101  typedef vector<string> THeaderValues;
102  /// Map of header name-values, case-insensitive.
104 
105  /// Check if there's at least one header with the name.
106  bool HasValue(CHeaderNameConverter name) const;
107 
108  /// Get number of values with the given name.
109  size_t CountValues(CHeaderNameConverter name) const;
110 
111  /// Get value of the header or empty string. If multiple values
112  /// exist, return the last one.
113  const string& GetValue(CHeaderNameConverter name) const;
114 
115  /// Get all values with the given name.
116  const THeaderValues& GetAllValues(CHeaderNameConverter name) const;
117 
118  /// Remove all existing values with the name, set the new value.
119  /// Throw exception if the name is a reserved one and can not be
120  /// set directly (NCBI-SID, NCBI-PHID). These values should be
121  /// set through CRequestContext, the headers will be added by
122  /// CConn_HttpStream automatically.
123  void SetValue(CHeaderNameConverter name, CTempString value);
124 
125  /// Add new value with the name (multiple values are allowed with
126  /// the same name, the order is preserved).
127  /// Throw exception if the name is a reserved one and can not be
128  /// set directly (NCBI-SID, NCBI-PHID). These values should be
129  /// set through CRequestContext, the headers will be added by
130  /// CConn_HttpStream automatically.
131  void AddValue(CHeaderNameConverter name, CTempString value);
132 
133  /// Remove all values with the given name.
134  void Clear(CHeaderNameConverter name);
135 
136  /// Remove all headers.
137  void ClearAll(void);
138 
139  /// Clear any existing values and copy all headers from 'headers'
140  /// to this object.
141  void Assign(const CHttpHeaders& headers);
142 
143  /// Add values from 'headers' to this object. When merging values
144  /// with the same name, the new values are added after the existing
145  /// ones, so that the new values have higher priority.
146  void Merge(const CHttpHeaders& headers);
147 
148  virtual ~CHttpHeaders(void) {}
149 
150 private:
151  friend class CHttpRequest;
152  friend class CHttpResponse;
153 
154  // Prohibit copying headers.
157 
158  // Check if the name is a reserved one (NCBI-SID, NCBI-PHID).
159  // If yes, log error - these headers must be set in
160  // CRequestContext, not directly.
161  // Return 'false' if the header name is not reserved and a value can
162  // be set safely.
163  bool x_IsReservedHeader(CTempString name) const;
164 
166 
167 public:
168  /// Parse headers from the string (usually provided by a stream callback).
169  /// The new headers are added to the existing ones.
170  void ParseHttpHeader(const CTempString& headers);
171 
172  /// Get all headers as a single string as required by CConn_HttpStream.
173  /// Each header line is terminated by a single HTTP_EOL.
174  string GetHttpHeader(void) const;
175 
176  const THeaders& Get() const { return m_Headers; }
177 
178  /// Get string representation of the given name.
179  static const char* GetHeaderName(EHeaderName name);
180 };
181 
182 
183 /// Per-request proxy settings.
185 {
186 public:
187  CHttpProxy(void) : m_Port(0) {}
188  CHttpProxy(string host, unsigned short port)
189  : m_Host(std::move(host)), m_Port(port) {}
190  CHttpProxy(string host, unsigned short port, string user, string password)
191  : m_Host(std::move(host)), m_Port(port), m_User(std::move(user)), m_Password(std::move(password)) {}
192 
193  bool IsEmpty(void) const { return m_Host.empty(); }
194  const string& GetHost(void) const { return m_Host; }
195  unsigned short GetPort(void) const { return m_Port; }
196  const string& GetUser(void) const { return m_User; }
197  const string& GetPassword(void) const { return m_Password; }
198 
199 private:
200  string m_Host;
201  unsigned short m_Port;
202  string m_User;
203  string m_Password;
204 };
205 
206 
207 class CHttpResponse;
208 class CTlsCertCredentials;
209 
210 
211 /// CHttpSession and CHttpRequest parameters.
213 {
214 public:
215  CHttpParam(void);
216 
217  /// Add all HTTP headers to request.
218  CHttpParam& SetHeaders(const CHttpHeaders& headers);
219  /// Set or replace a single HTTP header, @sa CHttpHeaders::SetValue().
221  /// Add a single HTTP header, @sa CHttpHeaders::AddValue().
223  const CHttpHeaders& GetHeaders(void) const { return *m_Headers; }
224 
225  CHttpParam& SetTimeout(const CTimeout& timeout);
226  const CTimeout& GetTimeout(void) const { return m_Timeout; }
227 
228  CHttpParam& SetRetries(THttpRetries retries);
229  THttpRetries GetRetries(void) const { return m_Retries; }
230 
231  CHttpParam& SetCredentials(shared_ptr<CTlsCertCredentials> credentials);
232  shared_ptr<CTlsCertCredentials> GetCredentials(void) const { return m_Credentials; }
233 
234  CHttpParam& SetProxy(const CHttpProxy& proxy) { m_Proxy = proxy; return *this; }
235  const CHttpProxy& GetProxy(void) const { return m_Proxy; }
236 
237  const CTimeout& GetDeadline() const { return m_Deadline; }
238  CHttpParam& SetDeadline(const CTimeout& deadline) { m_Deadline = deadline; return *this; }
239 
240  ESwitch GetRetryProcessing() const { return m_RetryProcessing; }
241  CHttpParam& SetRetryProcessing(ESwitch on_off) { m_RetryProcessing = on_off; return *this; }
242 
243 private:
247  shared_ptr<CTlsCertCredentials> m_Credentials;
251 };
252 
253 
254 /// Shortcut for GET request. Each request uses a separate session,
255 /// no data like cookies is shared between multiple requests.
256 /// @sa CHttpSession::Get()
258 CHttpResponse g_HttpGet(const CUrl& url, const CHttpParam& param);
259 
260 /// Shortcut for GET request. Each request uses a separate session,
261 /// no data like cookies is shared between multiple requests.
262 /// @sa CHttpSession::Get()
264 CHttpResponse g_HttpGet(const CUrl& url,
265  const CTimeout& timeout = CTimeout(CTimeout::eDefault),
266  THttpRetries retries = null);
267 
268 /// Shortcut for GET request with custom headers. Each request uses a separate
269 /// session, no data like cookies is shared between multiple requests.
270 /// @sa CHttpSession::Get()
272 CHttpResponse g_HttpGet(const CUrl& url,
273  const CHttpHeaders& headers,
274  const CTimeout& timeout = CTimeout(CTimeout::eDefault),
275  THttpRetries retries = null);
276 
277 /// Shortcut for POST request. Each request uses a separate session,
278 /// no data like cookies is shared between multiple requests.
279 /// @sa CHttpSession::Post()
281 CHttpResponse g_HttpPost(const CUrl& url,
283  const CHttpParam& param = CHttpParam());
284 
285 /// Shortcut for POST request. Each request uses a separate session,
286 /// no data like cookies is shared between multiple requests.
287 /// @sa CHttpSession::Post()
289 CHttpResponse g_HttpPost(const CUrl& url,
291  CTempString content_type,
292  const CTimeout& timeout = CTimeout(CTimeout::eDefault),
293  THttpRetries retries = null);
294 
295 /// Shortcut for POST request with custom headers. Each request uses a separate
296 /// session, no data like cookies is shared between multiple requests.
297 /// @sa CHttpSession::Post()
299 CHttpResponse g_HttpPost(const CUrl& url,
300  const CHttpHeaders& headers,
302  CTempString content_type = CTempString(),
303  const CTimeout& timeout = CTimeout(CTimeout::eDefault),
304  THttpRetries retries = null);
305 
306 /// Shortcut for PUT request. Each request uses a separate session,
307 /// no data like cookies is shared between multiple requests.
308 /// @sa CHttpSession::Put()
310 CHttpResponse g_HttpPut(const CUrl& url,
312  const CHttpParam& param = CHttpParam());
313 
314 /// Shortcut for PUT request. Each request uses a separate session,
315 /// no data like cookies is shared between multiple requests.
316 /// @sa CHttpSession::Put()
318 CHttpResponse g_HttpPut(const CUrl& url,
320  CTempString content_type,
321  const CTimeout& timeout = CTimeout(CTimeout::eDefault),
322  THttpRetries retries = null);
323 
324 /// Shortcut for PUT request with custom headers. Each request uses a separate
325 /// session, no data like cookies is shared between multiple requests.
326 /// @sa CHttpSession::Put()
328 CHttpResponse g_HttpPut(const CUrl& url,
329  const CHttpHeaders& headers,
331  CTempString content_type = CTempString(),
332  const CTimeout& timeout = CTimeout(CTimeout::eDefault),
333  THttpRetries retries = null);
334 
335 
336 /// Interface for custom form data providers.
338 {
339 public:
340  /// Get content type. Returns empty string by default, indicating
341  /// no Content-Type header should be used for the part.
342  virtual string GetContentType(void) const { return string(); }
343 
344  /// Get optional filename to be shown in Content-Disposition header.
345  virtual string GetFileName(void) const { return string(); }
346 
347  /// Write user data to the stream.
348  virtual void WriteData(CNcbiOstream& out) const = 0;
349 
350  virtual ~CFormDataProvider_Base(void) {}
351 };
352 
353 
354 /// POST request data
356 {
357 public:
358  /// Supported content types for POST requests.
360  eFormUrlEncoded, ///< 'application/x-www-form-urlencoded', default
361  eMultipartFormData ///< 'multipart/form-data'
362  };
363 
364  /// Add name=value pair. The data of this type can be sent using either
365  /// eFormUrlEncoded or eMultipartFormData content types.
366  /// @param entry_name
367  /// Name of the form input. The name must not be empty, otherwise an
368  /// exception is thrown. Multiple values with the same name are allowed.
369  /// @param value
370  /// Value for the input. If the form content type is eFormUrlEncoded,
371  /// the value will be URL encoded properly. Otherwise the value is sent as-is.
372  /// URL-encoded form data allows only one value per entry, otherwise
373  /// exception will be thrown when sending the data.
374  /// @param content_type
375  /// Content type for the entry used if the form content type is
376  /// eMultipartFormData. If not set, the protocol assumes 'text/plain'
377  /// content type. Not used when sending eFormUrlEncoded content.
378  void AddEntry(CTempString entry_name,
380  CTempString content_type = CTempString());
381 
382  /// Add file entry. The form content type is automatically set to
383  /// eMultipartFormData and can not be changed later.
384  /// @param entry_name
385  /// Name of the form input responsible for selecting files. Multiple
386  /// files can be added with the same entry name. The name must not be
387  /// empty, otherwise an exception is thrown.
388  /// @param file_name
389  /// Path to the local file to be sent. The file must exist and be
390  /// readable during the call to WriteFormData, otherwise an exception
391  /// will be thrown.
392  /// @param content_type
393  /// Can be used to set content type for each file. If not set, the
394  /// protocol assumes it to be 'application/octet-stream'.
395  void AddFile(CTempString entry_name,
397  CTempString content_type = CTempString());
398 
399  /// Add custom data provider. The data written by the provider is
400  /// properly prefixed with Content-Disposition, boundary, Content-Type etc.
401  /// The form content type is automatically set to eMultipartFormData and
402  /// can not be changed later.
403  /// @param entry_name
404  /// Name of the form input responsible for the data. Multiple providers
405  /// can be added with the same entry name. The name must not be empty,
406  /// otherwise an exception is thrown.
407  /// @param provider
408  /// An instance of CFormDataProvider_Base derived class. The object must
409  /// be created in heap.
410  void AddProvider(CTempString entry_name,
411  CFormDataProvider_Base* provider);
412 
413  /// Check if the form data is empty (no entries have been added).
414  bool IsEmpty(void) const;
415 
416  /// Clear all form data, reset content type to the default eFormUrlEncoded.
417  void Clear(void);
418 
419  /// Write form data to the stream using the selected form content type.
420  /// If the data is not valid (e.g. a file does not exist or can not be
421  /// read), throw CHttpSessionException.
422  void WriteFormData(CNcbiOstream& out) const;
423 
424  /// Get current content type.
425  EContentType GetContentType(void) const { return m_ContentType; }
426  /// Set content type for the form data. If the new content type conflicts
427  /// with the types of entries already added, throw an exception (e.g.
428  /// files/providers require eMultipartFormData content type).
429  /// @note Content types for individual entries can be set when adding
430  /// an entry (see AddEntry, AddFile, AddProvider).
431  void SetContentType(EContentType content_type);
432 
433  virtual ~CHttpFormData(void) {}
434 
435 private:
436  friend class CHttpRequest;
437 
438  // Create new data object. The default content type is eFormUrlEncoded.
439  CHttpFormData(void);
440 
441  // Prohibit copying.
444 
445  struct SFormData {
446  string m_Value;
448  };
449 
450  typedef vector<SFormData> TValues;
452  typedef vector< CRef<CFormDataProvider_Base> > TProviders;
454 
456  TEntries m_Entries; // Normal entries
457  TProviderEntries m_Providers; // Files and custom providers
458  mutable string m_Boundary; // Main boundary string
459 
460 public:
461  /// Get the form content type as a string.
462  string GetContentTypeStr(void) const;
463 
464  /// Generate a new random string to be used as multipart boundary.
465  static string CreateBoundary(void);
466 };
467 
468 
469 class CHttpRequest;
470 class CHttpSession_Base;
471 
472 
473 /// HTTP response
475 {
476 public:
477  /// Get incoming HTTP headers.
478  const CHttpHeaders& Headers(void) const { return *m_Headers; }
479 
480  /// Get input stream. If the status code indicates that there's
481  /// no content to be read, throw CHttpSessionException. The actual
482  /// request body (e.g. error page) can be read using ErrorStream().
483  CNcbiIstream& ContentStream(void) const;
484 
485  /// Get input stream containing error message (e.g. 404 page)
486  /// If the status code indicates that valid content is available
487  /// the method throws CHttpSessionException.
488  CNcbiIstream& ErrorStream(void) const;
489 
490  /// Get actual resource location. This may be different from the
491  /// requested URL in case of redirects.
492  const CUrl& GetLocation(void) const { return m_Location; }
493 
494  /// Get response status code.
495  int GetStatusCode(void) const { return m_StatusCode; }
496 
497  /// Get response status text.
498  const string& GetStatusText(void) const { return m_StatusText; }
499 
500  /// Check if the requested content can be read from the content stream.
501  /// This is true for status codes 2xx. If there's no content available,
502  /// ContentStream() will throw an exception and response body can be
503  /// accessed using ErrorStream().
504  /// @note This method returns true even if the content stream is empty
505  /// (e.g. after HEAD request), it's based on status code only.
506  bool CanGetContentStream(void) const;
507 
508  virtual ~CHttpResponse(void) {}
509 
510 private:
511  friend class CHttpRequest;
512 
513  CHttpResponse(CHttpSession_Base& session, const CUrl& url, shared_ptr<iostream> stream = {});
514 
515  // Update response headers and location, parse cookies and store them in the session.
516  void x_Update(CHttpHeaders::THeaders headers, int status_code, string status_text);
517 
519  CUrl m_Url; // Original URL
520  CUrl m_Location; // Redirection or the original URL.
521  shared_ptr<iostream> m_Stream;
524  string m_StatusText;
525 };
526 
527 
528 /// Wrapper class for NCBI_CRED
530 {
531 public:
532  /// Initialize credentials. The arguments are passed to NcbiCreateTlsCertCredentials.
533  /// @sa
534  /// NcbiCreateTlsCertCredentials
535  CTlsCertCredentials(const CTempStringEx& cert, const CTempStringEx& pkey);
536  ~CTlsCertCredentials(void);
537 
538  NCBI_CRED GetNcbiCred(void) const;
539  const string& GetCert(void) const { return m_Cert; }
540  const string& GetPKey(void) const { return m_PKey; }
541 
542 private:
545 
546  string m_Cert;
547  string m_PKey;
548  mutable NCBI_CRED m_Cred = nullptr;
549 };
550 
551 
552 /// HTTP request
554 {
555 public:
556  /// Get HTTP headers to be sent.
557  CHttpHeaders& Headers(void) { return *m_Headers; }
558 
559  /// Get form data to be sent with POST request. Throw an exception
560  /// if the selected method is not POST or if the request is already
561  /// being executed (after calling ContentStream() but before Execute()).
562  CHttpFormData& FormData(void);
563 
564  /// Get output stream to write user data.
565  /// Headers are sent automatically when opening the stream.
566  /// No changes can be made to the request after getting the stream
567  /// until it is completed by calling Execute().
568  /// Throws an exception if the selected request method does not
569  /// support sending data or if the existing form data is not empty.
570  /// @note This method automatically adds cookies to the request headers.
571  CNcbiOstream& ContentStream(void);
572 
573  /// Send the request, initialize and return the response. The output
574  /// content stream is flushed and closed by this call.
575  /// After executing a request it can be modified (e.g. more headers
576  /// and/or form data added) and re-executed.
577  /// @note This method automatically adds cookies to the request headers.
578  CHttpResponse Execute(void);
579 
580  /// Get current timeout. If set to CTimeout::eDefault, the global
581  /// default value is used (or the one from $CONN_TIMEOUT).
582  const CTimeout& GetTimeout(void) const { return m_Timeout; }
583  /// Set new timeout.
584  CHttpRequest& SetTimeout(const CTimeout& timeout);
585  /// Set new timeout in seconds/microseconds.
586  CHttpRequest& SetTimeout(unsigned int sec, unsigned int usec = 0);
587 
588  /// Get number of retries. If not set returns the global default
589  /// value ($CONN_MAX_TRY - 1).
590  THttpRetries GetRetries(void) const { return m_Retries; }
591  /// Set number of retries. If not set, the global default
592  /// value is used ($CONN_MAX_TRY - 1).
593  void SetRetries(THttpRetries retries) { m_Retries = retries; }
594 
595  /// Get current deadline for Execute().
596  /// For now, effective only if waiting for actual response (as opposed to
597  /// a recognized 'retry later' response), infinite by default.
598  /// @sa Execute() GetRetryProcessing()
599  const CTimeout& GetDeadline() const { return m_Deadline; }
600  /// Set new deadline for Execute().
601  /// @sa Execute() SetRetryProcessing()
602  CHttpRequest& SetDeadline(const CTimeout& deadline);
603 
604  /// Return whether Execute() will wait for actual response.
605  /// If on, will wait for deadline expired or actual response
606  /// (as opposed to a recognized 'retry later' response), off by default.
607  /// @sa Execute() GetDeadline()
608  ESwitch GetRetryProcessing() const { return m_RetryProcessing; }
609  /// Set whether Execute() should wait for actual response.
610  /// @sa Execute() SetDeadline()
611  CHttpRequest& SetRetryProcessing(ESwitch on_off);
612 
613  /// Set callback to adjust URL after resolving service location.
614  /// The callback must take a CUrl reference and return bool:
615  /// bool AdjustUrlCallback(CUrl& url);
616  /// The callback should return true for the adjusted URL to be used to
617  /// make the request, or false if the changes should be discarded.
618  template<class TCallback>
619  void SetAdjustUrlCallback(TCallback callback) {
620  m_AdjustUrl.Reset(new CAdjustUrlCallback<TCallback>(callback));
621  }
622 
623  /// Set proxy.
624  void SetProxy(const CHttpProxy& proxy) { m_Proxy = proxy; }
625  const CHttpProxy& GetProxy(void) const { return m_Proxy; }
626 
627  /// Set request parameters.
628  /// @sa CHttpParam
629  void SetParam(const CHttpParam& param);
630 
631 private:
632  friend class CHttpSession_Base;
633  friend class CHttpSession;
634  friend class CHttp2Session;
635 
636  CHttpRequest(CHttpSession_Base& session, const CUrl& url, EReqMethod method, const CHttpParam& param = {});
637 
639  public:
640  virtual ~CAdjustUrlCallback_Base(void) {}
641  virtual bool AdjustUrl(CUrl& url) = 0;
642  };
643 
644  template<class TCallback>
646  public:
647  CAdjustUrlCallback(TCallback& callback) : m_Callback(callback) {}
648  virtual bool AdjustUrl(CUrl& url) { return m_Callback(url); }
649  private:
650  TCallback m_Callback;
651  };
652 
653  // Open connection, initialize response.
654  void x_InitConnection(bool use_form_data);
655  void x_InitConnection2(shared_ptr<iostream> stream);
656 
657  bool x_CanSendData(void) const;
658 
659  // Find cookies matching the url, add or replace 'Cookie' header with the
660  // new values.
661  void x_AddCookieHeader(const CUrl& url, bool initial);
662 
663  void x_AdjustHeaders(bool use_form_data);
664  void x_UpdateResponse(CHttpHeaders::THeaders headers, int status_code, string status_text);
665  void x_SetProxy(SConnNetInfo& net_info);
666 
667  // CConn_HttpStream callback for parsing headers.
668  // 'user_data' must point to a CHttpRequest object.
669  static EHTTP_HeaderParse sx_ParseHeader(const char* headers,
670  void* user_data,
671  int server_error);
672  // CConn_HttpStream callback for handling retries and redirects.
673  // 'user_data' must point to a CHttpRequest object.
674  static int sx_Adjust(SConnNetInfo* net_info,
675  void* user_data,
676  unsigned int failure_count);
677 
683  shared_ptr<iostream> m_Stream;
684  CRef<CHttpResponse> m_Response; // current response or null
690  // Store credentials so that they are not destroyed while request is being executed.
691  shared_ptr<CTlsCertCredentials> m_Credentials;
693 };
694 
695 
696 /// HTTP session class, holding common data for multiple requests.
698  virtual protected CConnIniter
699 {
700 public:
701  /// Supported request methods, proxy for EReqMethod.
702  /// @sa EReqMethod
709  eDelete = eReqMethod_Delete
710  };
711 
712  /// Initialize request. This does not open connection to the server.
713  /// A user can set headers/form-data before opening the stream and
714  /// sending the actual request.
715  /// The default request method is GET.
716  CHttpRequest NewRequest(const CUrl& url, ERequestMethod method = eGet, const CHttpParam& param = {});
717 
718  /// Shortcut for GET requests.
719  /// @param url
720  /// URL to send request to.
721  /// @sa NewRequest() CHttpRequest
722  CHttpResponse Get(const CUrl& url,
723  const CTimeout& timeout = CTimeout(CTimeout::eDefault),
724  THttpRetries retries = null);
725 
726  /// Shortcut for POST requests.
727  /// @param url
728  /// URL to send request to.
729  /// @param data
730  /// Data to be sent with the request. The data is sent as-is,
731  /// any required encoding must be performed by the caller.
732  /// @param content_type
733  /// Content-type. If empty, application/x-www-form-urlencoded
734  /// is used.
735  /// @sa NewRequest() CHttpRequest
736  CHttpResponse Post(const CUrl& url,
738  CTempString content_type = CTempString(),
739  const CTimeout& timeout = CTimeout(CTimeout::eDefault),
740  THttpRetries retries = null);
741 
742  /// Shortcut for PUT requests.
743  /// @param url
744  /// URL to send request to.
745  /// @param data
746  /// Data to be sent with the request. The data is sent as-is,
747  /// any required encoding must be performed by the caller.
748  /// @param content_type
749  /// Content-type. If empty, application/x-www-form-urlencoded
750  /// is used.
751  /// @sa NewRequest() CHttpRequest
752  CHttpResponse Put(const CUrl& url,
754  CTempString content_type = CTempString(),
755  const CTimeout& timeout = CTimeout(CTimeout::eDefault),
756  THttpRetries retries = null);
757 
758  /// Get all stored cookies.
759  const CHttpCookies& Cookies(void) const { return m_Cookies; }
760  /// Get all stored cookies, non-const.
761  CHttpCookies& Cookies(void) { return m_Cookies; }
762 
763  /// HTTP protocol version.
764  enum EProtocol {
765  eHTTP_10, ///< HTTP/1.0
766  eHTTP_11, ///< HTTP/1.1
767  eHTTP_2 ///< HTTP/2
768  };
769 
770  /// Get protocol version.
771  EProtocol GetProtocol(void) const { return m_Protocol; }
772  void SetProtocol(EProtocol protocol) { m_Protocol = protocol; }
773 
774  /// Get flags passed to CConn_HttpStream.
775  /// @sa SetHttpFlags
776  THTTP_Flags GetHttpFlags(void) const { return m_HttpFlags; }
777  /// Set flags passed to CConn_HttpStream. When sending request,
778  /// fHTTP_AdjustOnRedirect is always added to the flags.
779  /// @sa GetHttpFlags
780  void SetHttpFlags(THTTP_Flags flags) { m_HttpFlags = flags; }
781 
782  /// Set TLS credentials.
783  /// @sa CTlsCertCredentials
784  void SetCredentials(shared_ptr<CTlsCertCredentials> cred);
785  shared_ptr<CTlsCertCredentials> GetCredentials(void) const { return m_Credentials; }
786 
787  CHttpSession_Base(EProtocol protocol);
788  virtual ~CHttpSession_Base(void) {}
789 
790  void SetProxy(const CHttpProxy& proxy) { m_Proxy = proxy; }
791  const CHttpProxy& GetProxy(void) const { return m_Proxy; }
792 private:
793  friend class CHttpRequest;
794  friend class CHttpResponse;
795 
796  virtual void x_StartRequest(EProtocol protocol, CHttpRequest& req, bool use_form_data) = 0;
797  virtual bool x_Downgrade(CHttpResponse& resp, EProtocol& protocol) const = 0;
798 
799  // Save cookies returned by a response.
800  void x_SetCookies(const CHttpHeaders::THeaderValues& cookies,
801  const CUrl* url);
802  // Get a single 'Cookie' header line for the url.
803  string x_GetCookies(const CUrl& url) const;
804 
808  shared_ptr<CTlsCertCredentials> m_Credentials;
810 };
811 
812 
813 /// @sa CHttpSession_Base
815 {
816 public:
818 
819 private:
820  void x_StartRequest(EProtocol _DEBUG_ARG(protocol), CHttpRequest& req, bool use_form_data) override
821  {
823  req.x_InitConnection(use_form_data);
824  }
825 
826  bool x_Downgrade(CHttpResponse&, EProtocol&) const override
827  {
828  return false;
829  }
830 };
831 
832 
833 /////////////////////////////////////////////////////////////////////////////
834 ///
835 /// CHttpSessionException --
836 ///
837 /// Exceptions used by CHttpSession, CHttpRequest and CHttpResponse
838 /// classes.
839 
841 {
842 public:
843  enum EErrCode {
844  eConnFailed, ///< Failed to open connection.
845  eBadRequest, ///< Error initializing or sending a request.
846  eBadContentType, ///< Content-type conflicts with the data.
847  eBadFormDataName, ///< Empty or bad name in form data.
848  eBadFormData, ///< Bad form data (e.g. unreadable file).
849  eBadStream, ///< Wrong stream used to read content or error.
850  eOther
851  };
852 
853  virtual const char* GetErrCodeString(void) const override;
854 
856 };
857 
858 
860 
861 
862 /* @} */
863 
864 #endif /* CONNECT___NCBI_HTTP_SESSION__HPP */
Helper hook-up class that installs default logging/registry/locking (but only if they have not yet be...
Interface for custom form data providers.
POST request data.
Helper class allowing to use both strings and enums as header names.
CHttpSession and CHttpRequest parameters.
Per-request proxy settings.
HTTP request.
HTTP response.
CHttpSessionException –.
HTTP session class, holding common data for multiple requests.
CObject –.
Definition: ncbiobj.hpp:180
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
CTimeout – Timeout interval.
Definition: ncbitime.hpp:1693
Wrapper class for NCBI_CRED.
CUrl –.
Definition: ncbi_url.hpp:353
static uch flags
const char * file_name[]
std::ofstream out("events_result.xml")
main entry point for tests
char data[12]
Definition: iconv.c:80
string
Definition: cgiapp.hpp:690
unsigned int THTTP_Flags
Bitwise OR of EHTTP_Flag.
EHTTP_HeaderParse
The extended version HTTP_CreateConnectorEx() is able to track the HTTP response chain and also chang...
#define _DEBUG_ARG(arg)
Definition: ncbidbg.hpp:134
shared_ptr< iostream > m_Stream
virtual string GetFileName(void) const
Get optional filename to be shown in Content-Disposition header.
void SetRetries(THttpRetries retries)
Set number of retries.
vector< SFormData > TValues
shared_ptr< CTlsCertCredentials > GetCredentials(void) const
THttpRetries GetRetries(void) const
EHeaderName
Some standard HTTP headers.
EProtocol GetProtocol(void) const
Get protocol version.
const THeaders & Get() const
const CHttpProxy & GetProxy(void) const
CHttpHeaders & operator=(const CHttpHeaders &)
const CTimeout & GetTimeout(void) const
Get current timeout.
const string & GetPKey(void) const
shared_ptr< CTlsCertCredentials > GetCredentials(void) const
map< string, TProviders > TProviderEntries
CRef< CAdjustUrlCallback_Base > m_AdjustUrl
THttpRetries GetRetries(void) const
Get number of retries.
const CTimeout & GetDeadline() const
const CTimeout & GetDeadline() const
Get current deadline for Execute().
const string & GetHost(void) const
ESwitch GetRetryProcessing() const
CRef< CHttpHeaders > m_Headers
int GetStatusCode(void) const
Get response status code.
CTlsCertCredentials(const CTlsCertCredentials &)
CRef< CHttpSession_Base > m_Session
map< string, TValues > TEntries
unsigned short GetPort(void) const
CRef< CHttpSession_Base > m_Session
const CHttpHeaders & Headers(void) const
Get incoming HTTP headers.
void x_InitConnection(bool use_form_data)
const CTimeout & GetTimeout(void) const
CHttpFormData(const CHttpFormData &)
const string & GetPassword(void) const
EContentType GetContentType(void) const
Get current content type.
CHttpParam & SetRetryProcessing(ESwitch on_off)
virtual string GetContentType(void) const
Get content type.
CHttpHeaders(const CHttpHeaders &)
void SetProxy(const CHttpProxy &proxy)
Set proxy.
virtual ~CHttpSession_Base(void)
EContentType
Supported content types for POST requests.
shared_ptr< iostream > m_Stream
CNullable< unsigned short, SGetHttpDefaultRetries > THttpRetries
Nullable retries for CHttpRequest.
vector< CRef< CFormDataProvider_Base > > TProviders
CHttpProxy(string host, unsigned short port, string user, string password)
ESwitch GetRetryProcessing() const
Return whether Execute() will wait for actual response.
void SetHttpFlags(THTTP_Flags flags)
Set flags passed to CConn_HttpStream.
CRef< CHttpHeaders > m_Headers
const CHttpHeaders & GetHeaders(void) const
CHttpHeaders & Headers(void)
Get HTTP headers to be sent.
CRef< CHttpFormData > m_FormData
virtual ~CFormDataProvider_Base(void)
shared_ptr< CTlsCertCredentials > m_Credentials
void SetAdjustUrlCallback(TCallback callback)
Set callback to adjust URL after resolving service location.
const string & GetCert(void) const
CHttpProxy(string host, unsigned short port)
CHeaderNameConverter(CHttpHeaders::EHeaderName name)
const string & GetStatusText(void) const
Get response status text.
CHttpResponse g_HttpPost(const CUrl &url, CTempString data, const CHttpParam &param=CHttpParam())
Shortcut for POST request.
CHttpHeaders(void)
Create empty headers list.
const CHttpProxy & GetProxy(void) const
virtual bool x_Downgrade(CHttpResponse &resp, EProtocol &protocol) const =0
const CHttpCookies & Cookies(void) const
Get all stored cookies.
NCBI_EXCEPTION_DEFAULT(CHttpSessionException, CException)
TProviderEntries m_Providers
virtual ~CHttpHeaders(void)
virtual ~CHttpResponse(void)
CHttpProxy m_Proxy
ESwitch m_RetryProcessing
void SetProtocol(EProtocol protocol)
EContentType m_ContentType
THTTP_Flags GetHttpFlags(void) const
Get flags passed to CConn_HttpStream.
CHttpResponse g_HttpPut(const CUrl &url, CTempString data, const CHttpParam &param=CHttpParam())
Shortcut for PUT request.
const CHttpProxy & GetProxy(void) const
unsigned short operator()(void) const
virtual void WriteData(CNcbiOstream &out) const =0
Write user data to the stream.
shared_ptr< CTlsCertCredentials > m_Credentials
CHttpCookies & Cookies(void)
Get all stored cookies, non-const.
CTlsCertCredentials & operator=(const CTlsCertCredentials &)
shared_ptr< CTlsCertCredentials > m_Credentials
virtual void x_StartRequest(EProtocol protocol, CHttpRequest &req, bool use_form_data)=0
virtual bool AdjustUrl(CUrl &url)=0
bool x_Downgrade(CHttpResponse &, EProtocol &) const override
ERequestMethod
Supported request methods, proxy for EReqMethod.
void SetProxy(const CHttpProxy &proxy)
CRef< CHttpResponse > m_Response
CHttpResponse g_HttpGet(const CUrl &url, const CHttpParam &param)
Shortcut for GET request.
virtual ~CHttpFormData(void)
CHttpParam & SetDeadline(const CTimeout &deadline)
unsigned short m_Port
const CUrl & GetLocation(void) const
Get actual resource location.
THttpRetries m_Retries
CHttpParam & SetProxy(const CHttpProxy &proxy)
const string & GetUser(void) const
bool IsEmpty(void) const
CRef< CHttpHeaders > m_Headers
vector< string > THeaderValues
List of header values (may be required for headers with multiple values like Cookie).
CHttpFormData & operator=(const CHttpFormData &)
void x_StartRequest(EProtocol protocol, CHttpRequest &req, bool use_form_data) override
EProtocol
HTTP protocol version.
map< string, THeaderValues, PNocase > THeaders
Map of header name-values, case-insensitive.
THttpRetries m_Retries
@ eFormUrlEncoded
'application/x-www-form-urlencoded', default
@ eBadStream
Wrong stream used to read content or error.
@ eBadFormData
Bad form data (e.g. unreadable file).
@ eBadContentType
Content-type conflicts with the data.
@ eBadFormDataName
Empty or bad name in form data.
@ eBadRequest
Error initializing or sending a request.
@ eConnFailed
Failed to open connection.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:146
unsigned short m_Port
TCP port to listen on.
@ eDefault
Default timeout (to be interpreted by the client code)
Definition: ncbitime.hpp:1698
enum ENcbiSwitch ESwitch
Aux.
EReqMethod
@ eReqMethod_Put
@ eReqMethod_Delete
@ eReqMethod_Patch
@ eReqMethod_Get
@ eReqMethod_Head
@ eReqMethod_Post
#define NCBI_XCONNECT_EXPORT
const TYPE & Get(const CNamedParameterList *param)
string Execute(const string &cmmd, const vector< string > &args, const string &data=kEmptyStr)
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
@ eGet
Definition: ns_types.hpp:55
#define _ASSERT
void Merge(wxMenu &menu_1, const wxMenu &menu_2)
merges all items form menu_2 into menu_1, preserving the structure if possible
Definition: wx_utils.cpp:579
Modified on Fri Sep 20 14:57:33 2024 by modify_doxy.py rev. 669887