diff options
Diffstat (limited to 'src/fconn_fastcgi.c')
-rw-r--r-- | src/fconn_fastcgi.c | 72 |
1 files changed, 51 insertions, 21 deletions
diff --git a/src/fconn_fastcgi.c b/src/fconn_fastcgi.c index 1d21603..e0f4132 100644 --- a/src/fconn_fastcgi.c +++ b/src/fconn_fastcgi.c @@ -26,25 +26,37 @@ #define req_cmp(c, val) (((int)(c)->reqs.a[i]->fconn_id) - ((int)val)) -static void handle_begin_request(fconn_fastcgi *c, uint16_t id, size_t len, const char *buf) { - if(id == 0 || len < 8 || *buf != 0 || buf[1] < 1 || buf[1] > 3) { +static void handle_get_values(fconn_fastcgi *c, fcgy_req *req, fastcgi_header h, const char *buf) { + /* TODO */ +} + + +static void handle_begin_request(fconn_fastcgi *c, fcgy_req *req, fastcgi_header h, const char *buf) { + if(h.requestId == 0 || h.contentLength < 8 || *buf != 0 || buf[1] < 1 || buf[1] > 3) { fprintf(stderr, "Invalid BEGIN_REQUEST record\n"); fconn_fastcgi_destroy(c); return; } size_t n; - vec_search_insert(c->reqs, n, req_cmp(c, id)); - if(n < c->reqs.n && c->reqs.a[n]->fconn_id == id) { + vec_search_insert(c->reqs, n, req_cmp(c, h.requestId)); + if(n < c->reqs.n && c->reqs.a[n]->fconn_id == h.requestId) { fprintf(stderr, "BEGIN_REQUEST record for existing request ID\n"); fconn_fastcgi_destroy(c); return; } - *vec_insert_orderp(c->reqs, n) = req_create(c, id); + *vec_insert_orderp(c->reqs, n) = req_create(c, h.requestId); +} + + +static void handle_abort_request(fconn_fastcgi *c, fcgy_req *req, fastcgi_header h, const char *buf) { + req_unset_front(req); + vec_search(c->reqs, req_cmp(c, h.requestId), vec_remove_order(c->reqs, i)); } -static void handle_params(fconn_fastcgi *c, fcgy_req *req, size_t len, const char *buf) { +static void handle_params(fconn_fastcgi *c, fcgy_req *req, fastcgi_header h, const char *buf) { + size_t len = h.contentLength; if(!len) /* End of param list. Should signal this to fcgy_req? */ return; @@ -67,9 +79,8 @@ static void handle_params(fconn_fastcgi *c, fcgy_req *req, size_t len, const cha } -static fcgy_req *get_request(fconn_fastcgi *c, uint16_t id) { - vec_search(c->reqs, req_cmp(c, id), return c->reqs.a[i]); - return NULL; +static void handle_data(fconn_fastcgi *c, fcgy_req *req, fastcgi_header h, const char *buf) { + /* TODO */ } @@ -85,24 +96,43 @@ static void read_cb(fastcgi_reader *r, ssize_t len, fastcgi_header h, const char fprintf(stderr, "Got FastCGI record: len = %4u, version = %u, type = %2u, requestId = %2u, contentLength = %4u\n", (unsigned)len, (unsigned)h.version, (unsigned)h.type, (unsigned)h.requestId, (unsigned)h.contentLength); - /* TODO: Handle management records here */ + static const struct { + uint8_t type; + bool req; /* Must have an existing request object */ + void (*cb)(fconn_fastcgi *, fcgy_req *, fastcgi_header, const char *); + } *handler = NULL, types[] = { + { FCGI_GET_VALUES, false, handle_get_values }, + { FCGI_BEGIN_REQUEST, false, handle_begin_request }, + { FCGI_ABORT_REQUEST, true, handle_abort_request }, + { FCGI_PARAMS, true, handle_params }, + { FCGI_STDIN, true, handle_data }, + { FCGI_DATA, true, handle_data } + }; - if(h.type == FCGI_BEGIN_REQUEST) { - handle_begin_request(c, h.requestId, h.contentLength, buf); - return; - } + size_t i; + for(i=0; i<sizeof(types)/sizeof(*types); i++) + if(types[i].type == h.type) { + handler = types+i; + break; + } - fcgy_req *req = get_request(c, h.requestId); - if(!req) { - fprintf(stderr, "Received record for unknown request id (%u)\n", (unsigned)h.requestId); - fconn_fastcgi_destroy(c); + if(!handler) { + fprintf(stderr, "Unknown record type %u\n", (unsigned)h.type); + /* TODO: Reply with FCGI_UNKNOWN_TYPE */ return; } - if(h.type == FCGI_PARAMS) - handle_params(c, req, h.contentLength, buf); + fcgy_req *req = NULL; + if(handler->req) { + vec_search(c->reqs, req_cmp(c, h.requestId), req = c->reqs.a[i]); + if(!req) { + fprintf(stderr, "Received record for unknown request id (type = %u, id = %u)\n", (unsigned)h.type, (unsigned)h.requestId); + fconn_fastcgi_destroy(c); + return; + } + } - /* TODO: Handle other request records here */ + handler->cb(c, req, h, buf); } |