--------------------- PatchSet 8526 Date: 2006/08/19 16:52:47 Author: adri Branch: parserwork Tag: (none) Log: Bring over some work to reduce the amount of re-parsing done in the client-side code: * Create a temporary structure - HttpMsgBuf - which holds a pointer to the current buffer, its size, and some parsing state * Modify some of the code used in the client side code to use this rather than calling headersEnd() and strlen() more than once. There's some CPU time saved by not calling headersEnd() but its cancelled out by the extra code added to support HttpMsgBuf. Hopefully this work will bring more benefits over time. Members: src/HttpMsg.c:1.8->1.8.8.1 src/HttpReply.c:1.16->1.16.8.1 src/HttpRequest.c:1.16->1.16.4.1 src/client_side.c:1.143.2.1->1.143.2.2 src/protos.h:1.122->1.122.2.1 src/structs.h:1.128.2.1->1.128.2.2 src/typedefs.h:1.40->1.40.2.1 Index: squid/src/HttpMsg.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/HttpMsg.c,v retrieving revision 1.8 retrieving revision 1.8.8.1 diff -u -r1.8 -r1.8.8.1 --- squid/src/HttpMsg.c 13 Jun 2006 14:53:53 -0000 1.8 +++ squid/src/HttpMsg.c 19 Aug 2006 16:52:47 -0000 1.8.8.1 @@ -1,6 +1,6 @@ /* - * $Id: HttpMsg.c,v 1.8 2006/06/13 14:53:53 squidadm Exp $ + * $Id: HttpMsg.c,v 1.8.8.1 2006/08/19 16:52:47 adri Exp $ * * DEBUG: section 74 HTTP Message * AUTHOR: Alex Rousskov @@ -35,17 +35,33 @@ #include "squid.h" +void +HttpMsgBufInit(HttpMsgBuf *hmsg, const char *buf, size_t size) +{ + hmsg->buf = buf; + hmsg->size = size; + hmsg->req_start = hmsg->req_end = -1; + hmsg->headers_start = hmsg->headers_end = -1; +} + +void +httpMsgBufDone(HttpMsgBuf *hmsg) +{ + (void) 0; +} + /* find end of headers */ +/* XXX this should be turned into something using HttpMsgBuf.. */ int -httpMsgIsolateHeaders(const char **parse_start, const char **blk_start, const char **blk_end) +httpMsgIsolateHeaders(const char **parse_start, size_t l, size_t end, const char **blk_start, const char **blk_end) { /* * parse_start points to the first line of HTTP message *headers*, * not including the request or status lines */ - size_t l = strlen(*parse_start); - size_t end = headersEnd(*parse_start, l); + // size_t l = strlen(*parse_start); + // size_t end = headersEnd(*parse_start, l); int nnl; if (end) { *blk_start = *parse_start; Index: squid/src/HttpReply.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/HttpReply.c,v retrieving revision 1.16 retrieving revision 1.16.8.1 diff -u -r1.16 -r1.16.8.1 --- squid/src/HttpReply.c 11 Jun 2006 00:50:43 -0000 1.16 +++ squid/src/HttpReply.c 19 Aug 2006 16:52:47 -0000 1.16.8.1 @@ -1,6 +1,6 @@ /* - * $Id: HttpReply.c,v 1.16 2006/06/11 00:50:43 squidadm Exp $ + * $Id: HttpReply.c,v 1.16.8.1 2006/08/19 16:52:47 adri Exp $ * * DEBUG: section 58 HTTP Reply (Response) * AUTHOR: Alex Rousskov @@ -405,7 +405,10 @@ rep->pstate++; } if (rep->pstate == psReadyToParseHeaders) { - if (!httpMsgIsolateHeaders(&parse_start, &blk_start, &blk_end)) { + int l, he; + l = strlen(parse_start); + he = headersEnd(parse_start, l); + if (!httpMsgIsolateHeaders(&parse_start, l, he, &blk_start, &blk_end)) { if (atEnd) blk_start = parse_start, blk_end = blk_start + strlen(blk_start); else Index: squid/src/HttpRequest.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/HttpRequest.c,v retrieving revision 1.16 retrieving revision 1.16.4.1 diff -u -r1.16 -r1.16.4.1 --- squid/src/HttpRequest.c 17 Jul 2006 02:51:31 -0000 1.16 +++ squid/src/HttpRequest.c 19 Aug 2006 16:52:47 -0000 1.16.4.1 @@ -1,6 +1,6 @@ /* - * $Id: HttpRequest.c,v 1.16 2006/07/17 02:51:31 squidadm Exp $ + * $Id: HttpRequest.c,v 1.16.4.1 2006/08/19 16:52:47 adri Exp $ * * DEBUG: section 73 HTTP Request * AUTHOR: Duane Wessels @@ -107,10 +107,14 @@ } int -httpRequestParseHeader(request_t * req, const char *parse_start) +httpRequestParseHeader(request_t * req, HttpMsgBuf *hmsg) { - const char *blk_start, *blk_end; - if (!httpMsgIsolateHeaders(&parse_start, &blk_start, &blk_end)) + const char *blk_start, *blk_end, *s; + assert(hmsg->headers_start > -1); + assert(hmsg->headers_end > -1); + s = hmsg->buf + hmsg->headers_start; + if (!httpMsgIsolateHeaders(&s, hmsg->size - hmsg->headers_start, + hmsg->headers_end - hmsg->headers_start, &blk_start, &blk_end)) return 0; return httpHeaderParse(&req->header, blk_start, blk_end); } Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.143.2.1 retrieving revision 1.143.2.2 diff -u -r1.143.2.1 -r1.143.2.2 --- squid/src/client_side.c 19 Aug 2006 16:47:15 -0000 1.143.2.1 +++ squid/src/client_side.c 19 Aug 2006 16:52:47 -0000 1.143.2.2 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.143.2.1 2006/08/19 16:47:15 adri Exp $ + * $Id: client_side.c,v 1.143.2.2 2006/08/19 16:52:47 adri Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -118,7 +118,7 @@ static void clientProcessMiss(clientHttpRequest *); static void clientBuildReplyHeader(clientHttpRequest * http, HttpReply * rep); static clientHttpRequest *parseHttpRequestAbort(ConnStateData * conn, const char *uri); -static clientHttpRequest *parseHttpRequest(ConnStateData *, method_t *, int *, char **, size_t *); +static clientHttpRequest *parseHttpRequest(ConnStateData *, HttpMsgBuf *, method_t *, int *, char **, size_t *); static void clientRedirectStart(clientHttpRequest * http); static RH clientRedirectDone; static void clientCheckNoCache(clientHttpRequest *); @@ -3488,7 +3488,7 @@ * a clientHttpRequest structure on success */ static clientHttpRequest * -parseHttpRequest(ConnStateData * conn, method_t * method_p, int *status, +parseHttpRequest(ConnStateData * conn, HttpMsgBuf *hmsg, method_t * method_p, int *status, char **prefix_p, size_t * req_line_sz_p) { char *inbuf = NULL; @@ -3511,23 +3511,29 @@ *method_p = METHOD_NONE; *status = -1; - if ((t = memchr(conn->in.buf, '\n', conn->in.offset)) == NULL) { + if ((t = memchr(hmsg->buf, '\n', hmsg->size)) == NULL) { debug(33, 5) ("Incomplete request, waiting for end of request line\n"); *status = 0; return NULL; } - *req_line_sz_p = req_sz = t - conn->in.buf + 1; /* HTTP/0.9 requests */ - while (t > conn->in.buf && xisspace(*t)) + *req_line_sz_p = req_sz = t - hmsg->buf + 1; /* HTTP/0.9 requests */ + hmsg->req_start = 0; /* I think the caller has 'trimmed' space .. */ + hmsg->req_end = t - hmsg->buf; + while (t > hmsg->buf && xisspace(*t)) t--; - while (t > conn->in.buf && !xisspace(*t)) + while (t > hmsg->buf && !xisspace(*t)) t--; - if (t > conn->in.buf && t < (conn->in.buf + conn->in.offset - 8) && strncasecmp(t + 1, "HTTP/", 5) == 0) { - if ((req_sz = headersEnd(conn->in.buf, conn->in.offset)) == 0) { + + if (t > hmsg->buf && t < (hmsg->buf + hmsg->size - 8) && strncasecmp(t + 1, "HTTP/", 5) == 0) { + if ((req_sz = headersEnd(hmsg->buf, hmsg->size)) == 0) { debug(33, 5) ("Incomplete request, waiting for end of headers\n"); *status = 0; return NULL; } - http_version_offset = t - conn->in.buf; + /* XXX should double-check these! */ + hmsg->headers_end = req_sz; + hmsg->headers_start = *req_line_sz_p; + http_version_offset = t - hmsg->buf; if (sscanf(t + 6, "%d.%d", &http_ver.major, &http_ver.minor) != 2) { debug(33, 3) ("parseHttpRequest: Invalid HTTP identifier.\n"); return parseHttpRequestAbort(conn, "error:invalid-http-ident"); @@ -3538,10 +3544,10 @@ httpBuildVersion(&http_ver, 0, 9); /* wild guess */ } - assert(req_sz <= conn->in.offset); + assert(req_sz <= hmsg->size); /* Use memcpy, not strdup! */ inbuf = xmalloc(req_sz + 1); - xmemcpy(inbuf, conn->in.buf, req_sz); + xmemcpy(inbuf, hmsg->buf, req_sz); *(inbuf + req_sz) = '\0'; /* Enforce max_request_size */ @@ -3607,7 +3613,7 @@ prefix_sz = end - inbuf; debug(33, 3) ("parseHttpRequest: prefix_sz = %d, req_line_sz = %d\n", (int) prefix_sz, (int) *req_line_sz_p); - assert(prefix_sz <= conn->in.offset); + assert(prefix_sz <= hmsg->size); /* Ok, all headers are received */ http = cbdataAlloc(clientHttpRequest); @@ -3617,7 +3623,7 @@ http->req_sz = prefix_sz; http->range_iter.boundary = StringNull; *prefix_p = xmalloc(prefix_sz + 1); - xmemcpy(*prefix_p, conn->in.buf, prefix_sz); + xmemcpy(*prefix_p, hmsg->buf, prefix_sz); *(*prefix_p + prefix_sz) = '\0'; dlinkAdd(http, &http->active, &ClientActiveRequests); @@ -3771,6 +3777,8 @@ ErrorState *err = NULL; fde *F = &fd_table[fd]; int len = conn->in.size - conn->in.offset - 1; + HttpMsgBuf hmsg; + debug(33, 4) ("clientReadRequest: FD %d: reading request...\n", fd); if (len == 0) { /* Grow the request memory area to accomodate for a large request */ @@ -3860,8 +3868,11 @@ conn->in.buf[conn->in.offset] = '\0'; /* Terminate the string */ if (nrequests == 0) fd_note(conn->fd, "Reading next request"); + + HttpMsgBufInit(&hmsg, conn->in.buf, conn->in.offset); + /* Process request */ - http = parseHttpRequest(conn, + http = parseHttpRequest(conn, &hmsg, &method, &parser_return_code, &prefix, @@ -3915,7 +3926,7 @@ } /* compile headers */ /* we should skip request line! */ - if ((http->http_ver.major >= 1) && !httpRequestParseHeader(request, prefix + req_line_sz)) { + if ((http->http_ver.major >= 1) && !httpRequestParseHeader(request, &hmsg)) { debug(33, 1) ("Failed to parse request headers: %s\n%s\n", http->uri, prefix); err = errorCon(ERR_INVALID_URL, HTTP_BAD_REQUEST); Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.122 retrieving revision 1.122.2.1 diff -u -r1.122 -r1.122.2.1 --- squid/src/protos.h 18 Aug 2006 23:52:05 -0000 1.122 +++ squid/src/protos.h 19 Aug 2006 16:52:47 -0000 1.122.2.1 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.122 2006/08/18 23:52:05 squidadm Exp $ + * $Id: protos.h,v 1.122.2.1 2006/08/19 16:52:47 adri Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -465,7 +465,7 @@ /* Http Msg (currently in HttpReply.c @?@ ) */ extern int httpMsgIsPersistent(http_version_t http_ver, const HttpHeader * hdr); -extern int httpMsgIsolateHeaders(const char **parse_start, const char **blk_start, const char **blk_end); +extern int httpMsgIsolateHeaders(const char **parse_start, size_t l, size_t end, const char **blk_start, const char **blk_end); /* Http Reply */ extern void httpReplyInitModule(void); @@ -505,7 +505,7 @@ extern void requestDestroy(request_t *); extern request_t *requestLink(request_t *); extern void requestUnlink(request_t *); -extern int httpRequestParseHeader(request_t * req, const char *parse_start); +extern int httpRequestParseHeader(request_t * req, HttpMsgBuf *hmsg); extern void httpRequestSwapOut(const request_t * req, StoreEntry * e); extern void httpRequestPackDebug(request_t * req, Packer * p); extern int httpRequestPrefixLen(const request_t * req); @@ -1413,4 +1413,9 @@ void storeLocateVary(StoreEntry * e, int offset, const char *vary_data, String accept_encoding, STLVCB * callback, void *cbdata); void storeAddVary(const char *url, const char *log_url, const method_t method, const cache_key * key, const char *etag, const char *vary, const char *vary_headers, const char *accept_encoding); +extern void HttpMsgBufInit(HttpMsgBuf *hmsg, const char *buf, size_t size); +extern void httpMsgBufDone(HttpMsgBuf *hmsg); + + + #endif /* SQUID_PROTOS_H */ Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.128.2.1 retrieving revision 1.128.2.2 diff -u -r1.128.2.1 -r1.128.2.2 --- squid/src/structs.h 19 Aug 2006 16:47:15 -0000 1.128.2.1 +++ squid/src/structs.h 19 Aug 2006 16:52:47 -0000 1.128.2.2 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.128.2.1 2006/08/19 16:47:15 adri Exp $ + * $Id: structs.h,v 1.128.2.2 2006/08/19 16:52:47 adri Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -2488,4 +2488,11 @@ Array etags; }; +struct _HttpMsgBuf { + const char *buf; + size_t size; + int headers_start, headers_end; + int req_start, req_end; +}; + #endif /* SQUID_STRUCTS_H */ Index: squid/src/typedefs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v retrieving revision 1.40 retrieving revision 1.40.2.1 diff -u -r1.40 -r1.40.2.1 --- squid/src/typedefs.h 18 Aug 2006 23:52:06 -0000 1.40 +++ squid/src/typedefs.h 19 Aug 2006 16:52:47 -0000 1.40.2.1 @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.40 2006/08/18 23:52:06 squidadm Exp $ + * $Id: typedefs.h,v 1.40.2.1 2006/08/19 16:52:47 adri Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -406,4 +406,6 @@ typedef struct _VaryData VaryData; typedef void STLVCB(VaryData * vary, void *cbdata); +typedef struct _HttpMsgBuf HttpMsgBuf; + #endif /* SQUID_TYPEDEFS_H */