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); }
h2_minimal_response(struct req *req, uint16_t status) { struct h2_req *r2; size_t l; uint8_t buf[6]; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC); assert(status >= 100); assert(status < 1000); l = h2_status(buf, status); assert(l < sizeof(buf)); VSLb(req->vsl, SLT_RespProtocol, "HTTP/2.0"); VSLb(req->vsl, SLT_RespStatus, "%03d", status); VSLb(req->vsl, SLT_RespReason, "%s", http_Status2Reason(status, NULL)); if (status >= 400) req->err_code = status; /* XXX return code checking once H2_Send returns anything but 0 */ H2_Send_Get(req->wrk, r2->h2sess, r2); H2_Send(req->wrk, r2, H2_F_HEADERS, H2FF_HEADERS_END_HEADERS | (status < 200 ? 0 : H2FF_HEADERS_END_STREAM), l, buf); H2_Send_Rel(r2->h2sess, r2); return (0); }
http1_minimal_response(struct req *req, uint16_t status) { ssize_t wl, l; char buf[80]; const char *reason; assert(status >= 100); assert(status < 1000); reason = http_Status2Reason(status, NULL); l = snprintf(buf, sizeof(buf), "HTTP/1.1 %03d %s\r\n\r\n", status, reason); assert (l < sizeof(buf)); VSLb(req->vsl, SLT_RespProtocol, "HTTP/1.1"); VSLb(req->vsl, SLT_RespStatus, "%03d", status); VSLb(req->vsl, SLT_RespReason, "%s", reason); if (status >= 400) req->err_code = status; wl = write(req->sp->fd, buf, l); if (wl > 0) req->acct.resp_hdrbytes += wl; if (wl != l) { if (wl < 0) VTCP_Assert(1); if (!req->doclose) req->doclose = SC_REM_CLOSE; return (-1); } return (0); }
void VRT_synth(VRT_CTX, unsigned code, const char *reason) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); if (code < 100) code = 503; ctx->req->err_code = (uint16_t)code; ctx->req->err_reason = reason ? reason : http_Status2Reason(ctx->req->err_code % 1000, NULL); }
void http_PutResponse(struct http *to, const char *proto, uint16_t status, const char *reason) { CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); if (proto != NULL) http_SetH(to, HTTP_HDR_PROTO, proto); http_SetStatus(to, status); if (reason == NULL) reason = http_Status2Reason(status); http_SetH(to, HTTP_HDR_REASON, reason); }
void VRT_error(VRT_CTX, unsigned code, const char *reason) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); VSLb(ctx->vsl, SLT_Debug, "VCL_error(%u, %s)", code, reason ? reason : "(null)"); if (code < 100 || code > 999) code = 503; ctx->req->err_code = (uint16_t)code; ctx->req->err_reason = reason ? reason : http_Status2Reason(ctx->req->err_code); }
void http_SetStatus(struct http *to, uint16_t status) { char buf[4]; CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); /* * We allow people to use top digits for internal VCL * signalling, but strip them from the ASCII version. */ to->status = status; status %= 1000; assert(status >= 100); bprintf(buf, "%03d", status); http_PutField(to, HTTP_HDR_STATUS, buf); http_SetH(to, HTTP_HDR_REASON, http_Status2Reason(status)); }