Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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);
}