95 return it->second.size();
103 return it->second.back();
122 vals.push_back(
value);
151 list<CTempString> lines;
156 ITERATE(list<CTempString>, line, lines) {
158 if (delim ==
NPOS || delim < 1) {
163 name = line->substr(0, delim);
164 value = line->substr(delim + 1);
166 to[name].push_back(
value);
201 name->second.begin(), name->second.end());
231 : m_ContentType(eFormUrlEncoded),
232 m_Boundary(CreateBoundary())
241 "Requested Content-Type cannot be used with the form data");
251 if ( entry_name.
empty() ) {
253 "Form data entry name must not be empty");
259 values.push_back(entry);
266 if ( entry_name.
empty() ) {
268 "Form data entry name must not be empty");
279 const string& content_type)
350 const Int8 a = 1103515245;
351 const Int8 c = 12345;
352 const Int8 m = 1 << 16;
360 static const char kBoundaryChars[] =
361 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-";
362 static const size_t kBoundaryCharsLen =
sizeof(kBoundaryChars) - 1;
363 static const int kBoundaryLen = 32;
366 for (
int i = 0;
i < kBoundaryLen; ++
i) {
367 boundary += kBoundaryChars[
s_SimpleRand(kBoundaryCharsLen)];
385 const string& boundary,
387 const string& content_type,
391 out <<
"Content-Disposition: form-data; name=\"" << name <<
"\"";
392 if ( !filename.empty() ) {
393 out <<
"; filename=\"" << filename <<
"\"";
396 if ( !content_type.empty() ) {
397 out <<
"Content-Type: " <<
411 if (values->second.size() > 1) {
413 "Multiple values not allowed in URL-encoded form data, "
414 " entry '" + values->first +
'\'');
416 args.
SetValue(values->first, values->second.back().m_Value);
427 entry->m_ContentType);
432 if ( providers->second.empty() )
continue;
434 string part_content_type =
"multipart/mixed; boundary=";
435 part_content_type += part_boundary;
440 (*provider)->GetContentType(),
441 (*provider)->GetFileName());
442 (*provider)->WriteData(
out);
467 shared_ptr<iostream> stream)
468 : m_Session(&session),
471 m_Stream(std::move(stream)),
483 "Content stream not available for status '"
496 "Error stream not available for status '"
527 : m_Cert(cert), m_PKey(pkey)
560 int maxtry = atoi(
buf);
561 return (
unsigned short)(maxtry ? maxtry - 1 : 0);
568 return (
unsigned short)(++retries ? retries : retries - 1);
576 : m_Session(&session),
581 m_Credentials(session.GetCredentials())
598 template <
class TMember,
class TValue = TMember>
611 template <
class TTo,
class TFrom>
static void Assign(TTo&,
const TFrom&);
625 m_Enabled(on_off ==
eOn),
626 m_Deadline(deadline.IsDefault() ?
CTimeout::eInfinite : deadline),
630 m_FormData(form_data)
638 const unsigned long kExecuteDefaultRefreshDelay = 5;
639 const string kExecuteHeaderRetryURL =
"X-NCBI-Retry-URL";
640 const string kExecuteHeaderRetryDelay =
"X-NCBI-Retry-Delay";
645 const auto& retry_url = headers.
GetValue(kExecuteHeaderRetryURL);
648 if (retry_url.empty())
return false;
650 const auto& retry_delay = headers.
GetValue(kExecuteHeaderRetryDelay);
651 unsigned long sleep_ms = kExecuteDefaultRefreshDelay;
654 if (!retry_delay.empty()) {
667 if (remaining < sleep_ms) sleep_ms = remaining;
685 template <
class TTo,
class TFrom>
720 "Attempt to execute HTTP request already being executed");
746 "Request method does not allow writing to the output stream");
751 "Attempt to execute HTTP request already being executed");
766 "Request method does not support sending data");
770 "Can not get form data while executing request");
849 if (!net_info || (is_service && !net_info->svc[0])) {
851 "Failed to create SConnNetInfo");
854 net_info->http_version = 1;
868 if (net_info->http_user_header) {
888 unique_ptr<SAdjustData> adjust_data(
new SAdjustData(
this, is_service));
905 memset(&x_extra, 0,
sizeof(x_extra));
906 x_extra.
data = adjust_data.get();
918 adjust_data.release();
942 if ( !cookies.empty() || !initial ) {
1009 unsigned int failure_count)
1011 if ( !user_data )
return 0;
1014 if (failure_count == (
unsigned int)(-1) && !adj->
m_IsService)
1020 if (failure_count && failure_count != (
unsigned int)(-1)) {
1041 CUrl url(loc.get());
1042 if (failure_count) {
1059 "Cannot parse URL " + new_url);
1063 "Cannot obtain updated URL");
1070 "Cannot obtain original URL");
1078 "Cannot set HTTP header(s)");
1134 : m_Protocol(protocol),
1166 if ( content_type.
empty() ) {
1170 if ( !
data.empty() ) {
1186 if ( content_type.
empty() ) {
1190 if ( !
data.empty() ) {
1217 if ( !cookies.empty() ) {
1230 "Session credentials already set");
1301 return g_HttpGet(url, hdr, timeout, retries);
1332 if (!
data.empty()) {
1347 return g_HttpPost(url, hdr,
data, content_type, timeout, retries);
1364 if ( content_type.
empty() ) {
1378 if ( !
data.empty() ) {
1399 if (!
data.empty()) {
1414 return g_HttpPut(url, hdr,
data, content_type, timeout, retries);
1431 if ( content_type.
empty() ) {
1445 if ( !
data.empty() ) {
1467 case eOther:
return "Other error";
Helper base class for HTTP-like streams.
This stream exchanges data with an HTTP server located at the URL: http[s]://host[:port]/path[?...
This stream exchanges data with a named service, in a constraint that the service is implemented as o...
Primitive encoder - all methods return the argument value.
CFileDataProvider(const string &file_name, const string &content_type)
virtual void WriteData(CNcbiOstream &out) const
Write user data to the stream.
virtual string GetFileName(void) const
Get optional filename to be shown in Content-Disposition header.
virtual ~CFileDataProvider(void)
virtual string GetContentType(void) const
Get content type.
CHttpSession and CHttpRequest parameters.
Per-request proxy settings.
HTTP session class, holding common data for multiple requests.
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
CTimeout – Timeout interval.
container_type::const_iterator const_iterator
container_type::iterator iterator
const_iterator end() const
const_iterator find(const key_type &key) const
The NCBI C++ standard methods for dealing with std::string.
std::ofstream out("events_result.xml")
main entry point for tests
static DLIST_TYPE *DLIST_NAME() last(DLIST_LIST_TYPE *list)
bool IsNull(void) const
Check if the object is unassigned.
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
unique_ptr< T, TDeleter > make_c_unique(T *p, TDeleter d)
Eliminates the necessity for specifying types of both allocated resource and deallocating C function.
int GetStatusCode(void) const
Get the last seen HTTP status code, if available.
const CTempString GetStatusText(void) const
Get the last seen HTTP status text, if available.
const string & GetHTTPHeader(void) const
Get the last seen HTTP header text, if available.
FHTTP_ParseHeader parse_header
EHTTP_HeaderParse
The extended version HTTP_CreateConnectorEx() is able to track the HTTP response chain and also chang...
@ fHTTP_AdjustOnRedirect
Call adjust routine for redirects, too.
@ eHTTP_HeaderError
Parse failed, treat as a server error.
@ eHTTP_HeaderContinue
Parse succeeded, continue with body.
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
TErrCode GetErrCode(void) const
Get error code.
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
TErrCode GetErrCode(void) const
virtual const char * GetErrCodeString(void) const
Get error code interpreted as text.
const_iterator begin(void) const
Iterate all cookies.
string AsString(ECookieFormat format) const
Compose string from the cookie.
void Add(const CHttpCookie &cookie)
Add a single cookie.
shared_ptr< iostream > m_Stream
void ParseHttpHeader(const CTempString &headers)
Parse headers from the string (usually provided by a stream callback).
void SetRetries(THttpRetries retries)
Set number of retries.
static const char * GetHeaderName(EHeaderName name)
Get string representation of the given name.
void x_InitConnection2(shared_ptr< iostream > stream)
vector< SFormData > TValues
CHttpResponse Get(const CUrl &url, const CTimeout &timeout=CTimeout(CTimeout::eDefault), THttpRetries retries=null)
Shortcut for GET requests.
shared_ptr< CTlsCertCredentials > GetCredentials(void) const
THttpRetries GetRetries(void) const
CHttpRequest & SetTimeout(const CTimeout &timeout)
Set new timeout.
EHeaderName
Some standard HTTP headers.
EProtocol GetProtocol(void) const
Get protocol version.
const CHttpProxy & GetProxy(void) const
void AddEntry(CTempString entry_name, CTempString value, CTempString content_type=CTempString())
Add name=value pair.
CHttpParam & AddHeader(CHttpHeaders::EHeaderName header, CTempString value)
Add a single HTTP header,.
CHttpParam & SetRetries(THttpRetries retries)
CNcbiIstream & ContentStream(void) const
Get input stream.
CRef< CAdjustUrlCallback_Base > m_AdjustUrl
const CTimeout & GetDeadline() const
const string & GetHost(void) const
ESwitch GetRetryProcessing() const
CRef< CHttpHeaders > m_Headers
void x_Update(CHttpHeaders::THeaders headers, int status_code, string status_text)
int GetStatusCode(void) const
Get response status code.
CHttpParam & SetHeaders(const CHttpHeaders &headers)
Add all HTTP headers to request.
void AddProvider(CTempString entry_name, CFormDataProvider_Base *provider)
Add custom data provider.
CRef< CHttpSession_Base > m_Session
void SetValue(CHeaderNameConverter name, CTempString value)
Remove all existing values with the name, set the new value.
unsigned short GetPort(void) const
CRef< CHttpSession_Base > m_Session
CHttpRequest & SetRetryProcessing(ESwitch on_off)
Set whether Execute() should wait for actual response.
CHttpSession_Base(EProtocol protocol)
bool x_CanSendData(void) const
const THeaderValues & GetAllValues(CHeaderNameConverter name) const
Get all values with the given name.
void WriteFormData(CNcbiOstream &out) const
Write form data to the stream using the selected form content type.
void x_SetProxy(SConnNetInfo &net_info)
const CHttpHeaders & Headers(void) const
Get incoming HTTP headers.
void x_InitConnection(bool use_form_data)
CNcbiIstream & ErrorStream(void) const
Get input stream containing error message (e.g.
string GetHttpHeader(void) const
Get all headers as a single string as required by CConn_HttpStream.
const CTimeout & GetTimeout(void) const
const string & GetPassword(void) const
string x_GetCookies(const CUrl &url) const
static int sx_Adjust(SConnNetInfo *net_info, void *user_data, unsigned int failure_count)
void ClearAll(void)
Remove all headers.
CHttpParam & SetCredentials(shared_ptr< CTlsCertCredentials > credentials)
CHttpRequest & SetDeadline(const CTimeout &deadline)
Set new deadline for Execute().
CNcbiOstream & ContentStream(void)
Get output stream to write user data.
void SetContentType(EContentType content_type)
Set content type for the form data.
void AddFile(CTempString entry_name, CTempString file_name, CTempString content_type=CTempString())
Add file entry.
NCBI_CRED GetNcbiCred(void) const
void Clear(void)
Clear all form data, reset content type to the default eFormUrlEncoded.
virtual const char * GetErrCodeString(void) const override
Get error code interpreted as text.
EContentType
Supported content types for POST requests.
shared_ptr< iostream > m_Stream
void AddValue(CHeaderNameConverter name, CTempString value)
Add new value with the name (multiple values are allowed with the same name, the order is preserved).
bool CanGetContentStream(void) const
Check if the requested content can be read from the content stream.
CTempString GetName(void)
ESwitch m_RetryProcessing
vector< CRef< CFormDataProvider_Base > > TProviders
void Clear(CHeaderNameConverter name)
Remove all values with the given name.
void x_UpdateResponse(CHttpHeaders::THeaders headers, int status_code, string status_text)
static EHTTP_HeaderParse sx_ParseHeader(const char *headers, void *user_data, int server_error)
static string CreateBoundary(void)
Generate a new random string to be used as multipart boundary.
CRef< CHttpHeaders > m_Headers
bool x_IsReservedHeader(CTempString name) const
const CHttpHeaders & GetHeaders(void) const
CHttpHeaders & Headers(void)
Get HTTP headers to be sent.
CRef< CHttpFormData > m_FormData
shared_ptr< CTlsCertCredentials > m_Credentials
CHttpResponse g_HttpPost(const CUrl &url, CTempString data, const CHttpParam ¶m)
Shortcut for POST request.
const CHttpProxy & GetProxy(void) const
bool IsEmpty(void) const
Check if the form data is empty (no entries have been added).
CHttpResponse Post(const CUrl &url, CTempString data, CTempString content_type=CTempString(), const CTimeout &timeout=CTimeout(CTimeout::eDefault), THttpRetries retries=null)
Shortcut for POST requests.
void x_AdjustHeaders(bool use_form_data)
void x_AddCookieHeader(const CUrl &url, bool initial)
virtual bool x_Downgrade(CHttpResponse &resp, EProtocol &protocol) const =0
TProviderEntries m_Providers
void Merge(const CHttpHeaders &headers)
Add values from 'headers' to this object.
CHttpParam & SetTimeout(const CTimeout &timeout)
CHttpResponse Put(const CUrl &url, CTempString data, CTempString content_type=CTempString(), const CTimeout &timeout=CTimeout(CTimeout::eDefault), THttpRetries retries=null)
Shortcut for PUT requests.
CHttpResponse(CHttpSession_Base &session, const CUrl &url, shared_ptr< iostream > stream={})
EContentType m_ContentType
THTTP_Flags GetHttpFlags(void) const
Get flags passed to CConn_HttpStream.
CHttpResponse g_HttpPut(const CUrl &url, CTempString data, const CHttpParam ¶m)
Shortcut for PUT request.
const CHttpProxy & GetProxy(void) const
unsigned short operator()(void) const
~CTlsCertCredentials(void)
void x_SetCookies(const CHttpHeaders::THeaderValues &cookies, const CUrl *url)
shared_ptr< CTlsCertCredentials > m_Credentials
const string & GetValue(CHeaderNameConverter name) const
Get value of the header or empty string.
shared_ptr< CTlsCertCredentials > m_Credentials
CHttpRequest NewRequest(const CUrl &url, ERequestMethod method=eGet, const CHttpParam ¶m={})
Initialize request.
virtual void x_StartRequest(EProtocol protocol, CHttpRequest &req, bool use_form_data)=0
CHttpResponse Execute(void)
Send the request, initialize and return the response.
ERequestMethod
Supported request methods, proxy for EReqMethod.
void SetCredentials(shared_ptr< CTlsCertCredentials > cred)
Set TLS credentials.
CRef< CHttpResponse > m_Response
CHttpResponse g_HttpGet(const CUrl &url, const CHttpParam ¶m)
Shortcut for GET request.
void SetParam(const CHttpParam ¶m)
Set request parameters.
CTlsCertCredentials(const CTempStringEx &cert, const CTempStringEx &pkey)
Initialize credentials.
size_t CountValues(CHeaderNameConverter name) const
Get number of values with the given name.
bool HasValue(CHeaderNameConverter name) const
Check if there's at least one header with the name.
const string & GetUser(void) const
string GetContentTypeStr(void) const
Get the form content type as a string.
CRef< CHttpHeaders > m_Headers
vector< string > THeaderValues
List of header values (may be required for headers with multiple values like Cookie).
CHttpFormData & FormData(void)
Get form data to be sent with POST request.
void Assign(const CHttpHeaders &headers)
Clear any existing values and copy all headers from 'headers' to this object.
EProtocol
HTTP protocol version.
friend class CHttpRequest
CHttpParam & SetHeader(CHttpHeaders::EHeaderName header, CTempString value)
Set or replace a single HTTP header,.
@ eFormUrlEncoded
'application/x-www-form-urlencoded', default
@ eMultipartFormData
'multipart/form-data'
@ 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.
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
void Reset(void)
Reset reference object.
bool Empty(void) const THROWS_NONE
Check if CRef is empty – not pointing to any object, which means having a null value.
int64_t Int8
8-byte (64-bit) signed integer
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
#define NCBI_AS_STRING(value)
Convert some value to string even if this value is macro itself.
NCBI_CRED NcbiCreateTlsCertCredentials(const void *cert, size_t certsz, const void *pkey, size_t pkeysz)
Build NCBI_CRED from memory buffers containing X.509 certificate and private key, respectively,...
void NcbiDeleteTlsCertCredentials(NCBI_CRED cred)
Delete a NCBI_CRED handle created by NcbiCreateTlsCertCredentials().
void NcbiStreamCopyThrow(CNcbiOstream &os, CNcbiIstream &is)
Same as NcbiStreamCopy() but throws an CCoreException when copy fails.
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
static int CompareNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive compare of a substring with another string.
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate whitespace in a string (in-place)
static unsigned long StringToULong(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to unsigned long.
bool empty(void) const
Return true if the represented string is empty (i.e., the length is zero)
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
bool HasZeroAtEnd(void) const
TErrCode GetErrCode(void) const
Get error code.
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
static string URLEncode(const CTempString str, EUrlEncode flag=eUrlEnc_SkipMarkChars)
URL-encode string.
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
@ eUrlEnc_URIQueryValue
Encode query part of an URI, arg value.
@ eUrlEnc_URIQueryName
Encode query part of an URI, arg name.
@ eConvert
Failure to convert string.
@ eTrunc_Both
Truncate whitespace at both begin and end of string.
CNanoTimeout GetRemainingTime(void) const
Get time left to the expiration.
bool IsExpired(void) const
Check if the deadline is expired.
const long kMilliSecondsPerSecond
Number milliseconds in one second.
unsigned long GetAsMilliSeconds(void) const
Get as number of milliseconds.
void Set(EType type)
Set special value.
@ eConvert
Error converting value from one format to another.
string GetQueryString(EAmpEncoding amp_enc, NStr::EUrlEncode encode) const
Construct and return complete query string.
const string & GetService(void) const
void Adjust(const CUrl &other, TAdjustFlags flags)
Adjust this URL using information from 'other' URL.
const string & GetScheme(void) const
void SetUrl(const string &url, const IUrlEncoder *encoder=0)
Parse the URL.
void SetValue(const string &name, const string &value)
Set new value for the first argument with the given name or add a new argument.
bool IsService(void) const
string ComposeUrl(CUrlArgs::EAmpEncoding amp_enc, const IUrlEncoder *encoder=0) const
Compose the URL.
@ eAmp_Char
Use & to separate arguments.
@ fScheme_Replace
Replace scheme if set in 'other'.
@ fPath_Append
Append new path to the existing one.
@ fArgs_Merge
Append new args; replace values of existing args, do not allow to set multiple values with the same n...
char http_proxy_host[255+1]
enum ENcbiSwitch ESwitch
Aux.
char http_proxy_user[63+1]
unsigned short http_proxy_port
int ConnNetInfo_SetTimeout(SConnNetInfo *net_info, const STimeout *timeout)
int ConnNetInfo_OverrideUserHeader(SConnNetInfo *net_info, const char *header)
const STimeout * g_CTimeoutToSTimeout(const CTimeout &cto, STimeout &sto)
CTimeout/STimeout adapters.
int ConnNetInfo_ParseURL(SConnNetInfo *net_info, const char *url)
char http_proxy_pass[63+1]
char * ConnNetInfo_URL(const SConnNetInfo *net_info)
SConnNetInfo * ConnNetInfo_Create(const char *service)
void ConnNetInfo_Destroy(SConnNetInfo *net_info)
range(_Ty, _Ty) -> range< _Ty >
const GenericPointer< typename T::ValueType > T2 value
const char * ConnNetInfo_GetValueInternal(const char *service, const char *param, char *value, size_t value_size, const char *def_value)
static const char * kReservedHeaders[]
const char * kContentType_MultipartFormData
static const char kHttpHeaderDelimiter
DEFINE_STATIC_FAST_MUTEX(s_SessionMutex)
const char * kContentType_FormUrlEnc
static Int8 s_SimpleRand(Int8 range)
static void x_WritePartHeader(CNcbiOstream &out, const string &boundary, const string &name, const string &content_type, const string &filename=kEmptyStr)
static void s_Cleanup(void *user_data)
static const char * kHttpHeaderNames[]
static void s_ParseHttpHeader(const CTempString &from, CHttpHeaders::THeaders &to)
unsigned short x_RetriesToMaxtry(unsigned short retries)
static CSafeStatic< CHttpHeaders::THeaderValues > kEmptyValues
void SleepMilliSec(unsigned long ml_sec, EInterruptOnSignal onsignal=eRestartOnSignal)
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
Multi-threading – mutexes; rw-locks; semaphore.
std::istream & in(std::istream &in_, double &x_)
Defines CRequestContext class for NCBI C++ diagnostic API.
SAdjustData(CHttpRequest *request, bool is_service)
SValueRestorer(TMember &v)
bool operator()(const CHttpHeaders &headers)
SValueRestorer< CRef< CHttpHeaders >, CHttpHeaders > m_Headers
static void Assign(TTo &, const TFrom &)
SRetryProcessing(ESwitch on_off, const CTimeout &deadline, CUrl &url, EReqMethod &method, CRef< CHttpHeaders > &headers, CRef< CHttpFormData > &form_data)
SValueRestorer< CUrl > m_Url
SValueRestorer< CRef< CHttpFormData > > m_FormData
SValueRestorer< EReqMethod > m_Method