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/tools/quic/quic_simple_server_session.h" | 5 #include "net/tools/quic/quic_simple_server_session.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 QuicStreamId original_stream_id, | 70 QuicStreamId original_stream_id, |
71 const SpdyHeaderBlock& original_request_headers) { | 71 const SpdyHeaderBlock& original_request_headers) { |
72 if (!server_push_enabled()) { | 72 if (!server_push_enabled()) { |
73 return; | 73 return; |
74 } | 74 } |
75 | 75 |
76 for (QuicInMemoryCache::ServerPushInfo resource : resources) { | 76 for (QuicInMemoryCache::ServerPushInfo resource : resources) { |
77 SpdyHeaderBlock headers = SynthesizePushRequestHeaders( | 77 SpdyHeaderBlock headers = SynthesizePushRequestHeaders( |
78 request_url, resource, original_request_headers); | 78 request_url, resource, original_request_headers); |
79 highest_promised_stream_id_ += 2; | 79 highest_promised_stream_id_ += 2; |
80 SendPushPromise(original_stream_id, highest_promised_stream_id_, headers); | 80 SendPushPromise(original_stream_id, highest_promised_stream_id_, |
| 81 headers.Clone()); |
81 promised_streams_.push_back(PromisedStreamInfo( | 82 promised_streams_.push_back(PromisedStreamInfo( |
82 std::move(headers), highest_promised_stream_id_, resource.priority)); | 83 std::move(headers), highest_promised_stream_id_, resource.priority)); |
83 } | 84 } |
84 | 85 |
85 // Procese promised push request as many as possible. | 86 // Procese promised push request as many as possible. |
86 HandlePromisedPushRequests(); | 87 HandlePromisedPushRequests(); |
87 } | 88 } |
88 | 89 |
89 QuicSpdyStream* QuicSimpleServerSession::CreateIncomingDynamicStream( | 90 QuicSpdyStream* QuicSimpleServerSession::CreateIncomingDynamicStream( |
90 QuicStreamId id) { | 91 QuicStreamId id) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 } | 145 } |
145 } | 146 } |
146 | 147 |
147 SpdyHeaderBlock QuicSimpleServerSession::SynthesizePushRequestHeaders( | 148 SpdyHeaderBlock QuicSimpleServerSession::SynthesizePushRequestHeaders( |
148 string request_url, | 149 string request_url, |
149 QuicInMemoryCache::ServerPushInfo resource, | 150 QuicInMemoryCache::ServerPushInfo resource, |
150 const SpdyHeaderBlock& original_request_headers) { | 151 const SpdyHeaderBlock& original_request_headers) { |
151 GURL push_request_url = resource.request_url; | 152 GURL push_request_url = resource.request_url; |
152 string path = push_request_url.path(); | 153 string path = push_request_url.path(); |
153 | 154 |
154 SpdyHeaderBlock spdy_headers = original_request_headers; | 155 SpdyHeaderBlock spdy_headers = original_request_headers.Clone(); |
155 // :authority could be different from original request. | 156 // :authority could be different from original request. |
156 spdy_headers.ReplaceOrAppendHeader(":authority", push_request_url.host()); | 157 spdy_headers.ReplaceOrAppendHeader(":authority", push_request_url.host()); |
157 spdy_headers.ReplaceOrAppendHeader(":path", path); | 158 spdy_headers.ReplaceOrAppendHeader(":path", path); |
158 // Push request always use GET. | 159 // Push request always use GET. |
159 spdy_headers.ReplaceOrAppendHeader(":method", "GET"); | 160 spdy_headers.ReplaceOrAppendHeader(":method", "GET"); |
160 spdy_headers.ReplaceOrAppendHeader("referer", request_url); | 161 spdy_headers.ReplaceOrAppendHeader("referer", request_url); |
161 spdy_headers.ReplaceOrAppendHeader(":scheme", push_request_url.scheme()); | 162 spdy_headers.ReplaceOrAppendHeader(":scheme", push_request_url.scheme()); |
162 // It is not possible to push a response to a request that includes a request | 163 // It is not possible to push a response to a request that includes a request |
163 // body. | 164 // body. |
164 spdy_headers.ReplaceOrAppendHeader("content-length", "0"); | 165 spdy_headers.ReplaceOrAppendHeader("content-length", "0"); |
165 // Remove "host" field as push request is a directly generated HTTP2 request | 166 // Remove "host" field as push request is a directly generated HTTP2 request |
166 // which should use ":authority" instead of "host". | 167 // which should use ":authority" instead of "host". |
167 spdy_headers.erase("host"); | 168 spdy_headers.erase("host"); |
168 return spdy_headers; | 169 return spdy_headers; |
169 } | 170 } |
170 | 171 |
171 void QuicSimpleServerSession::SendPushPromise(QuicStreamId original_stream_id, | 172 void QuicSimpleServerSession::SendPushPromise(QuicStreamId original_stream_id, |
172 QuicStreamId promised_stream_id, | 173 QuicStreamId promised_stream_id, |
173 SpdyHeaderBlock headers) { | 174 SpdyHeaderBlock headers) { |
174 DVLOG(1) << "stream " << original_stream_id | 175 DVLOG(1) << "stream " << original_stream_id |
175 << " send PUSH_PROMISE for promised stream " << promised_stream_id; | 176 << " send PUSH_PROMISE for promised stream " << promised_stream_id; |
176 headers_stream()->WritePushPromise(original_stream_id, promised_stream_id, | 177 headers_stream()->WritePushPromise(original_stream_id, promised_stream_id, |
177 std::move(headers), nullptr); | 178 std::move(headers), nullptr); |
178 } | 179 } |
179 | 180 |
180 void QuicSimpleServerSession::HandlePromisedPushRequests() { | 181 void QuicSimpleServerSession::HandlePromisedPushRequests() { |
181 while (!promised_streams_.empty() && ShouldCreateOutgoingDynamicStream()) { | 182 while (!promised_streams_.empty() && ShouldCreateOutgoingDynamicStream()) { |
182 const PromisedStreamInfo& promised_info = promised_streams_.front(); | 183 PromisedStreamInfo& promised_info = promised_streams_.front(); |
183 DCHECK_EQ(next_outgoing_stream_id(), promised_info.stream_id); | 184 DCHECK_EQ(next_outgoing_stream_id(), promised_info.stream_id); |
184 | 185 |
185 if (promised_info.is_cancelled) { | 186 if (promised_info.is_cancelled) { |
186 // This stream has been reset by client. Skip this stream id. | 187 // This stream has been reset by client. Skip this stream id. |
187 promised_streams_.pop_front(); | 188 promised_streams_.pop_front(); |
188 GetNextOutgoingStreamId(); | 189 GetNextOutgoingStreamId(); |
189 return; | 190 return; |
190 } | 191 } |
191 | 192 |
192 QuicSimpleServerStream* promised_stream = | 193 QuicSimpleServerStream* promised_stream = |
193 static_cast<QuicSimpleServerStream*>( | 194 static_cast<QuicSimpleServerStream*>( |
194 CreateOutgoingDynamicStream(promised_info.priority)); | 195 CreateOutgoingDynamicStream(promised_info.priority)); |
195 DCHECK(promised_stream != nullptr); | 196 DCHECK(promised_stream != nullptr); |
196 DCHECK_EQ(promised_info.stream_id, promised_stream->id()); | 197 DCHECK_EQ(promised_info.stream_id, promised_stream->id()); |
197 DVLOG(1) << "created server push stream " << promised_stream->id(); | 198 DVLOG(1) << "created server push stream " << promised_stream->id(); |
198 | 199 |
199 const SpdyHeaderBlock request_headers(promised_info.request_headers); | 200 SpdyHeaderBlock request_headers(std::move(promised_info.request_headers)); |
200 | 201 |
201 promised_streams_.pop_front(); | 202 promised_streams_.pop_front(); |
202 promised_stream->PushResponse(request_headers); | 203 promised_stream->PushResponse(std::move(request_headers)); |
203 } | 204 } |
204 } | 205 } |
205 | 206 |
206 } // namespace net | 207 } // namespace net |
OLD | NEW |