Commit 05bd60b1 authored by Stefan Eissing's avatar Stefan Eissing
Browse files

Merge of r1749505, r1749676 from trunk:

mod_proxy_http2: fixed retry behaviour when proxy engine needs to retry its base request on a new connection



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1749684 13f79535-47bb-0310-9956-ffa450edef68
parent fe52393a
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -139,6 +139,8 @@ h2_ngn_shed *h2_ngn_shed_get_shed(h2_req_engine *ngn)

void h2_ngn_shed_abort(h2_ngn_shed *shed)
{
    ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, shed->c,
                  "h2_ngn_shed(%ld): abort", shed->c->id);
    shed->aborted = 1;
}

@@ -249,7 +251,7 @@ apr_status_t h2_ngn_shed_pull_task(h2_ngn_shed *shed,
                  "h2_ngn_shed(%ld): pull task for engine %s, shutdown=%d", 
                  shed->c->id, ngn->id, want_shutdown);
    if (shed->aborted) {
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, shed->c,
        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, shed->c,
                      "h2_ngn_shed(%ld): abort while pulling requests %s", 
                      shed->c->id, ngn->id);
        ngn->shutdown = 1;
@@ -280,6 +282,12 @@ apr_status_t h2_ngn_shed_pull_task(h2_ngn_shed *shed,
        if (entry->task->c && ngn->c) {
            entry->task->c->current_thread = ngn->c->current_thread;
        }
        if (entry->task->engine == ngn) {
            /* If an engine pushes its own base task, and then pulls
             * it back to itself again, it needs to be thawed.
             */
            h2_task_thaw(entry->task);
        }
        return APR_SUCCESS;
    }
    
+16 −12
Original line number Diff line number Diff line
@@ -40,7 +40,9 @@ typedef struct h2_proxy_stream {

    h2_stream_state_t state;
    unsigned int suspended : 1;
    unsigned int data_sent : 1;
    unsigned int data_received : 1;
    uint32_t error_code;

    apr_bucket_brigade *input;
    apr_bucket_brigade *output;
@@ -158,14 +160,6 @@ static int on_frame_recv(nghttp2_session *ngh2, const nghttp2_frame *frame,
             * that it has started processing. */
            session->last_stream_id = frame->goaway.last_stream_id;
            dispatch_event(session, H2_PROXYS_EV_REMOTE_GOAWAY, 0, NULL);
            if (APLOGcinfo(session->c)) {
                char buffer[256];
                
                h2_util_frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0]));
                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03342)
                              "h2_proxy_session(%s): recv FRAME[%s]",
                              session->id, buffer);
            }
            break;
        default:
            break;
@@ -384,10 +378,15 @@ static int on_stream_close(nghttp2_session *ngh2, int32_t stream_id,
                           uint32_t error_code, void *user_data) 
{
    h2_proxy_session *session = user_data;
    h2_proxy_stream *stream;
    if (!session->aborted) {
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03360)
                      "h2_proxy_session(%s): stream=%d, closed, err=%d", 
                      session->id, stream_id, error_code);
        stream = h2_ihash_get(session->streams, stream_id);
        if (stream) {
            stream->error_code = error_code;
        }
        dispatch_event(session, H2_PROXYS_EV_STREAM_DONE, stream_id, NULL);
    }
    return 0;
@@ -480,6 +479,7 @@ static ssize_t stream_data_read(nghttp2_session *ngh2, int32_t stream_id,
        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, status, stream->r, 
                      "h2_proxy_stream(%d): request body read %ld bytes, flags=%d", 
                      stream->id, (long)readlen, (int)*data_flags);
        stream->data_sent = 1;
        return readlen;
    }
    else if (APR_STATUS_IS_EAGAIN(status)) {
@@ -1047,11 +1047,15 @@ static void ev_stream_done(h2_proxy_session *session, int stream_id,
    
    stream = nghttp2_session_get_stream_user_data(session->ngh2, stream_id);
    if (stream) {
        int touched = (stream->data_sent || 
                       stream_id <= session->last_stream_id);
        int complete = (stream->error_code == 0);
        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO(03364)
                      "h2_proxy_sesssion(%s): stream(%d) closed", 
                      session->id, stream_id);
                      "h2_proxy_sesssion(%s): stream(%d) closed "
                      "(complete=%d, touched=%d)", 
                      session->id, stream_id, complete, touched);
        
        if (!stream->data_received) {
        if (complete && !stream->data_received) {
            apr_bucket *b;
            /* if the response had no body, this is the time to flush
             * an empty brigade which will also "write" the resonse
@@ -1069,7 +1073,7 @@ static void ev_stream_done(h2_proxy_session *session, int stream_id,
        h2_ihash_remove(session->streams, stream_id);
        h2_iq_remove(session->suspended, stream_id);
        if (session->done) {
            session->done(session, stream->r, 1, 1);
            session->done(session, stream->r, complete, touched);
        }
    }
    
+4 −3
Original line number Diff line number Diff line
@@ -324,8 +324,9 @@ static apr_status_t next_request(h2_proxy_ctx *ctx, int before_leave)
                                 APR_BLOCK_READ: APR_NONBLOCK_READ, 
                                 ctx->capacity, &ctx->next);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, ctx->owner, 
                      "h2_proxy_engine(%s): pulled request %s", 
                      "h2_proxy_engine(%s): pulled request (%s) %s", 
                      ctx->engine_id, 
                      before_leave? "before leave" : "regular", 
                      (ctx->next? ctx->next->the_request : "NULL"));
        return APR_STATUS_IS_EAGAIN(status)? APR_SUCCESS : status;
    }
@@ -384,8 +385,8 @@ static apr_status_t proxy_engine_run(h2_proxy_ctx *ctx) {
        else {
            /* end of processing, maybe error */
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, 
                          APLOGNO(03375) "eng(%s): end of session run", 
                          ctx->engine_id);
                          APLOGNO(03375) "eng(%s): end of session %s", 
                          ctx->engine_id, ctx->session->id);
            /*
             * Any open stream of that session needs to
             * a) be reopened on the new session iff safe to do so