Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(307)

Side by Side Diff: net/tools/quic/quic_simple_server_stream.cc

Issue 2611613003: Add quic_logging (Closed)
Patch Set: fix failed test? Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/tools/quic/quic_simple_server_session.cc ('k') | net/tools/quic/quic_spdy_client_stream.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_stream.h" 5 #include "net/tools/quic/quic_simple_server_stream.h"
6 6
7 #include <list> 7 #include <list>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/logging.h"
11 #include "base/stl_util.h" 10 #include "base/stl_util.h"
12 #include "net/quic/core/quic_flags.h" 11 #include "net/quic/core/quic_flags.h"
13 #include "net/quic/core/quic_spdy_stream.h" 12 #include "net/quic/core/quic_spdy_stream.h"
14 #include "net/quic/core/spdy_utils.h" 13 #include "net/quic/core/spdy_utils.h"
15 #include "net/quic/platform/api/quic_bug_tracker.h" 14 #include "net/quic/platform/api/quic_bug_tracker.h"
15 #include "net/quic/platform/api/quic_logging.h"
16 #include "net/quic/platform/api/quic_text_utils.h" 16 #include "net/quic/platform/api/quic_text_utils.h"
17 #include "net/spdy/spdy_protocol.h" 17 #include "net/spdy/spdy_protocol.h"
18 #include "net/tools/quic/quic_http_response_cache.h" 18 #include "net/tools/quic/quic_http_response_cache.h"
19 #include "net/tools/quic/quic_simple_server_session.h" 19 #include "net/tools/quic/quic_simple_server_session.h"
20 20
21 using base::StringPiece; 21 using base::StringPiece;
22 using std::string; 22 using std::string;
23 23
24 namespace net { 24 namespace net {
25 25
26 QuicSimpleServerStream::QuicSimpleServerStream( 26 QuicSimpleServerStream::QuicSimpleServerStream(
27 QuicStreamId id, 27 QuicStreamId id,
28 QuicSpdySession* session, 28 QuicSpdySession* session,
29 QuicHttpResponseCache* response_cache) 29 QuicHttpResponseCache* response_cache)
30 : QuicSpdyServerStreamBase(id, session), 30 : QuicSpdyServerStreamBase(id, session),
31 content_length_(-1), 31 content_length_(-1),
32 response_cache_(response_cache) {} 32 response_cache_(response_cache) {}
33 33
34 QuicSimpleServerStream::~QuicSimpleServerStream() {} 34 QuicSimpleServerStream::~QuicSimpleServerStream() {}
35 35
36 void QuicSimpleServerStream::OnInitialHeadersComplete( 36 void QuicSimpleServerStream::OnInitialHeadersComplete(
37 bool fin, 37 bool fin,
38 size_t frame_len, 38 size_t frame_len,
39 const QuicHeaderList& header_list) { 39 const QuicHeaderList& header_list) {
40 QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list); 40 QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
41 if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_, 41 if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
42 &request_headers_)) { 42 &request_headers_)) {
43 DVLOG(1) << "Invalid headers"; 43 QUIC_DVLOG(1) << "Invalid headers";
44 SendErrorResponse(); 44 SendErrorResponse();
45 } 45 }
46 ConsumeHeaderList(); 46 ConsumeHeaderList();
47 } 47 }
48 48
49 void QuicSimpleServerStream::OnTrailingHeadersComplete( 49 void QuicSimpleServerStream::OnTrailingHeadersComplete(
50 bool fin, 50 bool fin,
51 size_t frame_len, 51 size_t frame_len,
52 const QuicHeaderList& header_list) { 52 const QuicHeaderList& header_list) {
53 QUIC_BUG << "Server does not support receiving Trailers."; 53 QUIC_BUG << "Server does not support receiving Trailers.";
54 SendErrorResponse(); 54 SendErrorResponse();
55 } 55 }
56 56
57 void QuicSimpleServerStream::OnDataAvailable() { 57 void QuicSimpleServerStream::OnDataAvailable() {
58 while (HasBytesToRead()) { 58 while (HasBytesToRead()) {
59 struct iovec iov; 59 struct iovec iov;
60 if (GetReadableRegions(&iov, 1) == 0) { 60 if (GetReadableRegions(&iov, 1) == 0) {
61 // No more data to read. 61 // No more data to read.
62 break; 62 break;
63 } 63 }
64 DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream " << id(); 64 QUIC_DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream "
65 << id();
65 body_.append(static_cast<char*>(iov.iov_base), iov.iov_len); 66 body_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
66 67
67 if (content_length_ >= 0 && 68 if (content_length_ >= 0 &&
68 body_.size() > static_cast<uint64_t>(content_length_)) { 69 body_.size() > static_cast<uint64_t>(content_length_)) {
69 DVLOG(1) << "Body size (" << body_.size() << ") > content length (" 70 QUIC_DVLOG(1) << "Body size (" << body_.size() << ") > content length ("
70 << content_length_ << ")."; 71 << content_length_ << ").";
71 SendErrorResponse(); 72 SendErrorResponse();
72 return; 73 return;
73 } 74 }
74 MarkConsumed(iov.iov_len); 75 MarkConsumed(iov.iov_len);
75 } 76 }
76 if (!sequencer()->IsClosed()) { 77 if (!sequencer()->IsClosed()) {
77 sequencer()->SetUnblocked(); 78 sequencer()->SetUnblocked();
78 return; 79 return;
79 } 80 }
80 81
(...skipping 10 matching lines...) Expand all
91 92
92 void QuicSimpleServerStream::PushResponse( 93 void QuicSimpleServerStream::PushResponse(
93 SpdyHeaderBlock push_request_headers) { 94 SpdyHeaderBlock push_request_headers) {
94 if (id() % 2 != 0) { 95 if (id() % 2 != 0) {
95 QUIC_BUG << "Client initiated stream shouldn't be used as promised stream."; 96 QUIC_BUG << "Client initiated stream shouldn't be used as promised stream.";
96 return; 97 return;
97 } 98 }
98 // Change the stream state to emulate a client request. 99 // Change the stream state to emulate a client request.
99 request_headers_ = std::move(push_request_headers); 100 request_headers_ = std::move(push_request_headers);
100 content_length_ = 0; 101 content_length_ = 0;
101 DVLOG(1) << "Stream " << id() << ": Ready to receive server push response."; 102 QUIC_DVLOG(1) << "Stream " << id()
103 << ": Ready to receive server push response.";
102 104
103 // Set as if stream decompresed the headers and received fin. 105 // Set as if stream decompresed the headers and received fin.
104 QuicSpdyStream::OnInitialHeadersComplete(/*fin=*/true, 0, QuicHeaderList()); 106 QuicSpdyStream::OnInitialHeadersComplete(/*fin=*/true, 0, QuicHeaderList());
105 } 107 }
106 108
107 void QuicSimpleServerStream::SendResponse() { 109 void QuicSimpleServerStream::SendResponse() {
108 if (request_headers_.empty()) { 110 if (request_headers_.empty()) {
109 DVLOG(1) << "Request headers empty."; 111 QUIC_DVLOG(1) << "Request headers empty.";
110 SendErrorResponse(); 112 SendErrorResponse();
111 return; 113 return;
112 } 114 }
113 115
114 if (content_length_ > 0 && 116 if (content_length_ > 0 &&
115 static_cast<uint64_t>(content_length_) != body_.size()) { 117 static_cast<uint64_t>(content_length_) != body_.size()) {
116 DVLOG(1) << "Content length (" << content_length_ << ") != body size (" 118 QUIC_DVLOG(1) << "Content length (" << content_length_ << ") != body size ("
117 << body_.size() << ")."; 119 << body_.size() << ").";
118 SendErrorResponse(); 120 SendErrorResponse();
119 return; 121 return;
120 } 122 }
121 123
122 if (!base::ContainsKey(request_headers_, ":authority") || 124 if (!base::ContainsKey(request_headers_, ":authority") ||
123 !base::ContainsKey(request_headers_, ":path")) { 125 !base::ContainsKey(request_headers_, ":path")) {
124 DVLOG(1) << "Request headers do not contain :authority or :path."; 126 QUIC_DVLOG(1) << "Request headers do not contain :authority or :path.";
125 SendErrorResponse(); 127 SendErrorResponse();
126 return; 128 return;
127 } 129 }
128 130
129 // Find response in cache. If not found, send error response. 131 // Find response in cache. If not found, send error response.
130 const QuicHttpResponseCache::Response* response = nullptr; 132 const QuicHttpResponseCache::Response* response = nullptr;
131 auto authority = request_headers_.find(":authority"); 133 auto authority = request_headers_.find(":authority");
132 auto path = request_headers_.find(":path"); 134 auto path = request_headers_.find(":path");
133 if (authority != request_headers_.end() && path != request_headers_.end()) { 135 if (authority != request_headers_.end() && path != request_headers_.end()) {
134 response = response_cache_->GetResponse(authority->second, path->second); 136 response = response_cache_->GetResponse(authority->second, path->second);
135 } 137 }
136 if (response == nullptr) { 138 if (response == nullptr) {
137 DVLOG(1) << "Response not found in cache."; 139 QUIC_DVLOG(1) << "Response not found in cache.";
138 SendNotFoundResponse(); 140 SendNotFoundResponse();
139 return; 141 return;
140 } 142 }
141 143
142 if (response->response_type() == QuicHttpResponseCache::CLOSE_CONNECTION) { 144 if (response->response_type() == QuicHttpResponseCache::CLOSE_CONNECTION) {
143 DVLOG(1) << "Special response: closing connection."; 145 QUIC_DVLOG(1) << "Special response: closing connection.";
144 CloseConnectionWithDetails(QUIC_NO_ERROR, "Toy server forcing close"); 146 CloseConnectionWithDetails(QUIC_NO_ERROR, "Toy server forcing close");
145 return; 147 return;
146 } 148 }
147 149
148 if (response->response_type() == QuicHttpResponseCache::IGNORE_REQUEST) { 150 if (response->response_type() == QuicHttpResponseCache::IGNORE_REQUEST) {
149 DVLOG(1) << "Special response: ignoring request."; 151 QUIC_DVLOG(1) << "Special response: ignoring request.";
150 return; 152 return;
151 } 153 }
152 154
153 // Examing response status, if it was not pure integer as typical h2 response 155 // Examing response status, if it was not pure integer as typical h2 response
154 // status, send error response. 156 // status, send error response.
155 string request_url = request_headers_[":authority"].as_string() + 157 string request_url = request_headers_[":authority"].as_string() +
156 request_headers_[":path"].as_string(); 158 request_headers_[":path"].as_string();
157 int response_code; 159 int response_code;
158 const SpdyHeaderBlock& response_headers = response->headers(); 160 const SpdyHeaderBlock& response_headers = response->headers();
159 if (!ParseHeaderStatusCode(response_headers, &response_code)) { 161 if (!ParseHeaderStatusCode(response_headers, &response_code)) {
160 auto status = response_headers.find(":status"); 162 auto status = response_headers.find(":status");
161 if (status == response_headers.end()) { 163 if (status == response_headers.end()) {
162 LOG(WARNING) << ":status not present in response from cache for request " 164 QUIC_LOG(WARNING)
163 << request_url; 165 << ":status not present in response from cache for request "
166 << request_url;
164 } else { 167 } else {
165 LOG(WARNING) << "Illegal (non-integer) response :status from cache: " 168 QUIC_LOG(WARNING) << "Illegal (non-integer) response :status from cache: "
166 << status->second << " for request " << request_url; 169 << status->second << " for request " << request_url;
167 } 170 }
168 SendErrorResponse(); 171 SendErrorResponse();
169 return; 172 return;
170 } 173 }
171 174
172 if (id() % 2 == 0) { 175 if (id() % 2 == 0) {
173 // A server initiated stream is only used for a server push response, 176 // A server initiated stream is only used for a server push response,
174 // and only 200 and 30X response codes are supported for server push. 177 // and only 200 and 30X response codes are supported for server push.
175 // This behavior mirrors the HTTP/2 implementation. 178 // This behavior mirrors the HTTP/2 implementation.
176 bool is_redirection = response_code / 100 == 3; 179 bool is_redirection = response_code / 100 == 3;
177 if (response_code != 200 && !is_redirection) { 180 if (response_code != 200 && !is_redirection) {
178 LOG(WARNING) << "Response to server push request " << request_url 181 QUIC_LOG(WARNING) << "Response to server push request " << request_url
179 << " result in response code " << response_code; 182 << " result in response code " << response_code;
180 Reset(QUIC_STREAM_CANCELLED); 183 Reset(QUIC_STREAM_CANCELLED);
181 return; 184 return;
182 } 185 }
183 } 186 }
184 std::list<QuicHttpResponseCache::ServerPushInfo> resources = 187 std::list<QuicHttpResponseCache::ServerPushInfo> resources =
185 response_cache_->GetServerPushResources(request_url); 188 response_cache_->GetServerPushResources(request_url);
186 DVLOG(1) << "Found " << resources.size() << " push resources for stream " 189 QUIC_DVLOG(1) << "Found " << resources.size() << " push resources for stream "
187 << id(); 190 << id();
188 191
189 if (!resources.empty()) { 192 if (!resources.empty()) {
190 QuicSimpleServerSession* session = 193 QuicSimpleServerSession* session =
191 static_cast<QuicSimpleServerSession*>(spdy_session()); 194 static_cast<QuicSimpleServerSession*>(spdy_session());
192 session->PromisePushResources(request_url, resources, id(), 195 session->PromisePushResources(request_url, resources, id(),
193 request_headers_); 196 request_headers_);
194 } 197 }
195 198
196 DVLOG(1) << "Sending response for stream " << id(); 199 QUIC_DVLOG(1) << "Sending response for stream " << id();
197 SendHeadersAndBodyAndTrailers(response->headers().Clone(), response->body(), 200 SendHeadersAndBodyAndTrailers(response->headers().Clone(), response->body(),
198 response->trailers().Clone()); 201 response->trailers().Clone());
199 } 202 }
200 203
201 void QuicSimpleServerStream::SendNotFoundResponse() { 204 void QuicSimpleServerStream::SendNotFoundResponse() {
202 DVLOG(1) << "Sending not found response for stream " << id(); 205 QUIC_DVLOG(1) << "Sending not found response for stream " << id();
203 SpdyHeaderBlock headers; 206 SpdyHeaderBlock headers;
204 headers[":status"] = "404"; 207 headers[":status"] = "404";
205 headers["content-length"] = 208 headers["content-length"] =
206 QuicTextUtils::Uint64ToString(strlen(kNotFoundResponseBody)); 209 QuicTextUtils::Uint64ToString(strlen(kNotFoundResponseBody));
207 SendHeadersAndBody(std::move(headers), kNotFoundResponseBody); 210 SendHeadersAndBody(std::move(headers), kNotFoundResponseBody);
208 } 211 }
209 212
210 void QuicSimpleServerStream::SendErrorResponse() { 213 void QuicSimpleServerStream::SendErrorResponse() {
211 DVLOG(1) << "Sending error response for stream " << id(); 214 QUIC_DVLOG(1) << "Sending error response for stream " << id();
212 SpdyHeaderBlock headers; 215 SpdyHeaderBlock headers;
213 headers[":status"] = "500"; 216 headers[":status"] = "500";
214 headers["content-length"] = 217 headers["content-length"] =
215 QuicTextUtils::Uint64ToString(strlen(kErrorResponseBody)); 218 QuicTextUtils::Uint64ToString(strlen(kErrorResponseBody));
216 SendHeadersAndBody(std::move(headers), kErrorResponseBody); 219 SendHeadersAndBody(std::move(headers), kErrorResponseBody);
217 } 220 }
218 221
219 void QuicSimpleServerStream::SendHeadersAndBody( 222 void QuicSimpleServerStream::SendHeadersAndBody(
220 SpdyHeaderBlock response_headers, 223 SpdyHeaderBlock response_headers,
221 StringPiece body) { 224 StringPiece body) {
222 SendHeadersAndBodyAndTrailers(std::move(response_headers), body, 225 SendHeadersAndBodyAndTrailers(std::move(response_headers), body,
223 SpdyHeaderBlock()); 226 SpdyHeaderBlock());
224 } 227 }
225 228
226 void QuicSimpleServerStream::SendHeadersAndBodyAndTrailers( 229 void QuicSimpleServerStream::SendHeadersAndBodyAndTrailers(
227 SpdyHeaderBlock response_headers, 230 SpdyHeaderBlock response_headers,
228 StringPiece body, 231 StringPiece body,
229 SpdyHeaderBlock response_trailers) { 232 SpdyHeaderBlock response_trailers) {
230 if (!allow_bidirectional_data() && !reading_stopped()) { 233 if (!allow_bidirectional_data() && !reading_stopped()) {
231 StopReading(); 234 StopReading();
232 } 235 }
233 236
234 // Send the headers, with a FIN if there's nothing else to send. 237 // Send the headers, with a FIN if there's nothing else to send.
235 bool send_fin = (body.empty() && response_trailers.empty()); 238 bool send_fin = (body.empty() && response_trailers.empty());
236 DVLOG(1) << "Writing headers (fin = " << send_fin 239 QUIC_DLOG(INFO) << "Writing headers (fin = " << send_fin
237 << ") : " << response_headers.DebugString(); 240 << ") : " << response_headers.DebugString();
238 WriteHeaders(std::move(response_headers), send_fin, nullptr); 241 WriteHeaders(std::move(response_headers), send_fin, nullptr);
239 if (send_fin) { 242 if (send_fin) {
240 // Nothing else to send. 243 // Nothing else to send.
241 return; 244 return;
242 } 245 }
243 246
244 // Send the body, with a FIN if there's no trailers to send. 247 // Send the body, with a FIN if there's no trailers to send.
245 send_fin = response_trailers.empty(); 248 send_fin = response_trailers.empty();
246 DVLOG(1) << "Writing body (fin = " << send_fin 249 QUIC_DLOG(INFO) << "Writing body (fin = " << send_fin
247 << ") with size: " << body.size(); 250 << ") with size: " << body.size();
248 if (!body.empty() || send_fin) { 251 if (!body.empty() || send_fin) {
249 WriteOrBufferData(body, send_fin, nullptr); 252 WriteOrBufferData(body, send_fin, nullptr);
250 } 253 }
251 if (send_fin) { 254 if (send_fin) {
252 // Nothing else to send. 255 // Nothing else to send.
253 return; 256 return;
254 } 257 }
255 258
256 // Send the trailers. A FIN is always sent with trailers. 259 // Send the trailers. A FIN is always sent with trailers.
257 DVLOG(1) << "Writing trailers (fin = true): " 260 QUIC_DLOG(INFO) << "Writing trailers (fin = true): "
258 << response_trailers.DebugString(); 261 << response_trailers.DebugString();
259 WriteTrailers(std::move(response_trailers), nullptr); 262 WriteTrailers(std::move(response_trailers), nullptr);
260 } 263 }
261 264
262 const char* const QuicSimpleServerStream::kErrorResponseBody = "bad"; 265 const char* const QuicSimpleServerStream::kErrorResponseBody = "bad";
263 const char* const QuicSimpleServerStream::kNotFoundResponseBody = 266 const char* const QuicSimpleServerStream::kNotFoundResponseBody =
264 "file not found"; 267 "file not found";
265 268
266 } // namespace net 269 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/quic/quic_simple_server_session.cc ('k') | net/tools/quic/quic_spdy_client_stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698