Neat. And this solved your issue?
Joe > -----Original Message----- > From: Bastiaan Stougie [mailto:[email protected]] > Sent: Monday, December 17, 2012 11:38 AM > To: [email protected] > Subject: [Pound Mailing List] Re: Forwarding of error responses > > I've patched pound myself, here's the diff with respect to Pound 2.6. > The patch does the following: > > If the backend unexpectedly closes the connection during transfer of > the content associated with a request from client to backend, and the > backend sent a response before closing the connection, the following > patch will make pound forward that response from the backend to the > client. The previous behavior was that pound would just send "500 > Internal Server Error" to the client. > > $ diff -u http.c http-patched.c > --- http.c 2011-12-28 14:57:45.000000000 +0100 > +++ http-patched.c 2012-12-17 17:29:00.706549200 +0100 > @@ -487,7 +487,7 @@ > void > do_http(thr_arg *arg) > { > - int cl_11, be_11, res, chunked, n, sock, no_cont, > skip, conn_closed, force_10, sock_proto, is_rpc; > + int cl_11, be_11, res, chunked, n, sock, no_cont, > skip, conn_closed, force_10, sock_proto, is_rpc, be_err_closed; > LISTENER *lstn; > SERVICE *svc; > BACKEND *backend, *cur_backend, *old_backend; > @@ -592,6 +592,7 @@ > BIO_set_buffer_size(cl, MAXBUF); > cl = BIO_push(bb, cl); > > + be_err_closed = 0; > for(cl_11 = be_11 = 0;;) { > res_bytes = L0; > is_rpc = -1; > @@ -1106,26 +1107,22 @@ > if(cl_11 && chunked) { > /* had Transfer-encoding: chunked so read/write all the > chunks (HTTP/1.1 only) */ > if(copy_chunks(cl, be, NULL, cur_backend->be_type, > lstn->max_req)) { > + be_err_closed = 1; > str_be(buf, MAXBUF - 1, cur_backend); > end_req = cur_time(); > addr2str(caddr, MAXBUF - 1, &from_host, 1); > - logmsg(LOG_NOTICE, "(%lx) e500 for %s copy_chunks to > %s/%s (%.3f sec)", > + logmsg(LOG_NOTICE, "(%lx) error for %s copy_chunks to > %s/%s (%.3f sec)", > pthread_self(), caddr, buf, request, (end_req - > start_req) / 1000000.0); > - err_reply(cl, h500, lstn->err500); > - clean_all(); > - return; > } > } else if(cont > L0 && is_rpc != 1) { > /* had Content-length, so do raw reads/writes for the > length */ > if(copy_bin(cl, be, cont, NULL, cur_backend->be_type)) { > + be_err_closed = 1; > str_be(buf, MAXBUF - 1, cur_backend); > end_req = cur_time(); > addr2str(caddr, MAXBUF - 1, &from_host, 1); > - logmsg(LOG_NOTICE, "(%lx) e500 for %s error copy > client > cont to %s/%s: %s (%.3f sec)", > + logmsg(LOG_NOTICE, "(%lx) error for %s copy client > cont > to %s/%s: %s (%.3f sec)", > pthread_self(), caddr, buf, request, > strerror(errno), (end_req - start_req) / 1000000.0); > - err_reply(cl, h500, lstn->err500); > - clean_all(); > - return; > } > } else if(cont > 0L && is_readable(cl, lstn->to)) { > char one; > @@ -1156,11 +1153,12 @@ > if(errno) > logmsg(LOG_NOTICE, "(%lx) error write request > pending: %s", > pthread_self(), strerror(errno)); > - clean_all(); > - pthread_exit(NULL); > + be_err_closed = 1; > + break; > } > } > - BIO_flush(be); > + if (!be_err_closed) > + BIO_flush(be); > > /* > * find the socket BIO in the chain @@ -1174,7 +1172,7 @@ > /* > * copy till EOF > */ > - while((res = BIO_read(cl_unbuf, buf, MAXBUF)) > 0) { > + while(!be_err_closed && (res = BIO_read(cl_unbuf, buf, > MAXBUF)) > 0) { > if((res_bytes += res) > cont) { > logmsg(LOG_NOTICE, "(%lx) error copy request > body: > max. RPC length exceeded", > pthread_self()); @@ -1185,8 +1183,7 @@ > if(errno) > logmsg(LOG_NOTICE, "(%lx) error copy request > body: %s", > pthread_self(), strerror(errno)); > - clean_all(); > - pthread_exit(NULL); > + be_err_closed = 1; > } else { > BIO_flush(be); > } > @@ -1194,15 +1191,13 @@ > } > > /* flush to the back-end */ > - if(cur_backend->be_type == 0 && BIO_flush(be) != 1) { > + if(!be_err_closed && cur_backend->be_type == 0 && > BIO_flush(be) > != 1) { > str_be(buf, MAXBUF - 1, cur_backend); > end_req = cur_time(); > addr2str(caddr, MAXBUF - 1, &from_host, 1); > logmsg(LOG_NOTICE, "(%lx) e500 for %s error flush to > %s/%s: %s (%.3f sec)", > pthread_self(), caddr, buf, request, strerror(errno), > (end_req - start_req) / 1000000.0); > - err_reply(cl, h500, lstn->err500); > - clean_all(); > - return; > + be_err_closed = 1; > } > > /* > @@ -1253,7 +1248,7 @@ > u_name[0]? u_name: "-", req_time, request, > cur_backend->be_type, referer, u_agent); > break; > } > - if(!cl_11 || conn_closed || force_10) > + if(be_err_closed || !cl_11 || conn_closed || force_10) > break; > continue; > } else if(is_rpc == 1) { > @@ -1541,13 +1536,18 @@ > } > /* > * Stop processing if: > + * - backend closed the connection during transfer of the > content > + * (in this case we have still made an attempt to forward > any response > + * from the backend to the client, but now we have to stop > because > + * of the closed connection) > + * or > * - client is not HTTP/1.1 > * or > * - we had a "Connection: closed" header > * or > * - this is an SSL connection and we had a NoHTTPS11 > directive > */ > - if(!cl_11 || conn_closed || force_10) > + if(be_err_closed || !cl_11 || conn_closed || force_10) > break; > } > > > > On 12/11/2012 05:50 PM, Bastiaan Stougie wrote: > > Hi, > > > > We are considering to use pound as reverse proxy. During tests, we > > have encountered the following issue: > > > > - a client does a PUT request, with non-zero content-length > > - pound forwards the PUT request and starts to forward the associated > > content > > - the server that pound forwards to reads and evaluates the request, > > without reading the content yet > > - the server that pound forwards to notices a problem with the > request > > and responds, then closes the connection without ever reading the > > content associated with the PUT request > > - pound notices that it can not forward the content (EPIPE), and > > immediately responds to the client with "500 Internal Server Error" > > > > In other words, on error, the response from the the server that pound > > forwards to never reaches the client, and the client needs more > > information than "500 Internal Server Error" to be able to take > > appropriate action. > > > > The PUT content can be very big (gigabytes), so reading it completely > > and then responding would take the server considerable time and > > resources, and would cost much bandwidth. > > > > Would it be possible to have pound attempt to forward the response > > back to the client after the forward of the content to the server has > > failed? > > > > Thank you, > > > > Bastiaan Stougie > > > > > -- > To unsubscribe send an email with subject unsubscribe to > [email protected]. > Please contact [email protected] for questions. -- To unsubscribe send an email with subject unsubscribe to [email protected]. Please contact [email protected] for questions.
