Commit 1910640d authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Encapsulate Expect: and Connection: processing in a transport

agnostic function.
parent 22857119
......@@ -940,6 +940,7 @@ void VRB_Free(struct req *);
/* cache_req_fsm.c [CNT] */
enum req_fsm_nxt CNT_Request(struct worker *, struct req *);
void CNT_AcctLogCharge(struct dstat *, struct req *);
int CNT_GotReq(struct worker *, struct req *);
/* cache_session.c [SES] */
struct sess *SES_New(struct pool *);
......
......@@ -664,13 +664,12 @@ http_DoConnection(struct http *hp)
retval = SC_NULL;
/* Refuse removal of well-known-headers if they would pass. */
/*lint -save -e506 */
/*lint -save -e506 [constant value boolean] */
#define HTTPH(a, x, c) \
if (!((c) & HTTPH_R_PASS) && \
strlen(a) == u && !strncasecmp(a, b, u)) \
return (SC_RX_BAD);
#include "tbl/http_headers.h"
/*lint -restore */
v = http_findhdr(hp, u, b);
......
......@@ -49,6 +49,51 @@
#include "vsha256.h"
#include "vtim.h"
/*--------------------------------------------------------------------
* Handle "Expect:" and "Connection:" on incoming request
*/
int
CNT_GotReq(struct worker *wrk, struct req *req)
{
const char *p;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(req->http, HTTP_MAGIC);
CHECK_OBJ_NOTNULL(req->transport, TRANSPORT_MAGIC);
AN(req->transport->minimal_response);
if (http_GetHdr(req->http, H_Expect, &p)) {
if (strcasecmp(p, "100-continue")) {
req->doclose = SC_RX_JUNK;
(void)req->transport->minimal_response(req, 417);
wrk->stats->client_req_417++;
return (-1);
}
if (req->http->protover >= 11 && req->htc->pipeline_b == NULL)
req->want100cont = 1;
http_Unset(req->http, H_Expect);
}
wrk->stats->client_req++;
wrk->stats->s_req++;
AZ(req->err_code);
req->ws_req = WS_Snapshot(req->ws);
req->doclose = http_DoConnection(req->http);
if (req->doclose == SC_RX_BAD) {
(void)req->transport->minimal_response(req, 400);
return (-1);
}
assert(req->req_body_status != REQ_BODY_INIT);
HTTP_Copy(req->http0, req->http); // For ESI & restart
return (0);
}
/*--------------------------------------------------------------------
* Deliver an object to client
*/
......@@ -766,8 +811,10 @@ cnt_recv(struct worker *wrk, struct req *req)
if (req->want100cont && !req->late100cont) {
req->want100cont = 0;
if (req->transport->minimal_response(req, 100))
return (-1);
if (req->transport->minimal_response(req, 100)) {
req->doclose = SC_REM_CLOSE;
return (REQ_FSM_DONE);
}
}
/* Attempts to cache req.body may fail */
......
......@@ -255,7 +255,7 @@ struct transport HTTP1_transport = {
*/
static inline void
http1_abort(struct req *req, unsigned status)
http1_abort(struct req *req, uint16_t status)
{
AN(req->doclose);
assert(status >= 400);
......@@ -265,7 +265,6 @@ http1_abort(struct req *req, unsigned status)
static int
http1_dissect(struct worker *wrk, struct req *req)
{
const char *p;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
......@@ -320,35 +319,7 @@ http1_dissect(struct worker *wrk, struct req *req)
WRONG("Unknown req_body_status situation");
}
if (http_GetHdr(req->http, H_Expect, &p)) {
if (strcasecmp(p, "100-continue")) {
req->doclose = SC_RX_JUNK;
http1_abort(req, 417);
wrk->stats->client_req_417++;
return (-1);
}
if (req->http->protover >= 11 && req->htc->pipeline_b == NULL)
req->want100cont = 1;
http_Unset(req->http, H_Expect);
}
wrk->stats->client_req++;
wrk->stats->s_req++;
AZ(req->err_code);
req->ws_req = WS_Snapshot(req->ws);
req->doclose = http_DoConnection(req->http);
if (req->doclose == SC_RX_BAD) {
http1_abort(req, 400);
return (-1);
}
assert(req->req_body_status != REQ_BODY_INIT);
HTTP_Copy(req->http0, req->http); // For ESI & restart
return (0);
return (CNT_GotReq(wrk, req));
}
/*----------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment