2020 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2121 */
2222
23+ /* Standard includes. */
24+ #include <assert.h>
25+ #include <stdlib.h>
26+ #include <string.h>
27+
28+ /* Include Demo Config as the first non-system header. */
29+ #include "demo_config.h"
30+
2331/* Demo utils header. */
24- #include "http_demo_utils.h"
32+ #include "http_demo_url_utils.h"
33+
34+ /*-----------------------------------------------------------*/
2535
26- /* Third party parser utilities. */
27- #include "http_parser.h"
36+ /**
37+ * @brief The separator between the "https" scheme and the host in a URL.
38+ */
39+ #define SCHEME_SEPARATOR "://"
40+
41+ /**
42+ * @brief The length of the "://" separator.
43+ */
44+ #define SCHEME_SEPARATOR_LEN ( sizeof( SCHEME_SEPARATOR ) - 1 )
2845
2946/*-----------------------------------------------------------*/
3047
@@ -33,13 +50,10 @@ HTTPStatus_t getUrlPath( const char * pUrl,
3350 const char * * pPath ,
3451 size_t * pPathLen )
3552{
36- /* http-parser status. Initialized to 1 to signify failure. */
37- int parserStatus = 1 ;
38- struct http_parser_url urlParser ;
3953 HTTPStatus_t httpStatus = HTTPSuccess ;
40-
41- /* Sets all members in urlParser to 0. */
42- http_parser_url_init ( & urlParser ) ;
54+ const char * pHostStart = NULL ;
55+ const char * pPathStart = NULL ;
56+ size_t hostLen = 0 , i = 0 , pathStartIndex = 0 , pathLen = 0 ;
4357
4458 if ( ( pUrl == NULL ) || ( pPath == NULL ) || ( pPathLen == NULL ) )
4559 {
@@ -49,33 +63,53 @@ HTTPStatus_t getUrlPath( const char * pUrl,
4963
5064 if ( httpStatus == HTTPSuccess )
5165 {
52- parserStatus = http_parser_parse_url ( pUrl , urlLen , 0 , & urlParser );
53-
54- if ( parserStatus != 0 )
55- {
56- LogError ( ( "Error parsing the input URL %.*s. Error code: %d." ,
57- ( int32_t ) urlLen ,
58- pUrl ,
59- parserStatus ) );
60- httpStatus = HTTPParserInternalError ;
61- }
66+ httpStatus = getUrlAddress ( pUrl , urlLen , & pHostStart , & hostLen );
6267 }
6368
6469 if ( httpStatus == HTTPSuccess )
6570 {
66- * pPathLen = ( size_t ) ( urlParser .field_data [ UF_PATH ].len );
71+ /* Search for the start of the path. */
72+ for ( i = ( pHostStart - pUrl ) + hostLen ; i < urlLen ; i ++ )
73+ {
74+ if ( pUrl [ i ] == '/' )
75+ {
76+ pPathStart = & pUrl [ i ];
77+ pathStartIndex = i ;
78+ break ;
79+ }
80+ }
6781
68- if ( * pPathLen == 0 )
82+ if ( pPathStart != NULL )
6983 {
70- httpStatus = HTTPNoResponse ;
71- * pPath = NULL ;
84+ /* The end of the path will be either the start of the query,
85+ * start of the fragment, or end of the URL. If this is an S3
86+ * presigned URL, then there must be a query. */
87+ for ( i = pathStartIndex ; i < urlLen ; i ++ )
88+ {
89+ if ( pUrl [ i ] == '?' )
90+ {
91+ break ;
92+ }
93+ }
94+
95+ pathLen = i - pathStartIndex ;
7296 }
73- else
97+
98+ if ( pathLen == 0 )
7499 {
75- * pPath = & pUrl [ urlParser .field_data [ UF_PATH ].off ];
100+ LogError ( ( "Could not parse path from input URL %.*s" ,
101+ ( int32_t ) urlLen ,
102+ pUrl ) );
103+ httpStatus = HTTPNoResponse ;
76104 }
77105 }
78106
107+ if ( httpStatus == HTTPSuccess )
108+ {
109+ * pPathLen = pathLen ;
110+ * pPath = pPathStart ;
111+ }
112+
79113 if ( httpStatus != HTTPSuccess )
80114 {
81115 LogError ( ( "Error parsing the path from URL %s. Error code: %d" ,
@@ -93,13 +127,10 @@ HTTPStatus_t getUrlAddress( const char * pUrl,
93127 const char * * pAddress ,
94128 size_t * pAddressLen )
95129{
96- /* http-parser status. Initialized to 1 to signify failure. */
97- int parserStatus = 1 ;
98- struct http_parser_url urlParser ;
99130 HTTPStatus_t httpStatus = HTTPSuccess ;
100-
101- /* Sets all members in urlParser to 0. */
102- http_parser_url_init ( & urlParser ) ;
131+ const char * pHostStart = NULL ;
132+ const char * pHostEnd = NULL ;
133+ size_t i = 0 , hostLen = 0 ;
103134
104135 if ( ( pUrl == NULL ) || ( pAddress == NULL ) || ( pAddressLen == NULL ) )
105136 {
@@ -109,30 +140,54 @@ HTTPStatus_t getUrlAddress( const char * pUrl,
109140
110141 if ( httpStatus == HTTPSuccess )
111142 {
112- parserStatus = http_parser_parse_url ( pUrl , urlLen , 0 , & urlParser );
143+ /* Search for the start of the hostname using the "://" separator. */
144+ for ( i = 0 ; i < ( urlLen - SCHEME_SEPARATOR_LEN ); i ++ )
145+ {
146+ if ( strncmp ( & ( pUrl [ i ] ), SCHEME_SEPARATOR , SCHEME_SEPARATOR_LEN ) == 0 )
147+ {
148+ pHostStart = pUrl + i + SCHEME_SEPARATOR_LEN ;
149+ break ;
150+ }
151+ }
113152
114- if ( parserStatus != 0 )
153+ if ( pHostStart == NULL )
115154 {
116- LogError ( ( "Error parsing the input URL %.*s. Error code: %d. " ,
155+ LogError ( ( "Could not find \"://\" scheme separator in input URL %.*s" ,
117156 ( int32_t ) urlLen ,
118- pUrl ,
119- parserStatus ) );
157+ pUrl ) );
120158 httpStatus = HTTPParserInternalError ;
121159 }
160+ else
161+ {
162+ /* Search for the end of the hostname assuming that the object path
163+ * is next. Assume that there is no port number as this is used for
164+ * S3 presigned URLs. */
165+ for ( pHostEnd = pHostStart ; pHostEnd < ( pUrl + urlLen ); pHostEnd ++ )
166+ {
167+ if ( * pHostEnd == '/' )
168+ {
169+ hostLen = ( size_t ) ( pHostEnd - pHostStart );
170+ break ;
171+ }
172+ }
173+ }
122174 }
123175
124176 if ( httpStatus == HTTPSuccess )
125177 {
126- * pAddressLen = ( size_t ) ( urlParser . field_data [ UF_HOST ]. len ) ;
178+ * pAddressLen = hostLen ;
127179
128- if ( * pAddressLen == 0 )
180+ if ( hostLen == 0 )
129181 {
182+ LogError ( ( "Could not find end of host in input URL %.*s" ,
183+ ( int32_t ) urlLen ,
184+ pUrl ) );
130185 httpStatus = HTTPNoResponse ;
131186 * pAddress = NULL ;
132187 }
133188 else
134189 {
135- * pAddress = & pUrl [ urlParser . field_data [ UF_HOST ]. off ] ;
190+ * pAddress = pHostStart ;
136191 }
137192 }
138193
0 commit comments