uint16_t HTTP1_DissectRequest(struct http_conn *htc, struct http *hp) { uint16_t retval; const char *p; const char *b = NULL, *e; CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); retval = http1_splitline(hp, htc, HTTP1_Req, cache_param->http_req_hdr_len); if (retval != 0) return (retval); hp->protover = http1_proto_ver(hp); if (hp->protover == 0) return (400); if (http_CountHdr(hp, H_Host) > 1) return (400); if (http_CountHdr(hp, H_Content_Length) > 1) return (400); /* RFC2616, section 5.2, point 1 */ if (!strncasecmp(hp->hd[HTTP_HDR_URL].b, "http://", 7)) b = hp->hd[HTTP_HDR_URL].b + 7; else if (FEATURE(FEATURE_HTTPS_SCHEME) && !strncasecmp(hp->hd[HTTP_HDR_URL].b, "https://", 8)) b = hp->hd[HTTP_HDR_URL].b + 8; if (b) { e = strchr(b, '/'); if (e) { http_Unset(hp, H_Host); http_PrintfHeader(hp, "Host: %.*s", (int)(e - b), b); hp->hd[HTTP_HDR_URL].b = e; } } htc->body_status = http1_body_status(hp, htc, 1); if (htc->body_status == BS_ERROR) return (400); p = http_GetMethod(hp); AN(p); if (htc->body_status == BS_EOF) { assert(hp->protover == 10); /* RFC1945 8.3 p32 and D.1.1 p58 */ if (!strcasecmp(p, "post") || !strcasecmp(p, "put")) return (400); htc->body_status = BS_NONE; } /* HEAD with a body is a hard error */ if (htc->body_status != BS_NONE && !strcasecmp(p, "head")) return (400); return (retval); }
uint16_t HTTP1_DissectResponse(struct http_conn *htc, struct http *hp, const struct http *req) { uint16_t retval = 0; const char *p; int8_t rv; CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); CHECK_OBJ_NOTNULL(req, HTTP_MAGIC); if (http1_splitline(hp, htc, HTTP1_Resp, cache_param->http_resp_hdr_len)) retval = 503; if (retval == 0) { hp->protover = http1_proto_ver(hp); if (hp->protover == 0) retval = 503; rv = http1_proto_ver(req); if (hp->protover > rv) hp->protover = rv; } if (retval == 0 && Tlen(hp->hd[HTTP_HDR_STATUS]) != 3) retval = 503; if (retval == 0) { p = hp->hd[HTTP_HDR_STATUS].b; if (p[0] >= '1' && p[0] <= '9' && p[1] >= '0' && p[1] <= '9' && p[2] >= '0' && p[2] <= '9') hp->status = 100 * (p[0] - '0') + 10 * (p[1] - '0') + p[2] - '0'; else retval = 503; } if (retval != 0) { VSLb(hp->vsl, SLT_HttpGarbage, "%.*s", (int)(htc->rxbuf_e - htc->rxbuf_b), htc->rxbuf_b); assert(retval >= 100 && retval <= 999); assert(retval == 503); hp->status = retval; http_SetH(hp, HTTP_HDR_STATUS, "503"); http_SetH(hp, HTTP_HDR_REASON, http_Status2Reason(retval)); } if (hp->hd[HTTP_HDR_REASON].b == NULL || !Tlen(hp->hd[HTTP_HDR_REASON])) http_SetH(hp, HTTP_HDR_REASON, http_Status2Reason(hp->status)); htc->body_status = http1_body_status(hp, htc, 0); return (retval); }
uint16_t HTTP1_DissectRequest(struct http_conn *htc, struct http *hp) { uint16_t retval; const char *p; const char *b, *e; CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); retval = http1_splitline(hp, htc, HTTP1_Req); if (retval != 0) return (retval); hp->protover = http1_proto_ver(hp); if (hp->protover == 0) return (400); if (http_CountHdr(hp, H_Host) > 1) return (400); if (http_CountHdr(hp, H_Content_Length) > 1) return (400); /* RFC2616, section 5.2, point 1 */ if (!strncasecmp(hp->hd[HTTP_HDR_URL].b, "http://", 7)) { b = e = hp->hd[HTTP_HDR_URL].b + 7; while (*e != '/' && *e != '\0') e++; if (*e == '/') { http_Unset(hp, H_Host); http_PrintfHeader(hp, "Host: %.*s", (int)(e - b), b); hp->hd[HTTP_HDR_URL].b = e; } } htc->body_status = http1_body_status(hp, htc); if (htc->body_status == BS_ERROR) return (400); p = http_GetMethod(hp); AN(p); if (htc->body_status == BS_EOF) { assert(hp->protover == 10); /* RFC1945 8.3 p32 and D.1.1 p58 */ if (!strcasecmp(p, "post") || !strcasecmp(p, "put")) return (400); htc->body_status = BS_NONE; } /* HEAD with a body is a hard error */ if (htc->body_status != BS_NONE && !strcasecmp(p, "head")) return (400); return (retval); }