Commit Graph

46 Commits

Author SHA1 Message Date
Valentin Bartenev
a57959b6cd SPDY: Stream-ID restrictions according to specification. 2014-04-21 18:59:53 +04:00
Valentin Bartenev
c69cabed1d SPDY: fixed typo in log message. 2014-04-16 11:40:42 +04:00
Valentin Bartenev
7da40e6a99 SPDY: moved a variable initialization near to its check.
This should prevent attempts of using pointer before it was checked, since
all modern compilers are able to spot access to uninitialized variable.

No functional changes.
2014-04-09 18:15:32 +04:00
Valentin Bartenev
5d3f84e4e1 SPDY: fixed arguments supplied for an error message. 2014-04-08 20:12:30 +04:00
Valentin Bartenev
a547f4ac15 SPDY: consistently handle control frames with unknown type.
The SPDY draft 2 specification requires that if an endpoint receives a
control frame for a type it does not recognize, it must ignore the frame.
But the 3 and 3.1 drafts don't seem to declare any behavior for such case.
Then sticking with the previous draft in this matter looks to be right.

But previously, only 8 least significant bits of the type field were
parsed while the rest of 16 bits of the field were checked against zero.
Though there are no known frame types bigger than 255, this resulted in
inconsistency in handling of such frames: they were not recognized as
valid frames at all, and the connection was closed.
2014-04-07 19:27:56 +04:00
Valentin Bartenev
108e4d94e4 SPDY: refactored ngx_http_spdy_state_read_data().
There's no more need in a separate indicator of frame completeness
after d74889fbf06d.
2014-04-07 19:27:56 +04:00
Valentin Bartenev
b2cd520673 SPDY: better detect premature closing of stream.
Following a24f88eff684, now the case when the FIN flag is set in SYN_STREAM
is also covered.
2014-04-07 19:27:56 +04:00
Valentin Bartenev
ac5a3cbeee SPDY: detect premature closing of stream.
The SPDY/3.1 specification requires that the server must respond with
a 400 "Bad request" error if the sum of the data frame payload lengths
does not equal the size of the Content-Length header.

This also fixes "zero size buf in output" alert, that might be triggered
if client sends a greater than zero Content-Length header and closes
stream using the FIN flag with an empty request body.
2014-03-28 20:22:57 +04:00
Valentin Bartenev
afb92a8127 SPDY: fixed the DATA frame length handling in case of some errors.
There are a few cases in ngx_http_spdy_state_read_data() related to error
handling when ngx_http_spdy_state_skip() might be called with an inconsistent
state between *pos and sc->length, that leads to violation of frame layout
parsing and resuted in corruption of spdy connection.

Based on a patch by Xiaochen Wang.
2014-03-28 20:05:07 +04:00
Valentin Bartenev
de3c7a825e SPDY: better detect if headers block has wrong entries count.
Previously, only one case was checked: if there's more data to parse
in a r->header_in buffer, but the buffer can be filled to the end by
the last parsed entry, so we also need to check that there's no more
data to inflate.
2014-03-26 18:01:11 +04:00
Valentin Bartenev
042122a066 SPDY: detect premature end of frame while start parsing headers. 2014-03-26 17:43:39 +04:00
Maxim Dounin
ec1211d2f6 SPDY: improved ngx_http_spdy_state_save() again. 2014-03-19 19:30:09 +04:00
Maxim Dounin
062e7a0042 SPDY: improved ngx_http_spdy_state_save() check. 2014-03-19 12:57:39 +04:00
Maxim Dounin
c6c702c329 SPDY: always check size of data to be saved into state buffer. 2014-03-18 17:00:19 +04:00
Roman Arutyunyan
0b5f329784 Added server-side support for PROXY protocol v1 (ticket #355).
Client address specified in the PROXY protocol header is now
saved in the $proxy_protocol_addr variable and can be used in
the realip module.

This is currently not implemented for mail.
2014-03-17 17:41:24 +04:00
Valentin Bartenev
0c05e5b55f SPDY: fixed potential integer overflow while parsing headers.
Previously r->header_size was used to store length for a part of
value that represents an individual already parsed HTTP header,
while r->header_end pointed to the end of the whole value.

Instead of storing length of a following name or value as pointer
to a potential end address (r->header_name_end and r->header_end)
that might be overflowed, now r->lowercase_index counter is used
to store remaining length of a following unparsed field.

It also fixes incorrect $body_bytes_sent value if a request is
closed while parsing of the request header.  Since r->header_size
is intended for counting header size, thus abusing it for header
parsing purpose was certainly a bad idea.
2014-03-03 19:24:55 +04:00
Valentin Bartenev
3925c1b110 SPDY: constant number of preallocated structures for headers. 2014-03-03 19:24:54 +04:00
Xiaochen Wang
cd358e5a95 SPDY: fixed parsing of http version.
There is an error while parsing multi-digit minor version numbers (e.g.
"HTTP/1.10").
2014-02-11 20:54:16 +08:00
Shigeki Ohtsu
38a9a8968d SPDY: fixed parsing of the priority field.
The size of the priority field is increased by one bit in spdy/3,
and now it's a 3-bit field followed by 5 bits of unused space.
But a shift of these bits hasn't been adjusted in 39d7eef2e332
accordingly.
2014-02-04 14:06:23 +09:00
Valentin Bartenev
449e8eeb53 SPDY: protocol implementation switched to spdy/3.1. 2014-01-31 19:17:26 +04:00
Valentin Bartenev
abcbe54219 SPDY: use ngx_queue_t to queue streams for post processing.
It simplifies the code and allows easy reuse the same queue pointer to store
streams in various queues with different requirements.  Future implementation
of SPDY/3.1 will take advantage of this quality.
2014-01-20 20:56:49 +04:00
Valentin Bartenev
3ddf9ccfce SPDY: store the length of frame instead of its whole size.
The "length" value better corresponds with the specification and reduces
confusion about whether frame's header is included in "size" or not.

Also this change simplifies some parts of code, since in more cases the
length of frame is more useful than its actual size, especially considering
that the size of frame header is constant.
2014-01-22 04:58:19 +04:00
Valentin Bartenev
e62156d829 SPDY: use frame->next pointer to chain free frames.
There is no need in separate "free" pointer and like it is for ngx_chain_t
the "next" pointer can be used.  But after this change successfully handled
frame should not be accessed, so the frame handling cycle was improved to
store pointer to the next frame before processing.

Also worth noting that initializing "free" pointer to NULL in the original
code was surplus.
2014-01-22 04:58:19 +04:00
Valentin Bartenev
650984cd20 SPDY: proper handling of all RST_STREAM statuses.
Previously, only stream CANCEL and INTERNAL_ERROR were handled right.
2014-01-22 04:58:19 +04:00
Valentin Bartenev
d055f74178 SPDY: removed state to check first SETTINGS frame.
That code was based on misunderstanding of spdy specification about
configuration applicability in the SETTINGS frames.  The original
interpretation was that configuration is assigned for the whole
SPDY connection, while it is only for the endpoint.

Moreover, the strange thing is that specification forbids multiple
entries in the SETTINGS frame with the same ID even if flags are
different.  As a result, Chrome sends two SETTINGS frames: one with
its own configuration, and another one with configuration stored
for a server (when the FLAG_SETTINGS_PERSIST_VALUE flags were used
by the server).

To simplify implementation we refuse to use the persistent settings
feature and thereby avoid all the complexity related with its proper
support.
2014-01-22 04:58:19 +04:00
Valentin Bartenev
406c0613f5 SPDY: better name for frame entries counter.
The "headers" is not a good term, since it is used not only to count
name/value pairs in the HEADERS block but to count SETTINGS entries too.

Moreover, one name/value pair in HEADERS can contain multiple http headers
with the same name.

No functional changes.
2014-01-22 04:58:19 +04:00
Valentin Bartenev
32bb39c48f SPDY: fixed possible segfault.
While processing a DATA frame, the link to related stream is stored in spdy
connection object as part of connection state.  But this stream can be closed
between receiving parts of the frame.
2014-01-22 04:58:19 +04:00
Valentin Bartenev
1ef5553644 SPDY: send output queue after processing of read event.
During the processing of input some control frames can be added to the queue.
And if there were no writing streams at the moment, these control frames might
be left unsent for a long time (or even forever).

This long delay is especially critical for PING replies since a client can
consider connection as broken and then resend exactly the same request over
a new connection, which is not safe in case of non-idempotent HTTP methods.
2014-01-15 17:16:38 +04:00
Valentin Bartenev
82a1ff31f9 SPDY: the SETTINGS frame should be allocated from sc->pool.
There is no reason to allocate it from connection pool that more like just
a bug especially since ngx_http_spdy_settings_frame_handler() already uses
sc->pool to free a chain.
2014-01-15 17:16:38 +04:00
Valentin Bartenev
b2b43ca50f SPDY: fixed possible uninitialized memory access.
The frame->stream pointer should always be initialized for control frames since
the check against it can be performed in ngx_http_spdy_filter_cleanup().
2014-01-15 17:16:38 +04:00
Valentin Bartenev
ac8bb7a9e5 SPDY: elimination of r->blocked counter usage for queuing frames.
It was used to prevent destroying of request object when there are unsent
frames in queue for the stream.  Since it was incremented for each frame
and is only 8 bits long, so it was not very hard to overflow the counter.

Now the stream->queued counter is checked instead.
2014-01-14 16:24:45 +04:00
Valentin Bartenev
6ddb578b22 SPDY: better name for flag that indicates incomplete frame state.
No functional changes.
2014-01-14 16:24:45 +04:00
Valentin Bartenev
00944562ac SPDY: better name for queued frames counter.
No functional changes.
2014-01-14 16:24:45 +04:00
Valentin Bartenev
df1d8f78ac SPDY: fixed format specifiers in logging. 2014-01-14 16:24:45 +04:00
Valentin Bartenev
75dad742e5 SPDY: fixed possible request hang.
Processing events from upstream connection can result in sending queued frames
from other streams.  In this case such streams were not added to handling queue
and properly handled.

A global per connection flag was replaced by a per stream flag that indicates
currently sending stream while all other streams can be added to handling
queue.
2013-12-26 17:03:16 +04:00
Valentin Bartenev
7f54528ca0 SPDY: drop the "delayed" flag when finalizing connection.
This flag in SPDY fake write events serves the same purposes as the "ready"
flag in real events, and it must be dropped if request needs to be handled.
Otherwise, it can prevent the request from finalization if ngx_http_writer()
was set, which results in a connection leak.

Found by Xiaochen Wang.
2013-12-10 20:27:33 +04:00
Valentin Bartenev
4f4963e87e SPDY: set empty write handler during connection finalization.
While ngx_http_spdy_write_handler() should not make any harm with current code,
calling it during finalization of SPDY connection was not intended.
2013-10-01 00:12:30 +04:00
Valentin Bartenev
92b82c80af SPDY: fixed connection leak while waiting for request headers.
If an error occurs in a SPDY connection, the c->error flag is set on every fake
request connection, and its read or write event handler is called, in order to
finalize it.  But while waiting for request headers, it was a no-op since the
read event handler had been set to ngx_http_empty_handler().
2013-10-01 00:04:00 +04:00
Valentin Bartenev
6ba03097db SPDY: fixed connection leak while waiting for request body.
If an error occurs in a SPDY connection, the c->error flag is set on every fake
request connection, and its read or write event handler is called, in order to
finalize it.  But while waiting for a request body, it was a no-op since the
read event handler ngx_http_request_handler() calls r->read_event_handler that
had been set to ngx_http_block_reading().
2013-10-01 00:00:57 +04:00
Valentin Bartenev
c189eda9e6 SPDY: alert about activated fake events instead of deleting them.
They refer to the same socket descriptor as our real connection, and
deleting them will stop processing of the connection.

Events of fake connections must not be activated, and if it happened there
is nothing we can do.  The whole processing should be terminated as soon as
possible, but it is not obvious how to do this safely.
2013-08-15 19:16:12 +04:00
Valentin Bartenev
db8a0c8bf1 SPDY: do not reject headers with empty value (ticket #396).
A quote from SPDY draft 2 specification: "The length of each name and
value must be greater than zero.  A receiver of a zero-length name or
value must send a RST_STREAM with code PROTOCOL error."

But it appears that Chrome browser allows sending requests over SPDY/2
connection using JavaScript that contain headers with empty values.

For better compatibility across SPDY clients and to be compliant with
HTTP, such headers are no longer rejected.

Also, it is worth noting that in SPDY draft 3 the statement has been
changed so that it permits empty values for headers.
2013-08-15 19:16:09 +04:00
Valentin Bartenev
3be925b6e3 SPDY: fixed corruption of headers with names longer than 255.
It is a bad idea to put zero byte in position where the length of
the next header name can be stored before it was parsed.
2013-08-15 19:14:58 +04:00
Valentin Bartenev
32e167e211 SPDY: fixed segfault with "client_body_in_file_only" enabled.
It is possible to send FLAG_FIN in additional empty data frame, even if it is
known from the content-length header that request body is empty.  And Firefox
actually behaves like this (see ticket #357).

To simplify code we sacrificed our microoptimization that did not work right
due to missing check in the ngx_http_spdy_state_data() function for rb->buf
set to NULL.
2013-07-24 22:24:25 +04:00
Sergey Kandaurov
3be6cc9b2f Use "void" for functions with empty parameter list. 2013-05-23 15:47:58 +04:00
Valentin Bartenev
670d42859d SPDY: set NGX_TCP_NODELAY_DISABLED for fake connections.
This is to avoid setting the TCP_NODELAY flag on SPDY socket in
ngx_http_upstream_send_response().  The latter works per request,
but in SPDY case it might affect other streams in connection.
2013-04-23 10:15:49 +00:00
Valentin Bartenev
2686cb4452 Preliminary experimental support for SPDY draft 2. 2013-03-20 10:36:57 +00:00