OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/spdy/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 1998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2009 | 2009 |
2010 if (availability_state_ == STATE_GOING_AWAY) { | 2010 if (availability_state_ == STATE_GOING_AWAY) { |
2011 // TODO(akalin): This behavior isn't in the SPDY spec, although it | 2011 // TODO(akalin): This behavior isn't in the SPDY spec, although it |
2012 // probably should be. | 2012 // probably should be. |
2013 EnqueueResetStreamFrame(stream_id, request_priority, | 2013 EnqueueResetStreamFrame(stream_id, request_priority, |
2014 RST_STREAM_REFUSED_STREAM, | 2014 RST_STREAM_REFUSED_STREAM, |
2015 "OnSyn received when going away"); | 2015 "OnSyn received when going away"); |
2016 return; | 2016 return; |
2017 } | 2017 } |
2018 | 2018 |
2019 if (associated_stream_id == 0) { | 2019 // TODO(jgraettinger): SpdyFramer simulates OnSynStream() from HEADERS |
| 2020 // frames, which don't convey associated stream ID. Disable this check |
| 2021 // for now, and re-enable when PUSH_PROMISE is implemented properly. |
| 2022 if (associated_stream_id == 0 && GetProtocolVersion() < SPDY4) { |
2020 std::string description = base::StringPrintf( | 2023 std::string description = base::StringPrintf( |
2021 "Received invalid OnSyn associated stream id %d for stream %d", | 2024 "Received invalid OnSyn associated stream id %d for stream %d", |
2022 associated_stream_id, stream_id); | 2025 associated_stream_id, stream_id); |
2023 EnqueueResetStreamFrame(stream_id, request_priority, | 2026 EnqueueResetStreamFrame(stream_id, request_priority, |
2024 RST_STREAM_REFUSED_STREAM, description); | 2027 RST_STREAM_REFUSED_STREAM, description); |
2025 return; | 2028 return; |
2026 } | 2029 } |
2027 | 2030 |
2028 streams_pushed_count_++; | 2031 streams_pushed_count_++; |
2029 | 2032 |
2030 // TODO(mbelshe): DCHECK that this is a GET method? | 2033 // TODO(mbelshe): DCHECK that this is a GET method? |
2031 | 2034 |
2032 // Verify that the response had a URL for us. | 2035 // Verify that the response had a URL for us. |
2033 GURL gurl = GetUrlFromHeaderBlock(headers, GetProtocolVersion(), true); | 2036 GURL gurl = GetUrlFromHeaderBlock(headers, GetProtocolVersion(), true); |
2034 if (!gurl.is_valid()) { | 2037 if (!gurl.is_valid()) { |
2035 EnqueueResetStreamFrame( | 2038 EnqueueResetStreamFrame( |
2036 stream_id, request_priority, RST_STREAM_PROTOCOL_ERROR, | 2039 stream_id, request_priority, RST_STREAM_PROTOCOL_ERROR, |
2037 "Pushed stream url was invalid: " + gurl.spec()); | 2040 "Pushed stream url was invalid: " + gurl.spec()); |
2038 return; | 2041 return; |
2039 } | 2042 } |
2040 | 2043 |
2041 // Verify we have a valid stream association. | 2044 // Verify we have a valid stream association. |
2042 ActiveStreamMap::iterator associated_it = | 2045 ActiveStreamMap::iterator associated_it = |
2043 active_streams_.find(associated_stream_id); | 2046 active_streams_.find(associated_stream_id); |
2044 if (associated_it == active_streams_.end()) { | 2047 // TODO(jgraettinger): (See PUSH_PROMISE comment above). |
| 2048 if (GetProtocolVersion() < SPDY4 && associated_it == active_streams_.end()) { |
2045 EnqueueResetStreamFrame( | 2049 EnqueueResetStreamFrame( |
2046 stream_id, request_priority, RST_STREAM_INVALID_STREAM, | 2050 stream_id, request_priority, RST_STREAM_INVALID_STREAM, |
2047 base::StringPrintf( | 2051 base::StringPrintf( |
2048 "Received OnSyn with inactive associated stream %d", | 2052 "Received OnSyn with inactive associated stream %d", |
2049 associated_stream_id)); | 2053 associated_stream_id)); |
2050 return; | 2054 return; |
2051 } | 2055 } |
2052 | 2056 |
2053 // Check that the SYN advertises the same origin as its associated stream. | 2057 // Check that the SYN advertises the same origin as its associated stream. |
2054 // Bypass this check if and only if this session is with a SPDY proxy that | 2058 // Bypass this check if and only if this session is with a SPDY proxy that |
2055 // is trusted explicitly via the --trusted-spdy-proxy switch. | 2059 // is trusted explicitly via the --trusted-spdy-proxy switch. |
2056 if (trusted_spdy_proxy_.Equals(host_port_pair())) { | 2060 if (trusted_spdy_proxy_.Equals(host_port_pair())) { |
2057 // Disallow pushing of HTTPS content. | 2061 // Disallow pushing of HTTPS content. |
2058 if (gurl.SchemeIs("https")) { | 2062 if (gurl.SchemeIs("https")) { |
2059 EnqueueResetStreamFrame( | 2063 EnqueueResetStreamFrame( |
2060 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, | 2064 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, |
2061 base::StringPrintf( | 2065 base::StringPrintf( |
2062 "Rejected push of Cross Origin HTTPS content %d", | 2066 "Rejected push of Cross Origin HTTPS content %d", |
2063 associated_stream_id)); | 2067 associated_stream_id)); |
2064 } | 2068 } |
2065 } else { | 2069 } else if (GetProtocolVersion() < SPDY4) { |
| 2070 // TODO(jgraettinger): (See PUSH_PROMISE comment above). |
2066 GURL associated_url(associated_it->second.stream->GetUrlFromHeaders()); | 2071 GURL associated_url(associated_it->second.stream->GetUrlFromHeaders()); |
2067 if (associated_url.GetOrigin() != gurl.GetOrigin()) { | 2072 if (associated_url.GetOrigin() != gurl.GetOrigin()) { |
2068 EnqueueResetStreamFrame( | 2073 EnqueueResetStreamFrame( |
2069 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, | 2074 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, |
2070 base::StringPrintf( | 2075 base::StringPrintf( |
2071 "Rejected Cross Origin Push Stream %d", | 2076 "Rejected Cross Origin Push Stream %d", |
2072 associated_stream_id)); | 2077 associated_stream_id)); |
2073 return; | 2078 return; |
2074 } | 2079 } |
2075 } | 2080 } |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2179 // NOTE: it may just be that the stream was cancelled. | 2184 // NOTE: it may just be that the stream was cancelled. |
2180 return; | 2185 return; |
2181 } | 2186 } |
2182 | 2187 |
2183 SpdyStream* stream = it->second.stream; | 2188 SpdyStream* stream = it->second.stream; |
2184 CHECK_EQ(stream->stream_id(), stream_id); | 2189 CHECK_EQ(stream->stream_id(), stream_id); |
2185 | 2190 |
2186 stream->IncrementRawReceivedBytes(last_compressed_frame_len_); | 2191 stream->IncrementRawReceivedBytes(last_compressed_frame_len_); |
2187 last_compressed_frame_len_ = 0; | 2192 last_compressed_frame_len_ = 0; |
2188 | 2193 |
| 2194 if (GetProtocolVersion() >= SPDY4) { |
| 2195 const std::string& error = |
| 2196 "SPDY4 wasn't expecting SYN_REPLY."; |
| 2197 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); |
| 2198 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error); |
| 2199 return; |
| 2200 } |
2189 if (!it->second.waiting_for_syn_reply) { | 2201 if (!it->second.waiting_for_syn_reply) { |
2190 const std::string& error = | 2202 const std::string& error = |
2191 "Received duplicate SYN_REPLY for stream."; | 2203 "Received duplicate SYN_REPLY for stream."; |
2192 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); | 2204 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); |
2193 ResetStreamIterator(it, RST_STREAM_STREAM_IN_USE, error); | 2205 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error); |
2194 return; | 2206 return; |
2195 } | 2207 } |
2196 it->second.waiting_for_syn_reply = false; | 2208 it->second.waiting_for_syn_reply = false; |
2197 | 2209 |
2198 ignore_result(OnInitialResponseHeadersReceived( | 2210 ignore_result(OnInitialResponseHeadersReceived( |
2199 headers, response_time, recv_first_byte_time, stream)); | 2211 headers, response_time, recv_first_byte_time, stream)); |
2200 } | 2212 } |
2201 | 2213 |
2202 void SpdySession::OnHeaders(SpdyStreamId stream_id, | 2214 void SpdySession::OnHeaders(SpdyStreamId stream_id, |
2203 bool fin, | 2215 bool fin, |
(...skipping 16 matching lines...) Expand all Loading... |
2220 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; | 2232 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; |
2221 return; | 2233 return; |
2222 } | 2234 } |
2223 | 2235 |
2224 SpdyStream* stream = it->second.stream; | 2236 SpdyStream* stream = it->second.stream; |
2225 CHECK_EQ(stream->stream_id(), stream_id); | 2237 CHECK_EQ(stream->stream_id(), stream_id); |
2226 | 2238 |
2227 stream->IncrementRawReceivedBytes(last_compressed_frame_len_); | 2239 stream->IncrementRawReceivedBytes(last_compressed_frame_len_); |
2228 last_compressed_frame_len_ = 0; | 2240 last_compressed_frame_len_ = 0; |
2229 | 2241 |
2230 int rv = stream->OnAdditionalResponseHeadersReceived(headers); | 2242 if (it->second.waiting_for_syn_reply) { |
2231 if (rv < 0) { | 2243 if (GetProtocolVersion() < SPDY4) { |
2232 DCHECK_NE(rv, ERR_IO_PENDING); | 2244 const std::string& error = |
2233 DCHECK(active_streams_.find(stream_id) == active_streams_.end()); | 2245 "Was expecting SYN_REPLY, not HEADERS."; |
| 2246 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); |
| 2247 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error); |
| 2248 return; |
| 2249 } |
| 2250 base::Time response_time = base::Time::Now(); |
| 2251 base::TimeTicks recv_first_byte_time = time_func_(); |
| 2252 |
| 2253 it->second.waiting_for_syn_reply = false; |
| 2254 ignore_result(OnInitialResponseHeadersReceived( |
| 2255 headers, response_time, recv_first_byte_time, stream)); |
| 2256 } else { |
| 2257 int rv = stream->OnAdditionalResponseHeadersReceived(headers); |
| 2258 if (rv < 0) { |
| 2259 DCHECK_NE(rv, ERR_IO_PENDING); |
| 2260 DCHECK(active_streams_.find(stream_id) == active_streams_.end()); |
| 2261 } |
2234 } | 2262 } |
2235 } | 2263 } |
2236 | 2264 |
2237 void SpdySession::OnRstStream(SpdyStreamId stream_id, | 2265 void SpdySession::OnRstStream(SpdyStreamId stream_id, |
2238 SpdyRstStreamStatus status) { | 2266 SpdyRstStreamStatus status) { |
2239 CHECK(in_io_loop_); | 2267 CHECK(in_io_loop_); |
2240 | 2268 |
2241 if (availability_state_ == STATE_CLOSED) | 2269 if (availability_state_ == STATE_CLOSED) |
2242 return; | 2270 return; |
2243 | 2271 |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2946 if (!queue->empty()) { | 2974 if (!queue->empty()) { |
2947 SpdyStreamId stream_id = queue->front(); | 2975 SpdyStreamId stream_id = queue->front(); |
2948 queue->pop_front(); | 2976 queue->pop_front(); |
2949 return stream_id; | 2977 return stream_id; |
2950 } | 2978 } |
2951 } | 2979 } |
2952 return 0; | 2980 return 0; |
2953 } | 2981 } |
2954 | 2982 |
2955 } // namespace net | 2983 } // namespace net |
OLD | NEW |