diff --git a/src/httpd.c b/src/httpd.c index ec4ca9d8..08663a8e 100644 --- a/src/httpd.c +++ b/src/httpd.c @@ -314,7 +314,10 @@ request_set(struct httpd_request *hreq, httpd_backend *backend, const char *uri, { backend_data = httpd_backend_data_create(backend); hreq->backend_data = backend_data; + hreq->uri = httpd_backend_uri_get(backend, backend_data); + hreq->uri_parsed = httpd_uri_parsed_create(backend); + hreq->in_headers = httpd_backend_input_headers_get(backend); hreq->out_headers = httpd_backend_output_headers_get(backend); hreq->in_body = httpd_backend_input_buffer_get(backend); @@ -326,20 +329,21 @@ request_set(struct httpd_request *hreq, httpd_backend *backend, const char *uri, else { hreq->uri = uri; + hreq->uri_parsed = httpd_uri_parsed_create_fromuri(uri); + hreq->user_agent = user_agent; } - // Don't write directly to backend's buffer. This way we are sure we own the - // buffer even if there is no backend. - CHECK_NULL(L_HTTPD, hreq->out_body = evbuffer_new()); - - hreq->uri_parsed = httpd_uri_parsed_create(hreq->uri); if (!hreq->uri_parsed) { DPRINTF(E_LOG, L_HTTPD, "Unable to parse URI '%s' in request from '%s'\n", hreq->uri, hreq->peer_address); return; } + // Don't write directly to backend's buffer. This way we are sure we own the + // buffer even if there is no backend. + CHECK_NULL(L_HTTPD, hreq->out_body = evbuffer_new()); + hreq->path = httpd_uri_path_get(hreq->uri_parsed); hreq->query = httpd_uri_query_get(hreq->uri_parsed); httpd_uri_path_parts_get(&hreq->path_parts, hreq->uri_parsed); diff --git a/src/httpd_internal.h b/src/httpd_internal.h index 87b3d535..8ad3874f 100644 --- a/src/httpd_internal.h +++ b/src/httpd_internal.h @@ -332,7 +332,10 @@ void httpd_backend_preprocess(httpd_backend *backend); httpd_uri_parsed * -httpd_uri_parsed_create(const char *uri); +httpd_uri_parsed_create(httpd_backend *backend); + +httpd_uri_parsed * +httpd_uri_parsed_create_fromuri(const char *uri); void httpd_uri_parsed_free(httpd_uri_parsed *uri_parsed); diff --git a/src/httpd_libevhtp.c b/src/httpd_libevhtp.c index 9fb243a0..4741eb9a 100644 --- a/src/httpd_libevhtp.c +++ b/src/httpd_libevhtp.c @@ -16,6 +16,7 @@ struct httpd_backend_data struct httpd_uri_parsed { evhtp_uri_t *ev_uri; + bool ev_uri_is_standalone; // true if ev_uri was allocated without a request, but via _fromuri httpd_uri_path_parts path_parts; }; @@ -137,7 +138,7 @@ httpd_server_new(struct event_base *evbase, unsigned short port, httpd_general_c if (fd < 0) goto error; - if (evhtp_accept_socket(server, fd, 0) != 0) + if (evhtp_accept_socket(server, fd, -1) != 0) goto error; evhtp_set_gencb(server, cb, arg); @@ -285,35 +286,30 @@ httpd_backend_preprocess(httpd_backend *backend) } httpd_uri_parsed * -httpd_uri_parsed_create(const char *uri) +httpd_uri_parsed_create(httpd_backend *backend) { - struct httpd_uri_parsed *parsed; - const char *query; + httpd_uri_parsed *parsed; char *path = NULL; char *path_part; char *ptr; + unsigned char *unescaped_part; int i; parsed = calloc(1, sizeof(struct httpd_uri_parsed)); if (!parsed) goto error; - parsed->ev_uri = evhttp_uri_parse_with_flags(uri, EVHTTP_URI_NONCONFORMANT); - if (!parsed->ev_uri) - goto error; + parsed->ev_uri = backend->uri; - query = evhttp_uri_get_query(parsed->ev_uri); - if (query && strchr(query, '=') && evhttp_parse_query_str(query, &(parsed->query)) < 0) - goto error; - - path = strdup(evhttp_uri_get_path(parsed->ev_uri)); - if (!path || !(parsed->path = evhttp_uridecode(path, 0, NULL))) + path = strdup(parsed->ev_uri->path->path); + if (!path) goto error; path_part = strtok_r(path, "/", &ptr); for (i = 0; (i < ARRAY_SIZE(parsed->path_parts) && path_part); i++) { - parsed->path_parts[i] = evhttp_uridecode(path_part, 0, NULL); + evhtp_unescape_string(&unescaped_part, (unsigned char *)path_part, strlen(path_part)); + parsed->path_parts[i] = (char *)unescaped_part; path_part = strtok_r(NULL, "/", &ptr); } @@ -326,28 +322,20 @@ httpd_uri_parsed_create(const char *uri) error: free(path); - httpd_uri_parsed_free(parsed); + return NULL; +} + +httpd_uri_parsed * +httpd_uri_parsed_create_fromuri(const char *uri) +{ return NULL; } void httpd_uri_parsed_free(httpd_uri_parsed *parsed) { - int i; - - if (!parsed) - return; - - free(parsed->path); - for (i = 0; i < ARRAY_SIZE(parsed->path_parts); i++) - free(parsed->path_parts[i]); - - httpd_query_clear(&(parsed->query)); - - if (parsed->ev_uri) - evhttp_uri_free(parsed->ev_uri); - - free(parsed); +// if (parsed->ev_uri_is_standalone) +// free ev_uri; } httpd_query *