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

Side by Side Diff: net/spdy/spdy_protocol.cc

Issue 246073007: SPDY & HPACK: Land recent internal changes (through 65328503) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase on upstream change: Expanded FRAME_TOO_LARGE/FRAME_SIZE_ERROR comment. Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_protocol.h ('k') | net/spdy/spdy_protocol_test.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/spdy/spdy_protocol.h" 5 #include "net/spdy/spdy_protocol.h"
6 6
7 namespace net { 7 namespace net {
8 8
9 SpdyFrameWithNameValueBlockIR::SpdyFrameWithNameValueBlockIR( 9 SpdyFrameWithNameValueBlockIR::SpdyFrameWithNameValueBlockIR(
10 SpdyStreamId stream_id) : SpdyFrameWithFinIR(stream_id) {} 10 SpdyStreamId stream_id) : SpdyFrameWithFinIR(stream_id) {}
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 return false; 42 return false;
43 } 43 }
44 44
45 // The valid range is non-contiguous. 45 // The valid range is non-contiguous.
46 if (frame_type_field == NOOP) { 46 if (frame_type_field == NOOP) {
47 return false; 47 return false;
48 } 48 }
49 49
50 return true; 50 return true;
51 case SPDY4: 51 case SPDY4:
52 case SPDY5:
52 // DATA is the first valid frame. 53 // DATA is the first valid frame.
53 if (frame_type_field < SerializeFrameType(version, DATA)) { 54 if (frame_type_field < SerializeFrameType(version, DATA)) {
54 return false; 55 return false;
55 } 56 }
56 57
57 // BLOCKED is the last valid frame. 58 // BLOCKED is the last valid frame.
58 if (frame_type_field > SerializeFrameType(version, BLOCKED)) { 59 if (frame_type_field > SerializeFrameType(version, BLOCKED)) {
59 return false; 60 return false;
60 } 61 }
61 62
(...skipping 22 matching lines...) Expand all
84 return PING; 85 return PING;
85 case 7: 86 case 7:
86 return GOAWAY; 87 return GOAWAY;
87 case 8: 88 case 8:
88 return HEADERS; 89 return HEADERS;
89 case 9: 90 case 9:
90 return WINDOW_UPDATE; 91 return WINDOW_UPDATE;
91 } 92 }
92 break; 93 break;
93 case SPDY4: 94 case SPDY4:
95 case SPDY5:
94 switch (frame_type_field) { 96 switch (frame_type_field) {
95 case 0: 97 case 0:
96 return DATA; 98 return DATA;
97 case 1: 99 case 1:
98 return HEADERS; 100 return HEADERS;
99 // TODO(hkhalil): Add PRIORITY. 101 // TODO(hkhalil): Add PRIORITY.
100 case 3: 102 case 3:
101 return RST_STREAM; 103 return RST_STREAM;
102 case 4: 104 case 4:
103 return SETTINGS; 105 return SETTINGS;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 return 7; 143 return 7;
142 case HEADERS: 144 case HEADERS:
143 return 8; 145 return 8;
144 case WINDOW_UPDATE: 146 case WINDOW_UPDATE:
145 return 9; 147 return 9;
146 default: 148 default:
147 LOG(DFATAL) << "Serializing unhandled frame type " << frame_type; 149 LOG(DFATAL) << "Serializing unhandled frame type " << frame_type;
148 return -1; 150 return -1;
149 } 151 }
150 case SPDY4: 152 case SPDY4:
153 case SPDY5:
151 switch (frame_type) { 154 switch (frame_type) {
152 case DATA: 155 case DATA:
153 return 0; 156 return 0;
154 case HEADERS: 157 case HEADERS:
155 return 1; 158 return 1;
156 // TODO(hkhalil): Add PRIORITY. 159 // TODO(hkhalil): Add PRIORITY.
157 case RST_STREAM: 160 case RST_STREAM:
158 return 3; 161 return 3;
159 case SETTINGS: 162 case SETTINGS:
160 return 4; 163 return 4;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 } 195 }
193 196
194 // INITIAL_WINDOW_SIZE is the last valid setting id. 197 // INITIAL_WINDOW_SIZE is the last valid setting id.
195 if (setting_id_field > 198 if (setting_id_field >
196 SerializeSettingId(version, SETTINGS_INITIAL_WINDOW_SIZE)) { 199 SerializeSettingId(version, SETTINGS_INITIAL_WINDOW_SIZE)) {
197 return false; 200 return false;
198 } 201 }
199 202
200 return true; 203 return true;
201 case SPDY4: 204 case SPDY4:
205 case SPDY5:
202 // HEADER_TABLE_SIZE is the first valid setting id. 206 // HEADER_TABLE_SIZE is the first valid setting id.
203 if (setting_id_field < 207 if (setting_id_field <
204 SerializeSettingId(version, SETTINGS_HEADER_TABLE_SIZE)) { 208 SerializeSettingId(version, SETTINGS_HEADER_TABLE_SIZE)) {
205 return false; 209 return false;
206 } 210 }
207 211
208 // INITIAL_WINDOW_SIZE is the last valid setting id. 212 // INITIAL_WINDOW_SIZE is the last valid setting id.
209 if (setting_id_field > 213 if (setting_id_field >
210 SerializeSettingId(version, SETTINGS_INITIAL_WINDOW_SIZE)) { 214 SerializeSettingId(version, SETTINGS_INITIAL_WINDOW_SIZE)) {
211 return false; 215 return false;
(...skipping 22 matching lines...) Expand all
234 return SETTINGS_MAX_CONCURRENT_STREAMS; 238 return SETTINGS_MAX_CONCURRENT_STREAMS;
235 case 5: 239 case 5:
236 return SETTINGS_CURRENT_CWND; 240 return SETTINGS_CURRENT_CWND;
237 case 6: 241 case 6:
238 return SETTINGS_DOWNLOAD_RETRANS_RATE; 242 return SETTINGS_DOWNLOAD_RETRANS_RATE;
239 case 7: 243 case 7:
240 return SETTINGS_INITIAL_WINDOW_SIZE; 244 return SETTINGS_INITIAL_WINDOW_SIZE;
241 } 245 }
242 break; 246 break;
243 case SPDY4: 247 case SPDY4:
248 case SPDY5:
244 switch (setting_id_field) { 249 switch (setting_id_field) {
245 case 1: 250 case 1:
246 return SETTINGS_HEADER_TABLE_SIZE; 251 return SETTINGS_HEADER_TABLE_SIZE;
247 case 2: 252 case 2:
248 return SETTINGS_ENABLE_PUSH; 253 return SETTINGS_ENABLE_PUSH;
249 case 3: 254 case 3:
250 return SETTINGS_MAX_CONCURRENT_STREAMS; 255 return SETTINGS_MAX_CONCURRENT_STREAMS;
251 case 4: 256 case 4:
252 return SETTINGS_INITIAL_WINDOW_SIZE; 257 return SETTINGS_INITIAL_WINDOW_SIZE;
253 } 258 }
(...skipping 22 matching lines...) Expand all
276 return 5; 281 return 5;
277 case SETTINGS_DOWNLOAD_RETRANS_RATE: 282 case SETTINGS_DOWNLOAD_RETRANS_RATE:
278 return 6; 283 return 6;
279 case SETTINGS_INITIAL_WINDOW_SIZE: 284 case SETTINGS_INITIAL_WINDOW_SIZE:
280 return 7; 285 return 7;
281 default: 286 default:
282 LOG(DFATAL) << "Serializing unhandled setting id " << id; 287 LOG(DFATAL) << "Serializing unhandled setting id " << id;
283 return -1; 288 return -1;
284 } 289 }
285 case SPDY4: 290 case SPDY4:
291 case SPDY5:
286 switch (id) { 292 switch (id) {
287 case SETTINGS_HEADER_TABLE_SIZE: 293 case SETTINGS_HEADER_TABLE_SIZE:
288 return 1; 294 return 1;
289 case SETTINGS_ENABLE_PUSH: 295 case SETTINGS_ENABLE_PUSH:
290 return 2; 296 return 2;
291 case SETTINGS_MAX_CONCURRENT_STREAMS: 297 case SETTINGS_MAX_CONCURRENT_STREAMS:
292 return 3; 298 return 3;
293 case SETTINGS_INITIAL_WINDOW_SIZE: 299 case SETTINGS_INITIAL_WINDOW_SIZE:
294 return 4; 300 return 4;
295 default: 301 default:
296 LOG(DFATAL) << "Serializing unhandled setting id " << id; 302 LOG(DFATAL) << "Serializing unhandled setting id " << id;
297 return -1; 303 return -1;
298 } 304 }
299 } 305 }
300 LOG(DFATAL) << "Unhandled SPDY version " << version; 306 LOG(DFATAL) << "Unhandled SPDY version " << version;
301 return -1; 307 return -1;
302 } 308 }
303 309
310 bool SpdyConstants::IsValidRstStreamStatus(SpdyMajorVersion version,
311 int rst_stream_status_field) {
312 switch (version) {
313 case SPDY2:
314 case SPDY3:
315 // PROTOCOL_ERROR is the valid first status code.
316 if (rst_stream_status_field <
317 SerializeRstStreamStatus(version, RST_STREAM_PROTOCOL_ERROR)) {
318 return false;
319 }
320
321 // FRAME_TOO_LARGE is the valid last status code.
322 if (rst_stream_status_field >
323 SerializeRstStreamStatus(version, RST_STREAM_FRAME_TOO_LARGE)) {
324 return false;
325 }
326
327 return true;
328 case SPDY4:
329 case SPDY5:
330 // NO_ERROR is the first valid status code.
331 if (rst_stream_status_field <
332 SerializeRstStreamStatus(version, RST_STREAM_PROTOCOL_ERROR)) {
333 return false;
334 }
335
336 // TODO(hkhalil): Omit COMPRESSION_ERROR and SETTINGS_TIMEOUT
337 /*
338 // This works because GOAWAY and RST_STREAM share a namespace.
339 if (rst_stream_status_field ==
340 SerializeGoAwayStatus(version, GOAWAY_COMPRESSION_ERROR) ||
341 rst_stream_status_field ==
342 SerializeGoAwayStatus(version, GOAWAY_SETTINGS_TIMEOUT)) {
343 return false;
344 }
345 */
346
347 // ENHANCE_YOUR_CALM is the last valid status code.
348 if (rst_stream_status_field >
349 SerializeRstStreamStatus(version, RST_STREAM_ENHANCE_YOUR_CALM)) {
350 return false;
351 }
352
353 return true;
354 }
355 LOG(DFATAL) << "Unhandled SPDY version " << version;
356 return false;
357 }
358
359 SpdyRstStreamStatus SpdyConstants::ParseRstStreamStatus(
360 SpdyMajorVersion version,
361 int rst_stream_status_field) {
362 switch (version) {
363 case SPDY2:
364 case SPDY3:
365 switch (rst_stream_status_field) {
366 case 1:
367 return RST_STREAM_PROTOCOL_ERROR;
368 case 2:
369 return RST_STREAM_INVALID_STREAM;
370 case 3:
371 return RST_STREAM_REFUSED_STREAM;
372 case 4:
373 return RST_STREAM_UNSUPPORTED_VERSION;
374 case 5:
375 return RST_STREAM_CANCEL;
376 case 6:
377 return RST_STREAM_INTERNAL_ERROR;
378 case 7:
379 return RST_STREAM_FLOW_CONTROL_ERROR;
380 case 8:
381 return RST_STREAM_STREAM_IN_USE;
382 case 9:
383 return RST_STREAM_STREAM_ALREADY_CLOSED;
384 case 10:
385 return RST_STREAM_INVALID_CREDENTIALS;
386 case 11:
387 return RST_STREAM_FRAME_TOO_LARGE;
388 }
389 break;
390 case SPDY4:
391 case SPDY5:
392 switch (rst_stream_status_field) {
393 case 1:
394 return RST_STREAM_PROTOCOL_ERROR;
395 case 2:
396 return RST_STREAM_INTERNAL_ERROR;
397 case 3:
398 return RST_STREAM_FLOW_CONTROL_ERROR;
399 case 5:
400 return RST_STREAM_STREAM_CLOSED;
401 case 6:
402 return RST_STREAM_FRAME_SIZE_ERROR;
403 case 7:
404 return RST_STREAM_REFUSED_STREAM;
405 case 8:
406 return RST_STREAM_CANCEL;
407 case 10:
408 return RST_STREAM_CONNECT_ERROR;
409 case 11:
410 return RST_STREAM_ENHANCE_YOUR_CALM;
411 }
412 break;
413 }
414
415 LOG(DFATAL) << "Invalid RST_STREAM status " << rst_stream_status_field;
416 return RST_STREAM_PROTOCOL_ERROR;
417 }
418
419 int SpdyConstants::SerializeRstStreamStatus(
420 SpdyMajorVersion version,
421 SpdyRstStreamStatus rst_stream_status) {
422 switch (version) {
423 case SPDY2:
424 case SPDY3:
425 switch (rst_stream_status) {
426 case RST_STREAM_PROTOCOL_ERROR:
427 return 1;
428 case RST_STREAM_INVALID_STREAM:
429 return 2;
430 case RST_STREAM_REFUSED_STREAM:
431 return 3;
432 case RST_STREAM_UNSUPPORTED_VERSION:
433 return 4;
434 case RST_STREAM_CANCEL:
435 return 5;
436 case RST_STREAM_INTERNAL_ERROR:
437 return 6;
438 case RST_STREAM_FLOW_CONTROL_ERROR:
439 return 7;
440 case RST_STREAM_STREAM_IN_USE:
441 return 8;
442 case RST_STREAM_STREAM_ALREADY_CLOSED:
443 return 9;
444 case RST_STREAM_INVALID_CREDENTIALS:
445 return 10;
446 case RST_STREAM_FRAME_TOO_LARGE:
447 return 11;
448 default:
449 LOG(DFATAL) << "Unhandled RST_STREAM status "
450 << rst_stream_status;
451 return -1;
452 }
453 case SPDY4:
454 case SPDY5:
455 switch (rst_stream_status) {
456 case RST_STREAM_PROTOCOL_ERROR:
457 return 1;
458 case RST_STREAM_INTERNAL_ERROR:
459 return 2;
460 case RST_STREAM_FLOW_CONTROL_ERROR:
461 return 3;
462 case RST_STREAM_STREAM_CLOSED:
463 return 5;
464 case RST_STREAM_FRAME_SIZE_ERROR:
465 return 6;
466 case RST_STREAM_REFUSED_STREAM:
467 return 7;
468 case RST_STREAM_CANCEL:
469 return 8;
470 case RST_STREAM_CONNECT_ERROR:
471 return 10;
472 case RST_STREAM_ENHANCE_YOUR_CALM:
473 return 11;
474 default:
475 LOG(DFATAL) << "Unhandled RST_STREAM status "
476 << rst_stream_status;
477 return -1;
478 }
479 }
480 LOG(DFATAL) << "Unhandled SPDY version " << version;
481 return -1;
482 }
483
484 bool SpdyConstants::IsValidGoAwayStatus(SpdyMajorVersion version,
485 int goaway_status_field) {
486 switch (version) {
487 case SPDY2:
488 case SPDY3:
489 // GOAWAY_OK is the first valid status.
490 if (goaway_status_field < SerializeGoAwayStatus(version, GOAWAY_OK)) {
491 return false;
492 }
493
494 // GOAWAY_INTERNAL_ERROR is the last valid status.
495 if (goaway_status_field > SerializeGoAwayStatus(version,
496 GOAWAY_INTERNAL_ERROR)) {
497 return false;
498 }
499
500 return true;
501 case SPDY4:
502 case SPDY5:
503 // GOAWAY_NO_ERROR is the first valid status.
504 if (goaway_status_field < SerializeGoAwayStatus(version,
505 GOAWAY_NO_ERROR)) {
506 return false;
507 }
508
509 // GOAWAY_INADEQUATE_SECURITY is the last valid status.
510 if (goaway_status_field >
511 SerializeGoAwayStatus(version, GOAWAY_INADEQUATE_SECURITY)) {
512 return false;
513 }
514
515 return true;
516 }
517 LOG(DFATAL) << "Unknown SpdyMajorVersion " << version;
518 return false;
519 }
520
521 SpdyGoAwayStatus SpdyConstants::ParseGoAwayStatus(SpdyMajorVersion version,
522 int goaway_status_field) {
523 switch (version) {
524 case SPDY2:
525 case SPDY3:
526 switch (goaway_status_field) {
527 case 0:
528 return GOAWAY_OK;
529 case 1:
530 return GOAWAY_PROTOCOL_ERROR;
531 case 2:
532 return GOAWAY_INTERNAL_ERROR;
533 }
534 break;
535 case SPDY4:
536 case SPDY5:
537 switch (goaway_status_field) {
538 case 0:
539 return GOAWAY_NO_ERROR;
540 case 1:
541 return GOAWAY_PROTOCOL_ERROR;
542 case 2:
543 return GOAWAY_INTERNAL_ERROR;
544 case 3:
545 return GOAWAY_FLOW_CONTROL_ERROR;
546 case 4:
547 return GOAWAY_SETTINGS_TIMEOUT;
548 case 5:
549 return GOAWAY_STREAM_CLOSED;
550 case 6:
551 return GOAWAY_FRAME_SIZE_ERROR;
552 case 7:
553 return GOAWAY_REFUSED_STREAM;
554 case 8:
555 return GOAWAY_CANCEL;
556 case 9:
557 return GOAWAY_COMPRESSION_ERROR;
558 case 10:
559 return GOAWAY_CONNECT_ERROR;
560 case 11:
561 return GOAWAY_ENHANCE_YOUR_CALM;
562 case 12:
563 return GOAWAY_INADEQUATE_SECURITY;
564 }
565 break;
566 }
567
568 LOG(DFATAL) << "Unhandled GOAWAY status " << goaway_status_field;
569 return GOAWAY_PROTOCOL_ERROR;
570 }
571
572 SpdyMajorVersion SpdyConstants::ParseMajorVersion(int version_number) {
573 switch (version_number) {
574 case 2:
575 return SPDY2;
576 case 3:
577 return SPDY3;
578 case 4:
579 return SPDY4;
580 case 5:
581 return SPDY5;
582 default:
583 LOG(DFATAL) << "Unsupported SPDY version number: " << version_number;
584 return SPDY3;
585 }
586 }
587
588 int SpdyConstants::SerializeMajorVersion(SpdyMajorVersion version) {
589 switch (version) {
590 case SPDY2:
591 return 2;
592 case SPDY3:
593 return 3;
594 case SPDY4:
595 return 4;
596 case SPDY5:
597 return 5;
598 default:
599 LOG(DFATAL) << "Unsupported SPDY major version: " << version;
600 return -1;
601 }
602 }
603
604 std::string SpdyConstants::GetVersionString(SpdyMajorVersion version) {
605 switch (version) {
606 case SPDY2:
607 return "spdy/2";
608 case SPDY3:
609 return "spdy/3";
610 case SPDY4:
611 return "spdy/4";
612 case SPDY5:
613 return "spdy/5";
614 default:
615 LOG(DFATAL) << "Unsupported SPDY major version: " << version;
616 return "spdy/3";
617 }
618 }
619
620 int SpdyConstants::SerializeGoAwayStatus(SpdyMajorVersion version,
621 SpdyGoAwayStatus status) {
622 switch (version) {
623 case SPDY2:
624 case SPDY3:
625 switch (status) {
626 case GOAWAY_OK:
627 return 0;
628 case GOAWAY_PROTOCOL_ERROR:
629 return 1;
630 case GOAWAY_INTERNAL_ERROR:
631 return 2;
632 default:
633 LOG(DFATAL) << "Serializing unhandled GOAWAY status " << status;
634 return -1;
635 }
636 case SPDY4:
637 case SPDY5:
638 switch (status) {
639 case GOAWAY_NO_ERROR:
640 return 0;
641 case GOAWAY_PROTOCOL_ERROR:
642 return 1;
643 case GOAWAY_INTERNAL_ERROR:
644 return 2;
645 case GOAWAY_FLOW_CONTROL_ERROR:
646 return 3;
647 case GOAWAY_SETTINGS_TIMEOUT:
648 return 4;
649 case GOAWAY_STREAM_CLOSED:
650 return 5;
651 case GOAWAY_FRAME_SIZE_ERROR:
652 return 6;
653 case GOAWAY_REFUSED_STREAM:
654 return 7;
655 case GOAWAY_CANCEL:
656 return 8;
657 case GOAWAY_COMPRESSION_ERROR:
658 return 9;
659 case GOAWAY_CONNECT_ERROR:
660 return 10;
661 case GOAWAY_ENHANCE_YOUR_CALM:
662 return 11;
663 case GOAWAY_INADEQUATE_SECURITY:
664 return 12;
665 default:
666 LOG(DFATAL) << "Serializing unhandled GOAWAY status " << status;
667 return -1;
668 }
669 }
670 LOG(DFATAL) << "Unknown SpdyMajorVersion " << version;
671 return -1;
672 }
673
674 size_t SpdyConstants::GetDataFrameMinimumSize() {
675 return 8;
676 }
677
678 size_t SpdyConstants::GetControlFrameHeaderSize(SpdyMajorVersion version) {
679 switch (version) {
680 case SPDY2:
681 case SPDY3:
682 case SPDY4:
683 case SPDY5:
684 return 8;
685 }
686 LOG(DFATAL) << "Unhandled SPDY version.";
687 return 0;
688 }
689
690 size_t SpdyConstants::GetPrefixLength(SpdyFrameType type,
691 SpdyMajorVersion version) {
692 if (type != DATA) {
693 return GetControlFrameHeaderSize(version);
694 } else {
695 return GetDataFrameMinimumSize();
696 }
697 }
698
699 size_t SpdyConstants::GetFrameMaximumSize(SpdyMajorVersion version) {
700 if (version < SPDY4) {
701 // 24-bit length field plus eight-byte frame header.
702 return ((1<<24) - 1) + 8;
703 } else {
704 // 14-bit length field.
705 return (1<<14) - 1;
706 }
707 }
708
304 void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const { 709 void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const {
305 return visitor->VisitData(*this); 710 return visitor->VisitData(*this);
306 } 711 }
307 712
308 void SpdySynStreamIR::Visit(SpdyFrameVisitor* visitor) const { 713 void SpdySynStreamIR::Visit(SpdyFrameVisitor* visitor) const {
309 return visitor->VisitSynStream(*this); 714 return visitor->VisitSynStream(*this);
310 } 715 }
311 716
312 void SpdySynReplyIR::Visit(SpdyFrameVisitor* visitor) const { 717 void SpdySynReplyIR::Visit(SpdyFrameVisitor* visitor) const {
313 return visitor->VisitSynReply(*this); 718 return visitor->VisitSynReply(*this);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 778
374 void SpdyPushPromiseIR::Visit(SpdyFrameVisitor* visitor) const { 779 void SpdyPushPromiseIR::Visit(SpdyFrameVisitor* visitor) const {
375 return visitor->VisitPushPromise(*this); 780 return visitor->VisitPushPromise(*this);
376 } 781 }
377 782
378 void SpdyContinuationIR::Visit(SpdyFrameVisitor* visitor) const { 783 void SpdyContinuationIR::Visit(SpdyFrameVisitor* visitor) const {
379 return visitor->VisitContinuation(*this); 784 return visitor->VisitContinuation(*this);
380 } 785 }
381 786
382 } // namespace net 787 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_protocol.h ('k') | net/spdy/spdy_protocol_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698