| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_network_transaction.h" | 5 #include "net/spdy/spdy_network_transaction.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/ref_counted.h" | 8 #include "base/ref_counted.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "net/base/completion_callback.h" | 10 #include "net/base/completion_callback.h" |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 &buffer_write, | 493 &buffer_write, |
| 494 &buffer_left); | 494 &buffer_left); |
| 495 packet_size += AppendToBuffer("\n", | 495 packet_size += AppendToBuffer("\n", |
| 496 strlen("\n"), | 496 strlen("\n"), |
| 497 &buffer_write, | 497 &buffer_write, |
| 498 &buffer_left); | 498 &buffer_left); |
| 499 } | 499 } |
| 500 return packet_size; | 500 return packet_size; |
| 501 } | 501 } |
| 502 | 502 |
| 503 // Construct a single SPDY header entry, for validation. | |
| 504 // |extra_headers| are the extra header-value pairs. | |
| 505 // |buffer| is the buffer we're filling in. | |
| 506 // |index| is the index of the header we want. | |
| 507 // Returns the number of bytes written into |buffer|. | |
| 508 int ConstructSpdyHeader(const char* const extra_headers[], | |
| 509 int extra_header_count, | |
| 510 char* buffer, | |
| 511 int buffer_length, | |
| 512 int index) { | |
| 513 const char* this_header = NULL; | |
| 514 const char* this_value = NULL; | |
| 515 if (!buffer || !buffer_length) | |
| 516 return 0; | |
| 517 *buffer = '\0'; | |
| 518 // Sanity check: Non-empty header list. | |
| 519 DCHECK(NULL != extra_headers) << "NULL extra headers pointer"; | |
| 520 // Sanity check: Index out of range. | |
| 521 DCHECK((index >= 0) && (index < extra_header_count)) | |
| 522 << "Index " << index | |
| 523 << " out of range [0, " << extra_header_count << ")"; | |
| 524 this_header = extra_headers[index * 2]; | |
| 525 // Sanity check: Non-empty header. | |
| 526 if (!*this_header) | |
| 527 return 0; | |
| 528 std::string::size_type header_len = strlen(this_header); | |
| 529 if (!header_len) | |
| 530 return 0; | |
| 531 this_value = extra_headers[1 + (index * 2)]; | |
| 532 // Sanity check: Non-empty value. | |
| 533 if (!*this_value) | |
| 534 this_value = ""; | |
| 535 int n = base::snprintf(buffer, | |
| 536 buffer_length, | |
| 537 "%s: %s\r\n", | |
| 538 this_header, | |
| 539 this_value); | |
| 540 return n; | |
| 541 } | |
| 542 | |
| 543 // Constructs a standard SPDY GET packet. | 503 // Constructs a standard SPDY GET packet. |
| 544 // |extra_headers| are the extra header-value pairs, which typically | 504 // |extra_headers| are the extra header-value pairs, which typically |
| 545 // will vary the most between calls. | 505 // will vary the most between calls. |
| 546 // Returns a SpdFrame. | 506 // Returns a SpdFrame. |
| 547 spdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[], | 507 spdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[], |
| 548 int extra_header_count) { | 508 int extra_header_count) { |
| 549 SpdyHeaderInfo SynStartHeader = { | 509 SpdyHeaderInfo SynStartHeader = { |
| 550 spdy::SYN_STREAM, // Kind = Syn | 510 spdy::SYN_STREAM, // Kind = Syn |
| 551 1, // Stream ID | 511 1, // Stream ID |
| 552 0, // Associated stream ID | 512 0, // Associated stream ID |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 const SpdyHeaderInfo* syn_reply; | 1122 const SpdyHeaderInfo* syn_reply; |
| 1163 bool vary_matches; | 1123 bool vary_matches; |
| 1164 int num_headers[2]; | 1124 int num_headers[2]; |
| 1165 const char* extra_headers[2][16]; | 1125 const char* extra_headers[2][16]; |
| 1166 } test_cases[] = { | 1126 } test_cases[] = { |
| 1167 // Test the case of a multi-valued cookie. When the value is delimited | 1127 // Test the case of a multi-valued cookie. When the value is delimited |
| 1168 // with NUL characters, it needs to be unfolded into multiple headers. | 1128 // with NUL characters, it needs to be unfolded into multiple headers. |
| 1169 { | 1129 { |
| 1170 &syn_reply_info, | 1130 &syn_reply_info, |
| 1171 true, | 1131 true, |
| 1172 { 2, 4 }, | 1132 { 1, 4 }, |
| 1173 { { "cookie", "val1", | 1133 { { "cookie", "val1,val2", |
| 1174 "cookie", "val2", | |
| 1175 NULL | 1134 NULL |
| 1176 }, | 1135 }, |
| 1177 { "vary", "cookie", | 1136 { "vary", "cookie", |
| 1178 "status", "200", | 1137 "status", "200", |
| 1179 "url", "/index.php", | 1138 "url", "/index.php", |
| 1180 "version", "HTTP/1.1", | 1139 "version", "HTTP/1.1", |
| 1181 NULL | 1140 NULL |
| 1182 } | 1141 } |
| 1183 } | 1142 } |
| 1184 }, { // Multiple vary fields. | 1143 }, { // Multiple vary fields. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1223 "status", "200", | 1182 "status", "200", |
| 1224 "url", "/index.php", | 1183 "url", "/index.php", |
| 1225 "version", "HTTP/1.1", | 1184 "version", "HTTP/1.1", |
| 1226 NULL | 1185 NULL |
| 1227 } | 1186 } |
| 1228 } | 1187 } |
| 1229 } | 1188 } |
| 1230 }; | 1189 }; |
| 1231 | 1190 |
| 1232 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { | 1191 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { |
| 1233 char modified_syn_header[64]; | |
| 1234 | |
| 1235 // Construct the request. | 1192 // Construct the request. |
| 1236 scoped_ptr<spdy::SpdyFrame> frame_req( | 1193 scoped_ptr<spdy::SpdyFrame> frame_req( |
| 1237 ConstructSpdyGet(test_cases[i].extra_headers[0], | 1194 ConstructSpdyGet(test_cases[i].extra_headers[0], |
| 1238 test_cases[i].num_headers[0])); | 1195 test_cases[i].num_headers[0])); |
| 1239 | 1196 |
| 1240 MockWrite writes[] = { | 1197 MockWrite writes[] = { |
| 1241 MockWrite( | 1198 MockWrite( |
| 1242 true, | 1199 true, |
| 1243 frame_req->data(), | 1200 frame_req->data(), |
| 1244 frame_req->length() + spdy::SpdyFrame::size()), | 1201 frame_req->length() + spdy::SpdyFrame::size()), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1261 arraysize(kGetBodyFrame)), | 1218 arraysize(kGetBodyFrame)), |
| 1262 MockRead(true, 0, 0) // EOF | 1219 MockRead(true, 0, 0) // EOF |
| 1263 }; | 1220 }; |
| 1264 | 1221 |
| 1265 HttpRequestInfo request; | 1222 HttpRequestInfo request; |
| 1266 request.method = "GET"; | 1223 request.method = "GET"; |
| 1267 request.url = GURL("http://www.google.com/"); | 1224 request.url = GURL("http://www.google.com/"); |
| 1268 request.load_flags = 0; | 1225 request.load_flags = 0; |
| 1269 | 1226 |
| 1270 // Attach the headers to the request. | 1227 // Attach the headers to the request. |
| 1271 int hdrCount = test_cases[i].num_headers[0]; | 1228 int header_count = test_cases[i].num_headers[0]; |
| 1272 int len = 0; | |
| 1273 | 1229 |
| 1274 for (int ct = 0; ct < hdrCount; ct++) { | 1230 for (int ct = 0; ct < header_count; ct++) { |
| 1275 len = ConstructSpdyHeader(test_cases[i].extra_headers[0], | 1231 const char* header_key = test_cases[i].extra_headers[0][ct * 2]; |
| 1276 test_cases[i].num_headers[0], | 1232 const char* header_value = test_cases[i].extra_headers[0][ct * 2 + 1]; |
| 1277 modified_syn_header, | 1233 request.extra_headers.SetHeader(header_key, header_value); |
| 1278 64, | |
| 1279 ct); | |
| 1280 | |
| 1281 request.extra_headers.append(modified_syn_header); | |
| 1282 } | 1234 } |
| 1283 | 1235 |
| 1284 scoped_refptr<DelayedSocketData> data( | 1236 scoped_refptr<DelayedSocketData> data( |
| 1285 new DelayedSocketData(1, reads, arraysize(reads), | 1237 new DelayedSocketData(1, reads, arraysize(reads), |
| 1286 writes, arraysize(writes))); | 1238 writes, arraysize(writes))); |
| 1287 TransactionHelperResult out = TransactionHelper(request, data.get(), NULL); | 1239 TransactionHelperResult out = TransactionHelper(request, data.get(), NULL); |
| 1288 EXPECT_EQ(OK, out.rv) << i; | 1240 EXPECT_EQ(OK, out.rv) << i; |
| 1289 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i; | 1241 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line) << i; |
| 1290 EXPECT_EQ("hello!", out.response_data) << i; | 1242 EXPECT_EQ("hello!", out.response_data) << i; |
| 1291 | 1243 |
| (...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2452 // We shouldn't get here in this test. | 2404 // We shouldn't get here in this test. |
| 2453 FAIL() << "Unexpected read: " << rv; | 2405 FAIL() << "Unexpected read: " << rv; |
| 2454 } while (rv > 0); | 2406 } while (rv > 0); |
| 2455 | 2407 |
| 2456 // Flush the MessageLoop; this will cause the buffered IO task | 2408 // Flush the MessageLoop; this will cause the buffered IO task |
| 2457 // to run for the final time. | 2409 // to run for the final time. |
| 2458 MessageLoop::current()->RunAllPending(); | 2410 MessageLoop::current()->RunAllPending(); |
| 2459 } | 2411 } |
| 2460 | 2412 |
| 2461 } // namespace net | 2413 } // namespace net |
| OLD | NEW |