67 unsigned int position = 1;
103 if (err_pos !=
NPOS) {
105 "Space character in URL arguments: \"" +
query +
"\"",
118 string mid_seps =
"=&";
119 string end_seps =
"&";
125 unsigned int position = 1;
128 if (
query[beg] ==
'&') {
146 beg =
query.find_first_of(end_seps, beg);
147 if (beg ==
NPOS)
break;
158 if (
query[mid] ==
'=') {
185 m_Case(
NStr::eNocase),
194 m_Case(
NStr::eNocase),
203 m_Case(
NStr::eNocase),
241 string amp = (amp_enc ==
eAmp_Char) ?
"&" :
"&";
260 *is_found = iter !=
m_Args.end();
261 return *is_found ? iter->value :
kEmptyStr;
263 else if (iter !=
m_Args.end()) {
294 while (it !=
m_Args.end()) {
378 "http",
"https",
"file",
"ftp"
382 if (scheme.empty())
return false;
383 string sch_lower = scheme;
385 if (s_StdSchemes.find(sch_lower) != s_StdSchemes.end())
return false;
387 SIZE_TYPE port_end = unparsed.find_first_of(
"/?#");
388 string port = unparsed.substr(0, port_end);
393 port.find_first_not_of(
"0123456789") !=
NPOS)
return false;
394 int port_val = atoi(port.c_str());
395 if (port_val > 65535)
return false;
399 if (port_end !=
NPOS) {
400 unparsed = unparsed.substr(port_end);
431 if (orig_url.find_first_of(
":/.?#") ==
NPOS) {
440 bool slashes_are_in_args =
false;
442 SIZE_TYPE question_mark_pos = orig_url.find(
"?");
443 if (question_mark_pos !=
NPOS) {
444 if (question_mark_pos < pos) {
445 slashes_are_in_args =
true;
452 if (pos !=
NPOS && slashes_are_in_args ==
false) {
455 if (pos > 0 && orig_url[pos - 1] ==
':') {
457 x_SetScheme(orig_url.substr(0, pos - 1), *encoder);
461 unparsed = orig_url.substr(pos);
462 pos = unparsed.find_first_of(
"/?#");
463 authority = unparsed.substr(0, pos);
465 unparsed = unparsed.substr(pos);
471 pos = authority.find(
'@');
474 string user_info = authority.substr(0, pos);
475 host = authority.substr(pos + 1);
476 pos = user_info.find(
':');
478 x_SetUser(user_info.substr(0, pos), *encoder);
490 if (!host.empty() && host[0] ==
'[') {
492 pos = host.find(
']');
495 "Unmatched '[' in the URL: \"" + orig_url +
"\"", pos +
offset);
497 if (pos + 1 < host.size() && host[pos + 1] ==
':') {
505 pos = host.find(
':');
510 x_SetPort(host.substr(pos + 1), *encoder);
514 "Invalid port value: \"" + orig_url +
"\"", pos + 1);
521 if (scheme_svc_pos !=
NPOS && scheme_svc_pos > 0) {
535 SIZE_TYPE scheme_end = orig_url.find(
':');
536 if (scheme_end !=
NPOS) {
537 string scheme = orig_url.substr(0, scheme_end);
538 unparsed = orig_url.substr(scheme_end + 1);
541 x_SetScheme(orig_url.substr(0, scheme_end), *encoder);
549 if ( unparsed.empty() )
return;
550 if (unparsed[0] ==
'/') {
552 pos = unparsed.find_first_of(
"?#");
553 x_SetPath(unparsed.substr(0, pos), *encoder);
555 if (pos ==
NPOS)
return;
556 unparsed = unparsed.substr(pos);
560 if (unparsed[0] ==
'?') {
562 pos = unparsed.find(
'#');
563 x_SetArgs(unparsed.substr(1, pos - 1), *encoder);
564 if (pos ==
NPOS)
return;
565 unparsed = unparsed.substr(pos);
569 if (unparsed[0] ==
'#') {
619 bool have_user_info =
false;
622 have_user_info =
true;
626 have_user_info =
true;
628 if ( have_user_info ) {
634 else if ( !
m_Host.empty() ) {
642 url +=
"?" +
m_ArgsList->GetQueryString(amp_enc, encoder);
655 && (pos == 0 ||
value[pos - 1] ==
'+')
678 "The URL has no arguments");
698 if ((
flags & fUser_Mask) == fUser_Mask) {
701 if ( !other.
m_User.empty() ) {
710 if ((
flags & fPassword_Mask) == fPassword_Mask) {
722 if ((
flags & fPath_Mask) == fPath_Mask) {
734 if (
m_Path.back() ==
'/' && other.
m_Path.front() ==
'/') {
737 else if (
m_Path.back() !=
'/' && other.
m_Path.front() !=
'/') {
744 if ((
flags & fFragment_Mask) == fFragment_Mask) {
756 switch (
flags & fArgs_Mask) {
781 unique_ptr<CUrlArgs> args(
m_ArgsList.release());
786 m_ArgsList->SetUniqueValue(it->name, it->value);
791 m_ArgsList->SetUniqueValue(it->name, it->value);
811 return &s_DefaultEncoder.
Get();
Default encoder, uses the selected encoding for argument names/values and eUrlEncode_Path for documen...
T & Get(void)
Create the variable if not created yet, return the reference.
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
NCBI_DEPRECATED_CLASS NCBI_XCGI_EXPORT EUrlEncode decode
NCBI_DEPRECATED_CLASS NCBI_XCGI_EXPORT EUrlEncode encode
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
#define NCBI_THROW2(exception_class, err_code, message, extra)
Throw exception with extra parameter.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
NCBI_NS_STD::string::size_type SIZE_TYPE
static int CompareNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive compare of a substring with another string.
EUrlEncode
URL-encode flags.
static SIZE_TYPE Find(const CTempString str, const CTempString pattern, ECase use_case=eCase, EDirection direction=eForwardSearch, SIZE_TYPE occurrence=0)
Find the pattern in the string.
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
static bool Equal(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2, ECase use_case=eCase)
Test for equality of a substring with another string.
static string URLEncode(const CTempString str, EUrlEncode flag=eUrlEnc_SkipMarkChars)
URL-encode string.
static string & ToLower(string &str)
Convert string to lower case – string& version.
@ eUrlEnc_ProcessMarkChars
Convert all non-alphanumeric chars, spaces are converted to '+'.
@ eReverseSearch
Search in a backward direction.
@ eNocase
Case insensitive compare.
string GetQueryString(EAmpEncoding amp_enc, NStr::EUrlEncode encode) const
Construct and return complete query string.
const string & GetHost(void) const
const CUrlArgs & GetArgs(void) const
Get const list of arguments.
CUrl(void)
Default constructor.
void Adjust(const CUrl &other, TAdjustFlags flags)
Adjust this URL using information from 'other' URL.
void x_SetPort(const string &port, const IUrlEncoder &encoder)
EAmpEncoding
Ampersand encoding for composed URLs.
virtual string EncodeFragment(const string &value) const =0
Encode fragment.
void x_SetPassword(const string &password, const IUrlEncoder &encoder)
virtual string EncodeUser(const string &user) const =0
Encode user name.
void AddValue(const string &name, const string &value)
Add new value even if an argument with the same name already exists.
void x_SetService(const string &service)
TArgs::const_iterator const_iterator
int TFlags
An inverted subset of CCgiRequest::TFlags.
virtual void AddArgument(unsigned int position, const string &name, const string &value, EArgType arg_type)
Process next query argument.
void x_SetUser(const string &user, const IUrlEncoder &encoder)
CUrlArgs(TFlags flags=0)
Create an empty arguments set.
void x_SetFragment(const string &fragment, const IUrlEncoder &encoder)
#define NCBI_SCHEME_SERVICE
CUrl::
bool HaveArgs(void) const
Check if the URL contains any arguments.
virtual string DecodeArgName(const string &name) const =0
Decode URL argument name.
CUrl & operator=(const CUrl &url)
void x_SetPath(const string &path, const IUrlEncoder &encoder)
iterator FindNext(const iterator &iter)
Take argument name from the iterator, find next argument with the same name, return GetArgs()....
void SetQueryString(const string &query, NStr::EUrlEncode encode)
Parse query string, call AddArgument() to store each value.
static IUrlEncoder * GetDefaultEncoder(void)
Return default URL encoder.
void x_SetScheme(const string &scheme, const IUrlEncoder &encoder)
const string & GetValue(const string &name, bool *is_found=0) const
Get value for the given name.
void x_SetHost(const string &host, const IUrlEncoder &encoder)
void x_SetIndexString(const string &query, const IUrlEncoder &encoder)
bool x_IsHostPort(const string &scheme, string &unparsed, const IUrlEncoder &encoder)
virtual string EncodePath(const string &path) const =0
Encode path on server.
virtual string EncodePassword(const string &password) const =0
Encode password.
void x_SetArgs(const string &args, const IUrlEncoder &encoder)
virtual string EncodeArgName(const string &name) const =0
Encode URL argument name.
virtual string EncodeArgValue(const string &value) const =0
Encode URL argument value.
iterator x_Find(const string &name, const iterator &start)
void SetValue(const string &name, const string &value)
Set new value for the first argument with the given name or add a new argument.
void SetUniqueValue(const string &name, const string &value)
Set value, remove any other values for the name.
iterator FindFirst(const string &name)
Find the first argument with the given name.
void SetScheme(const string &value)
virtual string DecodeArgValue(const string &value) const =0
Decode URL argument value.
virtual void AddArgument(unsigned int position, const string &name, const string &value, EArgType arg_type=eArg_Index)=0
Process next query argument.
bool IsService(void) const
unique_ptr< CUrlArgs > m_ArgsList
string ComposeUrl(CUrlArgs::EAmpEncoding amp_enc, const IUrlEncoder *encoder=0) const
Compose the URL.
@ eAmp_Char
Use & to separate arguments.
@ fPassword_ReplaceIfEmpty
Replace password only if not yet set.
@ fScheme_Replace
Replace scheme if set in 'other'.
@ fFragment_Replace
Replace fragment if set in 'other'.
@ fUser_Replace
Replace user if set in 'other'.
@ fPath_Replace
Replace path.
@ fFragment_ReplaceIfEmpty
Replace fragment only if not yet set.
@ fPassword_Replace
Replace password if set in 'other'.
@ fArgs_Append
Append args, allow duplicate names and values.
@ fPath_Append
Append new path to the existing one.
@ fUser_ReplaceIfEmpty
Replace user only if not yet set.
@ fArgs_Merge
Append new args; replace values of existing args, do not allow to set multiple values with the same n...
@ fArgs_Replace
Discard all args, replace with args from 'other'.
@ fEnableParsingAsIndex
Enable parsing input as 'indexed' query (RFC3875) when no '=' is present.
@ fSemicolonIsArgDelimiter
Treat semicolon as query string argument separator.
@ eArg_Index
Query contains a list of names: name1+name2+name3.
@ eArg_Value
Query contains name=value pairs.
TUrl & SetUrl(void)
Assign a value to Url data member.
const GenericPointer< typename T::ValueType > T2 value
NCBI_PARAM_DEF(bool, CUrl, enable_parsing_as_index, false)
typedef NCBI_PARAM_TYPE(CUrl, enable_parsing_as_index) TCUrlEnableParsingAsIndex
NCBI_PARAM_DECL(bool, CUrl, enable_parsing_as_index)
Defines unified interface to application: