/************************************************************************ * Function : parse_uri * * Parameters : * char * in ; character string containing uri information to be * parsed * int max ; maximum limit on the number of characters * uri_type * out ; out parameter which will have the parsed uri * information * * Description : parses a uri as defined in http://www.ietf.org/rfc/ * rfc2396.txt (RFC explaining URIs) * Handles absolute, relative, and opaque uris. Parses into the * following pieces: scheme, hostport, pathquery, fragment (path and * query are treated as one token) * Caller should check for the pieces they require. * * Return : int ; * * Note : ************************************************************************/ int parse_uri( const char *in, int max, uri_type * out ) { int begin_path = 0; int begin_hostport = 0; int begin_fragment = 0; if( ( begin_hostport = parse_scheme( in, max, &out->scheme ) ) ) { out->type = ABSOLUTE; out->path_type = OPAQUE_PART; begin_hostport++; } else { out->type = RELATIVE; out->path_type = REL_PATH; } if( ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' ) && ( in[begin_hostport + 1] == '/' ) ) { begin_hostport += 2; if( ( begin_path = parse_hostport( &in[begin_hostport], max - begin_hostport, &out->hostport ) ) >= 0 ) { begin_path += begin_hostport; } else return begin_path; } else { out->hostport.IPv4address.sin_port = 0; out->hostport.IPv4address.sin_addr.s_addr = 0; out->hostport.text.size = 0; out->hostport.text.buff = 0; begin_path = begin_hostport; } begin_fragment = parse_uric( &in[begin_path], max - begin_path, &out->pathquery ) + begin_path; if( ( out->pathquery.size ) && ( out->pathquery.buff[0] == '/' ) ) { out->path_type = ABS_PATH; } if( ( begin_fragment < max ) && ( in[begin_fragment] == '#' ) ) { begin_fragment++; parse_uric( &in[begin_fragment], max - begin_fragment, &out->fragment ); } else { out->fragment.buff = NULL; out->fragment.size = 0; } return HTTP_SUCCESS; }
int parse_uri(const char *in, size_t max, uri_type *out) { int begin_path = 0; size_t begin_hostport = (size_t)0; size_t begin_fragment = (size_t)0; unsigned short int defaultPort = 80; begin_hostport = parse_scheme(in, max, &out->scheme); if (begin_hostport) { out->type = ABSOLUTE; out->path_type = OPAQUE_PART; begin_hostport++; } else { out->type = RELATIVE; out->path_type = REL_PATH; } if (begin_hostport + (size_t)1 < max && in[begin_hostport] == '/' && in[begin_hostport + (size_t)1] == '/') { begin_hostport += (size_t)2; if (token_string_casecmp(&out->scheme, "https") == 0) { defaultPort = 443; } begin_path = parse_hostport(&in[begin_hostport], defaultPort, &out->hostport); if (begin_path >= 0) { begin_path += (int)begin_hostport; } else return begin_path; } else { memset(&out->hostport, 0, sizeof(out->hostport)); begin_path = (int)begin_hostport; } begin_fragment = parse_uric(&in[begin_path], max - (size_t)begin_path, &out->pathquery) + (size_t)begin_path; if (out->pathquery.size && out->pathquery.buff[0] == '/') { out->path_type = ABS_PATH; } if (begin_fragment < max && in[begin_fragment] == '#') { begin_fragment++; parse_uric(&in[begin_fragment], max - begin_fragment, &out->fragment); } else { out->fragment.buff = NULL; out->fragment.size = (size_t)0; } return HTTP_SUCCESS; }