You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bugs@httpd.apache.org by bu...@apache.org on 2017/01/18 06:45:41 UTC
[Bug 60599] New: mod_http2 + mod_cache + "Cache-Control: max-age=0"
+ "If-Modified-Since:" => RST_STREAM
https://bz.apache.org/bugzilla/show_bug.cgi?id=60599
Bug ID: 60599
Summary: mod_http2 + mod_cache + "Cache-Control: max-age=0" +
"If-Modified-Since:" => RST_STREAM
Product: Apache httpd-2
Version: 2.4-HEAD
Hardware: PC
OS: FreeBSD
Status: NEW
Severity: normal
Priority: P2
Component: mod_http2
Assignee: bugs@httpd.apache.org
Reporter: apache@wheelhouse.org
Target Milestone: ---
In a configuration with mod_cache, an HTTP/2 request with both "Cache-Control:
max-age=0" and an If-Modified-Since: header that should generate a 304 response
instead causes a connection reset.
This can be reproduced with the latest 2.4 SVN, using nghttp as an HTTP/2
client. (The issue is also visible in Firefox and Chrome.)
First, a request to load the URL into cache:
$ nghttp -v https://www.example.org/test.txt
[ 0.073] Connected
The negotiated protocol: h2
[ 0.226] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
(niv=2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0.226] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
(dep_stream_id=0, weight=201, exclusive=0)
[ 0.226] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
(dep_stream_id=0, weight=101, exclusive=0)
[ 0.226] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
(dep_stream_id=0, weight=1, exclusive=0)
[ 0.226] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
(dep_stream_id=7, weight=1, exclusive=0)
[ 0.226] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
(dep_stream_id=3, weight=1, exclusive=0)
[ 0.227] send HEADERS frame <length=48, flags=0x25, stream_id=13>
; END_STREAM | END_HEADERS | PRIORITY
(padlen=0, dep_stream_id=11, weight=16, exclusive=0)
; Open new stream
:method: GET
:path: /test.txt
:scheme: https
:authority: www.example.org
accept: */*
accept-encoding: gzip, deflate
user-agent: nghttp2/1.14.1
[ 0.227] recv SETTINGS frame <length=6, flags=0x00, stream_id=0>
(niv=1)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[ 0.227] recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
(window_size_increment=2147418112)
[ 0.227] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
; ACK
(niv=0)
[ 0.299] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
; ACK
(niv=0)
[ 0.300] recv (stream_id=13) :status: 200
[ 0.300] recv (stream_id=13) date: Wed, 18 Jan 2017 05:31:40 GMT
[ 0.300] recv (stream_id=13) server: Apache/2.4.25 (Unix) OpenSSL/1.0.2j
[ 0.300] recv (stream_id=13) last-modified: Wed, 18 Jan 2017 05:29:29 GMT
[ 0.300] recv (stream_id=13) content-length: 16
[ 0.300] recv (stream_id=13) etag: "10-54657b3646338"
[ 0.300] recv (stream_id=13) accept-ranges: bytes
[ 0.300] recv HEADERS frame <length=107, flags=0x04, stream_id=13>
; END_HEADERS
(padlen=0)
; First response header
This is a test.
[ 0.300] recv DATA frame <length=16, flags=0x01, stream_id=13>
; END_STREAM
[ 0.300] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
(last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])
The second request can add the Cache-Control: and If-Modified-Since: headers to
demonstrate the problem:
$ nghttp -v -H 'Cache-Control: max-age=0' -H 'If-Modified-Since: Wed, 18 Jan
2017 05:29:29 GMT' https://www.example.org/test.txt
[ 0.073] Connected
The negotiated protocol: h2
[ 0.227] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
(niv=2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0.227] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
(dep_stream_id=0, weight=201, exclusive=0)
[ 0.227] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
(dep_stream_id=0, weight=101, exclusive=0)
[ 0.227] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
(dep_stream_id=0, weight=1, exclusive=0)
[ 0.227] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
(dep_stream_id=7, weight=1, exclusive=0)
[ 0.227] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
(dep_stream_id=3, weight=1, exclusive=0)
[ 0.227] send HEADERS frame <length=82, flags=0x25, stream_id=13>
; END_STREAM | END_HEADERS | PRIORITY
(padlen=0, dep_stream_id=11, weight=16, exclusive=0)
; Open new stream
:method: GET
:path: /test.txt
:scheme: https
:authority: www.example.org
accept: */*
accept-encoding: gzip, deflate
user-agent: nghttp2/1.14.1
cache-control: max-age=0
if-modified-since: Wed, 18 Jan 2017 05:29:29 GMT
[ 0.227] recv SETTINGS frame <length=6, flags=0x00, stream_id=0>
(niv=1)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[ 0.227] recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
(window_size_increment=2147418112)
[ 0.227] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
; ACK
(niv=0)
[ 0.299] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
; ACK
(niv=0)
[ 0.300] recv RST_STREAM frame <length=4, flags=0x00, stream_id=13>
(error_code=PROTOCOL_ERROR(0x01))
[ 0.300] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
(last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])
Some requests were not processed. total=1, processed=0
The RST_STREAM frame is received instead of the HEADERS frame.
The last revision where this worked properly appears to be r1763018. After
that and before r1765327, the connection hangs after receiving the SETTINGS
frame. At and after r1765327, the RST_STREAM occurs.
A simple config used to reproduce the issue:
LoadModule mpm_event_module libexec/mod_mpm_event.so
LoadModule ssl_module libexec/mod_ssl.so
LoadModule unixd_module libexec/mod_unixd.so
LoadModule authn_core_module libexec/mod_authn_core.so
LoadModule authz_core_module libexec/mod_authz_core.so
LoadModule cache_module libexec/mod_cache.so
LoadModule cache_disk_module libexec/mod_cache_disk.so
LoadModule http2_module libexec/mod_http2.so
LoadModule socache_shmcb_module libexec/mod_socache_shmcb.so
DocumentRoot /data/apache/public/
ErrorLog /data/apache/logs/error_log
Group nobody
Listen *:443
ServerName www.example.org
User nobody
Protocols h2
SSLEngine on
SSLCertificateFile /data/apache/example.pem
SSLCertificateKeyFile /data/apache/example.pem
SSLSessionCache shmcb:/ssl-session-cache
CacheEnable disk /
CacheRoot /data/apache/cache
If there is anything further I can do or provide to help troubleshoot this, I
am happy to do so.
Thanks!
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org
[Bug 60599] mod_http2 + mod_cache + "Cache-Control: max-age=0" +
"If-Modified-Since:" => RST_STREAM
Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60599
Stefan Eissing <st...@eissing.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Resolution|--- |FIXED
Status|NEW |RESOLVED
--- Comment #3 from Stefan Eissing <st...@eissing.org> ---
Thanks for the patch and the detailed setup description. With that it was easy
to reproduce the bug. Your patch was in the correct location, I just modified
it a tiny bit.
The fix is in Apache trunk and the 2.4.x branch and you can get it also from
https://github.com/icing/mod_h2/releases/tag/1.8.10
Hope this works for you as well!
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org
[Bug 60599] mod_http2 + mod_cache + "Cache-Control: max-age=0" +
"If-Modified-Since:" => RST_STREAM
Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60599
--- Comment #1 from Jeff Wheelhouse <ap...@wheelhouse.org> ---
Created attachment 34643
--> https://bz.apache.org/bugzilla/attachment.cgi?id=34643&action=edit
Proposed patch
This patch appears to address the issue, but I'm not at all convinced that the
logic it uses is applicable in the general case.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org
[Bug 60599] mod_http2 + mod_cache + "Cache-Control: max-age=0" +
"If-Modified-Since:" => RST_STREAM
Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=60599
--- Comment #2 from Jeff Wheelhouse <ap...@wheelhouse.org> ---
Upon investigation, I found that when mod_cache is returning a revalidated
response with a 304 status code, as is the case here, all it sends along the
filter stack is a single EOS bucket, with the relevant headers already set in
r->headers_out.
mod_http2 appears to check for a body bucket before creating a h2_headers
bucket. Since there's not one in this case, the mod_http2 code treats this
case as if there is no response at all.
The provided patch assumes that if there is no body and the status code is 304,
then it is OK to go ahead with no body and just prepend the h2_headers bucket
to the brigade.
This seems to work, but I suspect there may be various other cases where it's
OK that there's no body that are not handled by this patch. A more generic
approach to determining that would possibly be more suitable.
r->header_only sounds like it would be super helpful here but, alas, that seems
not to be the case.
Thanks!
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org