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.

Reply via email to