Previously, when proxy_cache and keepalive were both enabled with an
HTTP/2 upstream, the second request for a cached resource could fail with
"upstream sent frame for unknown stream" error followed by "cache file
contains invalid header".
This happened because ctx->id was set to 1 in the case when no upstream
connection exists (e.g. cache hit), making the stream id check fail when
the cached response contained frames from a different stream.
The fix is to set ctx->id to 0 when there is no upstream connection,
indicating that no real stream exists, and skip the stream id validation
in this case. Also, ctx->id = 1 is now set only for new connections,
not in the shared done label.
Closes: https://github.com/nginx/nginx/issues/1101
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
- if (ctx->stream_id && ctx->stream_id != ctx->id) {
+ if (ctx->id && ctx->stream_id && ctx->stream_id != ctx->id) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream sent frame for unknown stream %ui",
ctx->stream_id);
return NGX_ERROR;
}
+ ctx->id = 0;
+
goto done;
}
cln->handler = ngx_http_proxy_v2_cleanup;
ctx->connection = cln->data;
+ ctx->id = 1;
+
done:
ctx->connection->init_window = NGX_HTTP_V2_DEFAULT_WINDOW;
ctx->send_window = NGX_HTTP_V2_DEFAULT_WINDOW;
ctx->recv_window = NGX_HTTP_V2_MAX_WINDOW;
- ctx->id = 1;
ctx->connection->last_stream_id = 1;
return NGX_OK;