--------------------- PatchSet 2205 Date: 2001/05/04 14:39:35 Author: rbcollins Branch: newhttp Tag: (none) Log: full body read from the server - EOF not detected yet Members: src/HttpRequest.c:1.1.1.3.8.2.4.2.2.2->1.1.1.3.8.2.4.2.2.3 src/client_side.c:1.1.1.3.4.1.4.15.2.34.2.5->1.1.1.3.4.1.4.15.2.34.2.6 src/http.c:1.1.1.3.4.1.4.12.2.16.2.5->1.1.1.3.4.1.4.12.2.16.2.6 src/structs.h:1.1.1.3.4.1.4.12.2.26.2.5->1.1.1.3.4.1.4.12.2.26.2.6 src/typedefs.h:1.1.1.3.8.7.4.24.2.3->1.1.1.3.8.7.4.24.2.4 Index: squid/src/HttpRequest.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/HttpRequest.c,v retrieving revision 1.1.1.3.8.2.4.2.2.2 retrieving revision 1.1.1.3.8.2.4.2.2.3 diff -u -r1.1.1.3.8.2.4.2.2.2 -r1.1.1.3.8.2.4.2.2.3 --- squid/src/HttpRequest.c 4 May 2001 13:43:39 -0000 1.1.1.3.8.2.4.2.2.2 +++ squid/src/HttpRequest.c 4 May 2001 14:39:35 -0000 1.1.1.3.8.2.4.2.2.3 @@ -1,6 +1,6 @@ /* - * $Id: HttpRequest.c,v 1.1.1.3.8.2.4.2.2.2 2001/05/04 13:43:39 rbcollins Exp $ + * $Id: HttpRequest.c,v 1.1.1.3.8.2.4.2.2.3 2001/05/04 14:39:35 rbcollins Exp $ * * DEBUG: section 73 HTTP Request * AUTHOR: Duane Wessels @@ -132,7 +132,7 @@ assert(req && p); /* pack request-line */ packerPrintf(p, "%s %s HTTP/1.0\r\n", - RequestMethodStr[req->method], strBuf(req->urlpath) ? strBuf(req->urlpath) : "/" ); + RequestMethodStr[req->method], strBuf(req->urlpath)[0] ? strBuf(req->urlpath) : "/" ); /* headers */ httpHeaderPackInto(&req->header, p); /* trailer */ Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.1.1.3.4.1.4.15.2.34.2.5 retrieving revision 1.1.1.3.4.1.4.15.2.34.2.6 diff -u -r1.1.1.3.4.1.4.15.2.34.2.5 -r1.1.1.3.4.1.4.15.2.34.2.6 --- squid/src/client_side.c 4 May 2001 13:43:39 -0000 1.1.1.3.4.1.4.15.2.34.2.5 +++ squid/src/client_side.c 4 May 2001 14:39:35 -0000 1.1.1.3.4.1.4.15.2.34.2.6 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.1.1.3.4.1.4.15.2.34.2.5 2001/05/04 13:43:39 rbcollins Exp $ + * $Id: client_side.c,v 1.1.1.3.4.1.4.15.2.34.2.6 2001/05/04 14:39:35 rbcollins Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -3349,6 +3349,7 @@ /* This is a socket error on the client socket. * just close the socket, httpRequestFree will abort if needed */ + debug(33,1)("newclientWriteComplete: error writing\n"); comm_close(fd); return; } @@ -3373,6 +3374,7 @@ } return; } else if (clientReplyBodyTooLarge((int) http->out.offset)) { + debug(33,1)("newclientWriteComplete: size overrun\n"); comm_close(fd); return; } @@ -3380,7 +3382,7 @@ /* call the "I want more data function". Probably the head of the reply function * data filter, with no buffer. */ - // http-> + http->serverread(http->serverreaddata); } DATAFILTER_FILTER(newClientW) { @@ -3417,8 +3419,10 @@ /* there is data to write. Concept: buffer 4K/client sock buf/ whatever here * and only call TCP/IP layer when EOF or a larger amount is present ??? */ - if (flags & FILTER_EOF) + if (flags & FILTER_EOF) { + debug(33,1) ("newClientW called with EOF\n"); http->flags.done_copying=1; + } if (!http->flags.reply_write_in_progress) { http->flags.reply_write_in_progress=1; @@ -3462,8 +3466,10 @@ mb = httpReplyPack(rep); - if (flags & FILTER_EOF) + if (flags & FILTER_EOF) { + debug(33,1) ("newClientWH called with EOF\n"); http->flags.done_copying=1; + } if (!http->flags.reply_write_in_progress) { http->flags.reply_write_in_progress=1; Index: squid/src/http.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/http.c,v retrieving revision 1.1.1.3.4.1.4.12.2.16.2.5 retrieving revision 1.1.1.3.4.1.4.12.2.16.2.6 diff -u -r1.1.1.3.4.1.4.12.2.16.2.5 -r1.1.1.3.4.1.4.12.2.16.2.6 --- squid/src/http.c 4 May 2001 13:43:39 -0000 1.1.1.3.4.1.4.12.2.16.2.5 +++ squid/src/http.c 4 May 2001 14:39:35 -0000 1.1.1.3.4.1.4.12.2.16.2.6 @@ -1,6 +1,6 @@ /* - * $Id: http.c,v 1.1.1.3.4.1.4.12.2.16.2.5 2001/05/04 13:43:39 rbcollins Exp $ + * $Id: http.c,v 1.1.1.3.4.1.4.12.2.16.2.6 2001/05/04 14:39:35 rbcollins Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -1368,8 +1368,6 @@ { HttpStateData *http=data; size_t headerlen; - /* we can't have a reply yet! - take me out when the first packet gets through */ - assert(!http->rep); assert(http->readbuf); assert(http->readbuf->buffer); assert(offset==http->readbuf->offset); @@ -1381,9 +1379,24 @@ buf = the buffer data or possibly, move size into buf... */ - if (http->rep) + if (http->rep) { /* possibly just a case of call the filter chain... */ - fatal("reply present - don't know how to handle this\n"); + FILTER_list *temp_filter; + unsigned int rvflags, eofflag; + iobuf *readbuf; + /* if we've already got a request, we are using clean buffers now */ + assert(offset==0); + temp_filter=http->hcrequest->repfilters.head->data; + http->read_offset+=howmuch; + /* Allow a new read to be scheduled */ + readbuf=http->readbuf; + http->readbuf=NULL; + rvflags=temp_filter->filter(readbuf->buffer,howmuch,http->read_offset-howmuch,&http->hcrequest->repfilters, temp_filter,0,temp_filter->data); + cbdataUnlock(readbuf); + /* TODO: one of the filters needs to be a pipeline request handler that gets the next request handled correctly - setups this func up again */ + debug (33,3)("Process request got flags %0x from rep_filter\n", rvflags); + return; + } headerlen = headersEnd(buf+offset, size); if (headerlen) { @@ -1394,24 +1407,28 @@ /* TODO 2: add the server-side filters (ie TE) */ FILTER_list *temp_filter; unsigned int rvflags, eofflag; + iobuf *readbuf; temp_filter=http->hcrequest->repfilters.head->data; http->readbuf->offset+=howmuch; + http->read_offset=0; /* FIXME: this is broken if the server writes the headers in a different *packet to the first body data: we need to check the status line */ - eofflag = http->readbuf->offset-headerlen ? FILTER_EOF : 0; + eofflag = !(http->readbuf->offset - headerlen) ? FILTER_EOF : 0; + /* Allow a new read to be scheduled */ + readbuf=http->readbuf; + http->readbuf=NULL; rvflags = temp_filter->filter_hdr(http->rep, http->hcrequest ,&http->hcrequest->repfilters,temp_filter, eofflag, temp_filter->data); debug (33,3)("Process request got flags %0x from rep_header\n", rvflags); - if (http->readbuf->offset-headerlen + if ((readbuf->offset-headerlen) && !(rvflags & (FILTER_ABORT | FILTER_EOF))) { temp_filter=http->hcrequest->repfilters.head->data; /* offset total length in buffer */ - rvflags=temp_filter->filter(http->readbuf->buffer+http->readbuf->offset+headerlen-howmuch,http->readbuf->offset-headerlen,0,&http->hcrequest->repfilters, + rvflags=temp_filter->filter(readbuf->buffer+readbuf->offset+headerlen-howmuch,readbuf->offset-headerlen,0,&http->hcrequest->repfilters, temp_filter,0,temp_filter->data); debug (33,3)("Process request got flags %0x from rep_filter\n", rvflags); } /* all data written */ - cbdataUnlock(http->readbuf); /* FIXME: make iobuf unlock the buffer */ - http->readbuf=NULL; + cbdataUnlock(readbuf); /* FIXME: make iobuf unlock the buffer */ } @@ -1452,23 +1469,18 @@ static CWCB httpCommWriteComplete; static CRCB httpCommReadComplete; +static FILTERREAD httpServerRead; -/* we are the last in the filter chain. Always. */ -/* Unknowns: how do we detect early server writes: for example if the server rejects our - * header (ie content_length too long) - */ static void -httpCommWriteComplete(int fd, char *bufnotused, size_t size, int errflag, void *data) +httpServerRead(void * data) { HttpStateData *http=data; iobuf *readbuf; - if (http->hcrequest->request->content_length && ~(http->filterflags & FILTER_EOF )) { - /* there is a body.. and we haven't finished */ -// hcrequest->read(http->hcrequest); - } - /* there is no more body */ /* allocate a buffer. This is annoying: could comm_read allocate it for us? * (when we pass a NULL buf) */ + if (http->readbuf) + /* theres a write to the client in progress, or an attempt to queue multiple reads*/ + return; CBDATA_INIT_TYPE(iobuf); CBDATA_INIT_TYPE(buf4k); readbuf = cbdataAlloc(iobuf); @@ -1478,13 +1490,27 @@ readbuf->buffer = cbdataAlloc(buf4k); assert(readbuf->buffer); cbdataLock(readbuf->buffer); - /* this has to be empty ! */ - assert(!http->readbuf); http->readbuf=readbuf; cbdataLock(http->readbuf); comm_read(http->fd, readbuf->buffer, readbuf->offset, readbuf->size, httpCommReadComplete, http); } +/* we are the last in the filter chain. Always. */ +/* Unknowns: how do we detect early server writes: for example if the server rejects our + * header (ie content_length too long) + */ +static void +httpCommWriteComplete(int fd, char *bufnotused, size_t size, int errflag, void *data) +{ + HttpStateData *http=data; + if (http->hcrequest->request->content_length && ~(http->filterflags & FILTER_EOF )) { + /* there is a body.. and we haven't finished */ +// hcrequest->read(http->hcrequest); + } + /* there is no more body */ + httpServerRead(data); +} + /* helper function for http_server_req. * We modify the original request. Why? speed. * This raises a general issue: @@ -1791,6 +1817,9 @@ http->filter_list=filter_list; http->filters=filters->node.next->data; http->filterflags=flags; + http->hcrequest->serverread=httpServerRead; + http->hcrequest->serverreaddata=http; + cbdataLock(http->hcrequest->serverreaddata); dlinkDelete(&filters->node, filter_list); xfree(filters); } Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.1.1.3.4.1.4.12.2.26.2.5 retrieving revision 1.1.1.3.4.1.4.12.2.26.2.6 diff -u -r1.1.1.3.4.1.4.12.2.26.2.5 -r1.1.1.3.4.1.4.12.2.26.2.6 --- squid/src/structs.h 4 May 2001 13:43:39 -0000 1.1.1.3.4.1.4.12.2.26.2.5 +++ squid/src/structs.h 4 May 2001 14:39:36 -0000 1.1.1.3.4.1.4.12.2.26.2.6 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.1.1.3.4.1.4.12.2.26.2.5 2001/05/04 13:43:39 rbcollins Exp $ + * $Id: structs.h,v 1.1.1.3.4.1.4.12.2.26.2.6 2001/05/04 14:39:36 rbcollins Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1038,6 +1038,11 @@ dlink_list reqfilters; /* reply data filtering list */ dlink_list repfilters; + FILTERREAD *clientread; + void * clientreaddata; + FILTERREAD *serverread; + void * serverreaddata; + /* Membuf for aggregating data to be written to the client */ MemBuf mb; }; Index: squid/src/typedefs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v retrieving revision 1.1.1.3.8.7.4.24.2.3 retrieving revision 1.1.1.3.8.7.4.24.2.4 diff -u -r1.1.1.3.8.7.4.24.2.3 -r1.1.1.3.8.7.4.24.2.4 --- squid/src/typedefs.h 1 May 2001 19:40:53 -0000 1.1.1.3.8.7.4.24.2.3 +++ squid/src/typedefs.h 4 May 2001 14:39:36 -0000 1.1.1.3.8.7.4.24.2.4 @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.1.1.3.8.7.4.24.2.3 2001/05/01 19:40:53 adri Exp $ + * $Id: typedefs.h,v 1.1.1.3.8.7.4.24.2.4 2001/05/04 14:39:36 rbcollins Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -388,6 +388,10 @@ typedef void ADDFILTERINSTANCE(FILTER_instance *); /* free any instance data, and clear the fields in an instance entry */ typedef void REMFILTERINSTANCE(FILTER_instance *); +/* read more data from either the client or the server - any given function _only does one + */ +typedef void FILTERREAD(void *); + #if 0 /* config, namestr, param_str */ typedef void FILTERPARSE(void *,const char *, char *);