| 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 |