Line data Source code
1 : #include "fd_url.h" 2 : 3 : fd_url_t * 4 : fd_url_parse_cstr( fd_url_t * const url, 5 : char const * const url_str, 6 : ulong const url_str_len, 7 0 : int * opt_err ) { 8 0 : int err_[1]; 9 0 : if( !opt_err ) opt_err = err_; 10 0 : *opt_err = FD_URL_SUCCESS; 11 : 12 0 : char const * const url_end = url_str+url_str_len; 13 : 14 0 : char const * const scheme = url_str; 15 0 : ulong scheme_len = 0UL; 16 0 : if( FD_UNLIKELY( url_str_len<8UL ) ) return NULL; 17 0 : if( fd_memeq( scheme, "http://", 7 ) ) { 18 0 : scheme_len = 7; 19 0 : } else if( fd_memeq( scheme, "https://", 8 ) ) { 20 0 : scheme_len = 8; 21 0 : } else { 22 0 : *opt_err = FD_URL_ERR_SCHEME; 23 0 : return NULL; 24 0 : } 25 : 26 0 : char const * const authority = scheme+scheme_len; 27 : 28 : /* Find beginning of path */ 29 0 : char const * authority_end; 30 0 : for( authority_end = authority; 31 0 : authority_end < url_end && *authority_end!='/'; 32 0 : authority_end++ ) { 33 0 : if( FD_UNLIKELY( *authority_end=='@' ) ) { 34 0 : *opt_err = FD_URL_ERR_USERINFO; 35 0 : return NULL; /* userinfo not supported */ 36 0 : } 37 0 : } 38 0 : ulong const authority_len = (ulong)( authority_end-authority ); 39 : 40 : /* Find port number */ 41 0 : char const * const host = authority; 42 0 : ulong host_len = authority_len; 43 0 : char const * port = NULL; 44 0 : ulong port_len = 0UL; 45 0 : for( ulong j=0UL; j<authority_len; j++ ) { 46 0 : if( authority[ j ]==':' ) { 47 0 : host_len = j; 48 0 : port = authority +j+1; 49 0 : port_len = authority_len-j-1; 50 0 : break; 51 0 : } 52 0 : } 53 : 54 0 : if( FD_UNLIKELY( host_len>255 ) ) { 55 0 : *opt_err = FD_URL_ERR_HOST_OVERSZ; 56 0 : return NULL; 57 0 : } 58 : 59 : 60 0 : *url = (fd_url_t){ 61 0 : .scheme = scheme, 62 0 : .scheme_len = scheme_len, 63 0 : .host = host, 64 0 : .host_len = host_len, 65 0 : .port = port, 66 0 : .port_len = port_len, 67 0 : .tail = authority+authority_len, 68 0 : .tail_len = (ulong)( url_end-(authority+authority_len) ) 69 0 : }; 70 : 71 0 : return url; 72 0 : }