* a ClientSocketContext structure on success or failure.
*/
static ClientSocketContext *
-parseHttpRequest(ConnStateData *csd, HttpParser *hp, HttpRequestMethod * method_p, Http::ProtocolVersion *http_ver)
+parseHttpRequest(ConnStateData *csd, Http1::RequestParser &hp)
{
- char *req_hdr = NULL;
- char *end;
- size_t req_sz;
- ClientHttpRequest *http;
- ClientSocketContext *result;
- StoreIOBuffer tempBuffer;
- int r;
-
- /* pre-set these values to make aborting simpler */
- *method_p = Http::METHOD_NONE;
+ /* Attempt to parse the first line; this will define where the method, url, version and header begin */
+ {
+ const bool parsedOk = hp.parse(csd->in.buf);
- /* NP: don't be tempted to move this down or remove again.
- * It's the only DDoS protection old-String has against long URL */
- if ( hp->bufsiz <= 0) {
- debugs(33, 5, "Incomplete request, waiting for end of request line");
- return NULL;
- } else if ( (size_t)hp->bufsiz >= Config.maxRequestHeaderSize && headersEnd(hp->buf, Config.maxRequestHeaderSize) == 0) {
- debugs(33, 5, "parseHttpRequest: Too large request");
- hp->request_parse_status = Http::scHeaderTooLarge;
- return parseHttpRequestAbort(csd, "error:request-too-large");
- }
-
- /* Attempt to parse the first line; this'll define the method, url, version and header begin */
- r = HttpParserParseReqLine(hp);
+ // sync the buffers after parsing.
+ csd->in.buf = hp.remaining();
- if (r == 0) {
- debugs(33, 5, "Incomplete request, waiting for end of request line");
- return NULL;
- }
-
- if (r == -1) {
- return parseHttpRequestAbort(csd, "error:invalid-request");
- }
-
- /* Request line is valid here .. */
- *http_ver = Http::ProtocolVersion(hp->req.v_maj, hp->req.v_min);
-
- /* This call scans the entire request, not just the headers */
- if (hp->req.v_maj > 0) {
- if ((req_sz = headersEnd(hp->buf, hp->bufsiz)) == 0) {
- debugs(33, 5, "Incomplete request, waiting for end of headers");
+ if (hp.needsMoreData()) {
+ debugs(33, 5, "Incomplete request, waiting for end of request line");
return NULL;
}
- } else {
- debugs(33, 3, "parseHttpRequest: Missing HTTP identifier");
- req_sz = HttpParserReqSz(hp);
- }
-
- /* We know the whole request is in hp->buf now */
-
- assert(req_sz <= (size_t) hp->bufsiz);
- /* Will the following be true with HTTP/0.9 requests? probably not .. */
- /* So the rest of the code will need to deal with '0'-byte headers (ie, none, so don't try parsing em) */
- assert(req_sz > 0);
+ if (!parsedOk) {
+ if (hp.request_parse_status == Http::scHeaderTooLarge)
+ return parseHttpRequestAbort(csd, "error:request-too-large");
- hp->hdr_end = req_sz - 1;
-
- hp->hdr_start = hp->req.end + 1;
-
- /* Enforce max_request_size */
- if (req_sz >= Config.maxRequestHeaderSize) {
- debugs(33, 5, "parseHttpRequest: Too large request");
- hp->request_parse_status = Http::scHeaderTooLarge;
- return parseHttpRequestAbort(csd, "error:request-too-large");
+ return parseHttpRequestAbort(csd, "error:invalid-request");
+ }
}
- /* Set method_p */
- *method_p = HttpRequestMethod(&hp->buf[hp->req.m_start], &hp->buf[hp->req.m_end]+1);
+ /* We know the whole request is in parser now */
+ debugs(11, 2, "HTTP Client " << csd->clientConnection);
+ debugs(11, 2, "HTTP Client REQUEST:\n---------\n" <<
+ hp.method() << " " << hp.requestUri() << " " << hp.messageProtocol() << "\n" <<
+ hp.mimeHeader() <<
+ "\n----------");
/* deny CONNECT via accelerated ports */
- if (hp.method() == Http::METHOD_CONNECT && csd->port && csd->port->flags.accelSurrogate) {
- if (*method_p == Http::METHOD_CONNECT && csd->port != NULL && csd->port->flags.accelSurrogate) {
++ if (hp.method() == Http::METHOD_CONNECT && csd->port != NULL && csd->port->flags.accelSurrogate) {
debugs(33, DBG_IMPORTANT, "WARNING: CONNECT method received on " << csd->port->transport.protocol << " Accelerator port " << csd->port->s.port());
- /* XXX need a way to say "this many character length string" */
- debugs(33, DBG_IMPORTANT, "WARNING: for request: " << hp->buf);
- hp->request_parse_status = Http::scMethodNotAllowed;
+ debugs(33, DBG_IMPORTANT, "WARNING: for request: " << hp.method() << " " << hp.requestUri() << " " << hp.messageProtocol());
+ hp.request_parse_status = Http::scMethodNotAllowed;
return parseHttpRequestAbort(csd, "error:method-not-allowed");
}
--- /dev/null
- /*HDR_IF_UNMODIFIED_SINCE,*/ /* RFC 2608, 2616 */
+#ifndef SQUID_HTTP_REGISTEREDHEADERS_H
+#define SQUID_HTTP_REGISTEREDHEADERS_H
+
+/// recognized or "known" header fields; and the RFC which defines them (or not)
+typedef enum {
+ HDR_BAD_HDR = -1,
+ HDR_ACCEPT = 0, /**< RFC 2608, 2616 */
+ HDR_ACCEPT_CHARSET, /**< RFC 2608, 2616 */
+ HDR_ACCEPT_ENCODING, /**< RFC 2608, 2616 */
+ /*HDR_ACCEPT_FEATURES,*/ /* experimental RFC 2295 */
+ HDR_ACCEPT_LANGUAGE, /**< RFC 2608, 2616 */
+ HDR_ACCEPT_RANGES, /**< RFC 2608, 2616 */
+ HDR_AGE, /**< RFC 2608, 2616 */
+ HDR_ALLOW, /**< RFC 2608, 2616 */
+ /*HDR_ALTERNATES,*/ /* deprecated RFC 2068, 2295 */
+ HDR_AUTHORIZATION, /**< RFC 2608, 2616, 4559 */
+ HDR_CACHE_CONTROL, /**< RFC 2608, 2616 */
+ HDR_CONNECTION, /**< RFC 2608, 2616 */
+ HDR_CONTENT_BASE, /**< RFC 2608 */
+ HDR_CONTENT_DISPOSITION, /**< RFC 2183, 2616 */
+ HDR_CONTENT_ENCODING, /**< RFC 2608, 2616 */
+ HDR_CONTENT_LANGUAGE, /**< RFC 2608, 2616 */
+ HDR_CONTENT_LENGTH, /**< RFC 2608, 2616 */
+ HDR_CONTENT_LOCATION, /**< RFC 2608, 2616 */
+ HDR_CONTENT_MD5, /**< RFC 2608, 2616 */
+ HDR_CONTENT_RANGE, /**< RFC 2608, 2616 */
+ HDR_CONTENT_TYPE, /**< RFC 2608, 2616 */
+ /*HDR_CONTENT_VERSION,*/ /* deprecated RFC 2608 header. */
+ HDR_COOKIE, /**< de-facto and RFC 2965 header we may need to erase */
+ HDR_COOKIE2, /**< obsolete RFC 2965 header we may need to erase */
+ HDR_DATE, /**< RFC 2608, 2616 */
+ /*HDR_DAV,*/ /* RFC 2518 */
+ /*HDR_DEPTH,*/ /* RFC 2518 */
+ /*HDR_DERIVED_FROM,*/ /* deprecated RFC 2608 */
+ /*HDR_DESTINATION,*/ /* RFC 2518 */
+ HDR_ETAG, /**< RFC 2608, 2616 */
+ HDR_EXPECT, /**< RFC 2608, 2616 */
+ HDR_EXPIRES, /**< RFC 2608, 2616 */
++ HDR_FORWARDED, /**< RFC 7239 */
+ HDR_FROM, /**< RFC 2608, 2616 */
+ HDR_HOST, /**< RFC 2608, 2616 */
+ HDR_HTTP2_SETTINGS, /**< HTTP/2.0 upgrade header. see draft-ietf-httpbis-http2-04 */
+ /*HDR_IF,*/ /* RFC 2518 */
+ HDR_IF_MATCH, /**< RFC 2608, 2616 */
+ HDR_IF_MODIFIED_SINCE, /**< RFC 2608, 2616 */
+ HDR_IF_NONE_MATCH, /**< RFC 2608, 2616 */
+ HDR_IF_RANGE, /**< RFC 2608, 2616 */
- HDR_TITLE, /**< obsolete draft suggested header */
++ /*HDR_IF_UNMODIFIED_SINCE,*/ /**< RFC 2608, 2616 */
+ HDR_KEEP_ALIVE, /**< obsolete HTTP/1.0 header we may need to erase */
+ HDR_KEY, /**< experimental RFC Draft draft-fielding-http-key-02 */
+ HDR_LAST_MODIFIED, /**< RFC 2608, 2616 */
+ HDR_LINK, /**< RFC 2068 */
+ HDR_LOCATION, /**< RFC 2608, 2616 */
+ /*HDR_LOCK_TOKEN,*/ /* RFC 2518 */
+ HDR_MAX_FORWARDS, /**< RFC 2608, 2616 */
+ HDR_MIME_VERSION, /**< RFC 2626 */
+ HDR_NEGOTIATE, /**< experimental RFC 2295. Why only this one from 2295? */
+ /*HDR_OVERWRITE,*/ /* RFC 2518 */
+ HDR_ORIGIN, /* CORS Draft specification (see http://www.w3.org/TR/cors/) */
+ HDR_PRAGMA, /**< deprecated RFC 2068,2616 header we may need to erase */
+ HDR_PROXY_AUTHENTICATE, /**< RFC 2608, 2616, 2617 */
+ HDR_PROXY_AUTHENTICATION_INFO, /**< RFC 2617 */
+ HDR_PROXY_AUTHORIZATION, /**< RFC 2608, 2616, 2617 */
+ HDR_PROXY_CONNECTION, /**< obsolete Netscape header we may need to erase. */
+ HDR_PROXY_SUPPORT, /**< RFC 4559 */
+ HDR_PUBLIC, /**< RFC 2608 */
+ HDR_RANGE, /**< RFC 2608, 2616 */
+ HDR_REFERER, /**< RFC 2608, 2616 */
+ HDR_REQUEST_RANGE, /**< some clients use this, sigh */
+ HDR_RETRY_AFTER, /**< RFC 2608, 2616 */
+ HDR_SERVER, /**< RFC 2608, 2616 */
+ HDR_SET_COOKIE, /**< de-facto standard header we may need to erase */
+ HDR_SET_COOKIE2, /**< obsolete RFC 2965 header we may need to erase */
+ /*HDR_STATUS_URI,*/ /* RFC 2518 */
+ /*HDR_TCN,*/ /* experimental RFC 2295 */
+ HDR_TE, /**< RFC 2616 */
+ /*HDR_TIMEOUT,*/ /* RFC 2518 */
- HDR_X_FORWARDED_FOR, /**< Squid custom header */
++ HDR_TITLE, /* obsolete draft suggested header */
+ HDR_TRAILER, /**< RFC 2616 */
+ HDR_TRANSFER_ENCODING, /**< RFC 2608, 2616 */
+ HDR_TRANSLATE, /**< IIS custom header we may need to erase */
+ HDR_UNLESS_MODIFIED_SINCE, /**< IIS custom header we may need to erase */
+ HDR_UPGRADE, /**< RFC 2608, 2616 */
+ /*HDR_URI,*/ /* obsolete RFC 2068 header */
+ HDR_USER_AGENT, /**< RFC 2608, 2616 */
+ /*HDR_VARIANT_VARY,*/ /* experimental RFC 2295 */
+ HDR_VARY, /**< RFC 2608, 2616 */
+ HDR_VIA, /**< RFC 2608, 2616 */
+ HDR_WARNING, /**< RFC 2608, 2616 */
+ HDR_WWW_AUTHENTICATE, /**< RFC 2608, 2616, 2617, 4559 */
+ HDR_AUTHENTICATION_INFO, /**< RFC 2617 */
+ HDR_X_CACHE, /**< Squid custom header */
+ HDR_X_CACHE_LOOKUP, /**< Squid custom header. temporary hack that became de-facto. TODO remove */
++ HDR_X_FORWARDED_FOR, /**< obsolete Squid custom header */
+ HDR_X_REQUEST_URI, /**< Squid custom header appended if ADD_X_REQUEST_URI is defined */
+ HDR_X_SQUID_ERROR, /**< Squid custom header on generated error responses */
+#if X_ACCELERATOR_VARY
+ HDR_X_ACCELERATOR_VARY, /**< obsolete Squid custom header. */
+#endif
+#if USE_ADAPTATION
+ HDR_X_NEXT_SERVICES, /**< Squid custom ICAP header */
+#endif
+ HDR_SURROGATE_CAPABILITY, /**< Edge Side Includes (ESI) header */
+ HDR_SURROGATE_CONTROL, /**< Edge Side Includes (ESI) header */
+ HDR_FRONT_END_HTTPS, /**< MS Exchange custom header we may have to add */
+ HDR_OTHER, /**< internal tag value for "unknown" headers */
+ HDR_ENUM_END
+} http_hdr_type;
+
+#endif /* SQUID_HTTP_REGISTEREDHEADERS_H */