LCOV - code coverage report
Current view: top level - waltz/http - fd_url.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 7 93 7.5 %
Date: 2025-08-05 05:04:49 Functions: 1 3 33.3 %

          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 : }
      73             : 
      74             : 
      75             : static inline int
      76           0 : fd_hex_unhex( int c ) {
      77           0 :   if( c>='0' && c<='9' ) return c-'0';
      78           0 :   if( c>='a' && c<='f' ) return c-'a'+0xa;
      79           0 :   if( c>='A' && c<='F' ) return c-'A'+0xa;
      80           0 :   return -1;
      81           0 : }
      82             : 
      83             : ulong
      84             : fd_url_unescape( char * const msg,
      85          12 :                  ulong  const len ) {
      86          12 :   char * end = msg+len;
      87          12 :   int state = 0;
      88          12 :   char * dst = msg;
      89          12 :   for( char * src=msg; src<end; src++ ) {
      90             :     /* invariant: p<=msg */
      91           0 :     switch( state ) {
      92           0 :     case 0:
      93           0 :       if( FD_LIKELY( (*src)!='%' ) ) {
      94           0 :         *dst = *src;
      95           0 :         dst++;
      96           0 :       } else {
      97           0 :         state = 1;
      98           0 :       }
      99           0 :       break;
     100           0 :     case 1:
     101           0 :       if( FD_LIKELY( (*src)!='%' ) )  {
     102           0 :         *dst = (char)( ( fd_hex_unhex( *src )&0xf )<<4 );
     103           0 :         state = 2;
     104           0 :       } else {
     105             :         /* FIXME is 'aa%%aa' a valid escape? */
     106           0 :         *(dst++) = '%';
     107           0 :         state = 0;
     108           0 :       }
     109           0 :       break;
     110           0 :     case 2:
     111           0 :       *dst = (char)( (*dst) | ( fd_hex_unhex( *src )&0xf ) );
     112           0 :       dst++;
     113           0 :       state = 0;
     114           0 :       break;
     115           0 :     }
     116           0 :   }
     117          12 :   return (ulong)( dst-msg );
     118          12 : }

Generated by: LCOV version 1.14