////////////////////////////////////////////////////////////////////////// Name : check_request_validity() Description: checks to see if incoming request has necessary fields Input : State, header (can we do this without the state?) Output : enum RequestError_t of the error type, if any Details : //////////////////////////////////////////////////////////////////////////
| 5337 | // |
| 5338 | /////////////////////////////////////////////////////////////////////////////// |
| 5339 | HttpTransact::RequestError_t |
| 5340 | HttpTransact::check_request_validity(State *s, HTTPHdr *incoming_hdr) |
| 5341 | { |
| 5342 | // Called also on receiving request. Not sure if we need to call this again in case |
| 5343 | // the transfer-encoding and content-length headers changed |
| 5344 | set_client_request_state(s, incoming_hdr); |
| 5345 | if (incoming_hdr == nullptr) { |
| 5346 | return NON_EXISTANT_REQUEST_HEADER; |
| 5347 | } |
| 5348 | |
| 5349 | if (!(HttpTransactHeaders::is_request_proxy_authorized(incoming_hdr))) { |
| 5350 | return FAILED_PROXY_AUTHORIZATION; |
| 5351 | } |
| 5352 | |
| 5353 | URL *incoming_url = incoming_hdr->url_get(); |
| 5354 | int hostname_len; |
| 5355 | const char *hostname = incoming_hdr->host_get(&hostname_len); |
| 5356 | |
| 5357 | if (hostname == nullptr) { |
| 5358 | return MISSING_HOST_FIELD; |
| 5359 | } |
| 5360 | |
| 5361 | if (hostname_len >= MAXDNAME || hostname_len <= 0 || memchr(hostname, '\0', hostname_len)) { |
| 5362 | return BAD_HTTP_HEADER_SYNTAX; |
| 5363 | } |
| 5364 | |
| 5365 | int scheme = incoming_url->scheme_get_wksidx(); |
| 5366 | int method = incoming_hdr->method_get_wksidx(); |
| 5367 | |
| 5368 | if (!((scheme == URL_WKSIDX_HTTP) && (method == HTTP_WKSIDX_GET))) { |
| 5369 | if (scheme != URL_WKSIDX_HTTP && scheme != URL_WKSIDX_HTTPS && method != HTTP_WKSIDX_CONNECT && |
| 5370 | !((scheme == URL_WKSIDX_WS || scheme == URL_WKSIDX_WSS) && s->is_websocket)) { |
| 5371 | if (scheme < 0) { |
| 5372 | return NO_REQUEST_SCHEME; |
| 5373 | } else { |
| 5374 | return SCHEME_NOT_SUPPORTED; |
| 5375 | } |
| 5376 | } |
| 5377 | |
| 5378 | if (!HttpTransactHeaders::is_this_method_supported(scheme, method)) { |
| 5379 | return METHOD_NOT_SUPPORTED; |
| 5380 | } |
| 5381 | if ((method == HTTP_WKSIDX_CONNECT) && !s->transparent_passthrough && |
| 5382 | (!is_port_in_range(incoming_hdr->url_get()->port_get(), s->http_config_param->connect_ports))) { |
| 5383 | TxnDbg(dbg_ctl_http_trans, "Rejected a CONNECT to port %d not in connect_ports", incoming_hdr->url_get()->port_get()); |
| 5384 | return BAD_CONNECT_PORT; |
| 5385 | } |
| 5386 | |
| 5387 | if (s->client_info.transfer_encoding == CHUNKED_ENCODING && incoming_hdr->version_get() < HTTP_1_1) { |
| 5388 | // Per spec, Transfer-Encoding is only supported in HTTP/1.1. For earlier |
| 5389 | // versions, we must reject Transfer-Encoding rather than interpret it |
| 5390 | // since downstream proxies may ignore the chunk header and rely upon the |
| 5391 | // Content-Length, or interpret the body some other way. These |
| 5392 | // differences in interpretation may open up the door to compatibility |
| 5393 | // issues. To protect against this, we reply with a 4xx if the client |
| 5394 | // uses Transfer-Encoding with HTTP versions that do not support it. |
| 5395 | return UNACCEPTABLE_TE_REQUIRED; |
| 5396 | } |
nothing calls this directly
no test coverage detected