avs_url_t *avs_url_parse(const char *raw_url) { // In data, we store all the components from raw_url; // The input url, in its fullest possible form, looks like this: // // proto://user:password@hostname:port/path\0 // // The output data will look like this: // // proto\0user\0password\0hostname\0port\0/path\0 // // A copy of the original string would require strlen(raw_url)+1 bytes. // Then: // - we replace "://" with a single nullbyte : -2 bytes // - we replace ":" before password with nullbyte : +-0 bytes // - we replace "@" before hostname with nullbyte : +-0 bytes // - we replace ":" before port with nullbyte : +-0 bytes // - we add a nullbyte before path's "/" : +1 byte // - we add a "/" in path if it's empty or query string only: +1 byte // ----------- // TOTAL DIFFERENCE IN REQUIRED SIZE: 0 bytes // // Thus, we know that we need out->data to be strlen(raw_url)+1 bytes long. size_t data_length = strlen(raw_url) + 1; avs_url_t *out = (avs_url_t *) avs_calloc(1, offsetof(avs_url_t, data) + data_length); if (!out) { LOG(ERROR, "out of memory"); return NULL; } size_t data_out_ptr = 0; if (url_parse_protocol(&raw_url, &data_out_ptr, data_length, out) || url_parse_credentials(&raw_url, &data_out_ptr, data_length, out) || url_parse_host(&raw_url, &data_out_ptr, data_length, out) || url_parse_port(&raw_url, &data_out_ptr, data_length, out) || url_parse_path(&raw_url, &data_out_ptr, data_length, out) || url_parsed(raw_url)) { avs_free(out); return NULL; } return out; }
/** * Parses first line of request */ uint8_t* ICACHE_FLASH_ATTR http_request_parse_method_line( http_request_object_type* request, uint8_t* data ) { uint8_t* w, v, *end, ev; char hpost[ 5 ] = "POST", hget[ 4 ] = "GET"; ev = *( end = get_line_ending( data )); ( *end ) = '\0'; request->method = HTTP_METHOD_NONE; data = skip_whitespace( data ); v = *( w = skip_to_whitespace( data ) ); ( *w ) = '\0'; if( strcmp( hget, ( char* ) data ) == 0 ) request->method = HTTP_METHOD_GET; if( strcmp( hpost, ( char* ) data ) == 0 ) request->method = HTTP_METHOD_POST; ( *w ) = v; data = skip_whitespace( w ); v = *( w = skip_to_whitespace( data ) ); ( *w ) = '\0'; url_parse_path( request->location, data ); ( *w ) = v; ( *end ) = ev; return skip_line_ending( end ); }