| 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/flip_server/spdy_interface.h" | 5 #include "net/tools/flip_server/spdy_interface.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "net/spdy/spdy_framer.h" | 10 #include "net/spdy/spdy_framer.h" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Creating new HTTP interface"; | 86 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Creating new HTTP interface"; |
| 87 SMInterface* sm_http_interface = | 87 SMInterface* sm_http_interface = |
| 88 new HttpSM(server_connection, this, memory_cache_, acceptor_); | 88 new HttpSM(server_connection, this, memory_cache_, acceptor_); |
| 89 return sm_http_interface; | 89 return sm_http_interface; |
| 90 } | 90 } |
| 91 | 91 |
| 92 SMInterface* SpdySM::FindOrMakeNewSMConnectionInterface( | 92 SMInterface* SpdySM::FindOrMakeNewSMConnectionInterface( |
| 93 const std::string& server_ip, | 93 const std::string& server_ip, |
| 94 const std::string& server_port) { | 94 const std::string& server_port) { |
| 95 SMInterface* sm_http_interface; | 95 SMInterface* sm_http_interface; |
| 96 int32 server_idx; | 96 int32_t server_idx; |
| 97 if (unused_server_interface_list.empty()) { | 97 if (unused_server_interface_list.empty()) { |
| 98 sm_http_interface = NewConnectionInterface(); | 98 sm_http_interface = NewConnectionInterface(); |
| 99 server_idx = server_interface_list.size(); | 99 server_idx = server_interface_list.size(); |
| 100 server_interface_list.push_back(sm_http_interface); | 100 server_interface_list.push_back(sm_http_interface); |
| 101 VLOG(2) << ACCEPTOR_CLIENT_IDENT | 101 VLOG(2) << ACCEPTOR_CLIENT_IDENT |
| 102 << "SpdySM: Making new server connection on index: " << server_idx; | 102 << "SpdySM: Making new server connection on index: " << server_idx; |
| 103 } else { | 103 } else { |
| 104 server_idx = unused_server_interface_list.back(); | 104 server_idx = unused_server_interface_list.back(); |
| 105 unused_server_interface_list.pop_back(); | 105 unused_server_interface_list.pop_back(); |
| 106 sm_http_interface = server_interface_list.at(server_idx); | 106 sm_http_interface = server_interface_list.at(server_idx); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 DCHECK(buffered_spdy_framer_); | 336 DCHECK(buffered_spdy_framer_); |
| 337 return close_on_error_ || buffered_spdy_framer_->HasError(); | 337 return close_on_error_ || buffered_spdy_framer_->HasError(); |
| 338 } | 338 } |
| 339 | 339 |
| 340 const char* SpdySM::ErrorAsString() const { | 340 const char* SpdySM::ErrorAsString() const { |
| 341 DCHECK(Error()); | 341 DCHECK(Error()); |
| 342 DCHECK(buffered_spdy_framer_); | 342 DCHECK(buffered_spdy_framer_); |
| 343 return SpdyFramer::ErrorCodeToString(buffered_spdy_framer_->error_code()); | 343 return SpdyFramer::ErrorCodeToString(buffered_spdy_framer_->error_code()); |
| 344 } | 344 } |
| 345 | 345 |
| 346 void SpdySM::ResetForNewInterface(int32 server_idx) { | 346 void SpdySM::ResetForNewInterface(int32_t server_idx) { |
| 347 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Reset for new interface: " | 347 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Reset for new interface: " |
| 348 << "server_idx: " << server_idx; | 348 << "server_idx: " << server_idx; |
| 349 unused_server_interface_list.push_back(server_idx); | 349 unused_server_interface_list.push_back(server_idx); |
| 350 } | 350 } |
| 351 | 351 |
| 352 void SpdySM::ResetForNewConnection() { | 352 void SpdySM::ResetForNewConnection() { |
| 353 // seq_num is not cleared, intentionally. | 353 // seq_num is not cleared, intentionally. |
| 354 buffered_spdy_framer_.reset(); | 354 buffered_spdy_framer_.reset(); |
| 355 valid_spdy_session_ = false; | 355 valid_spdy_session_ = false; |
| 356 client_output_ordering_.Reset(); | 356 client_output_ordering_.Reset(); |
| 357 next_outgoing_stream_id_ = 2; | 357 next_outgoing_stream_id_ = 2; |
| 358 } | 358 } |
| 359 | 359 |
| 360 // Send a settings frame | 360 // Send a settings frame |
| 361 int SpdySM::PostAcceptHook() { | 361 int SpdySM::PostAcceptHook() { |
| 362 // We should have buffered_spdy_framer_ set after reuse | 362 // We should have buffered_spdy_framer_ set after reuse |
| 363 DCHECK(buffered_spdy_framer_); | 363 DCHECK(buffered_spdy_framer_); |
| 364 SettingsMap settings; | 364 SettingsMap settings; |
| 365 settings[SETTINGS_MAX_CONCURRENT_STREAMS] = | 365 settings[SETTINGS_MAX_CONCURRENT_STREAMS] = |
| 366 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 100); | 366 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 100); |
| 367 SpdyFrame* settings_frame = buffered_spdy_framer_->CreateSettings(settings); | 367 SpdyFrame* settings_frame = buffered_spdy_framer_->CreateSettings(settings); |
| 368 | 368 |
| 369 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending Settings Frame"; | 369 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending Settings Frame"; |
| 370 EnqueueDataFrame(new SpdyFrameDataFrame(settings_frame)); | 370 EnqueueDataFrame(new SpdyFrameDataFrame(settings_frame)); |
| 371 return 1; | 371 return 1; |
| 372 } | 372 } |
| 373 | 373 |
| 374 void SpdySM::NewStream(uint32 stream_id, | 374 void SpdySM::NewStream(uint32_t stream_id, |
| 375 uint32 priority, | 375 uint32_t priority, |
| 376 const std::string& filename) { | 376 const std::string& filename) { |
| 377 MemCacheIter mci; | 377 MemCacheIter mci; |
| 378 mci.stream_id = stream_id; | 378 mci.stream_id = stream_id; |
| 379 mci.priority = priority; | 379 mci.priority = priority; |
| 380 // TODO(yhirano): The program will crash when | 380 // TODO(yhirano): The program will crash when |
| 381 // acceptor_->flip_handler_type_ != FLIP_HANDLER_SPDY_SERVER. | 381 // acceptor_->flip_handler_type_ != FLIP_HANDLER_SPDY_SERVER. |
| 382 // It should be fixed or an assertion should be placed. | 382 // It should be fixed or an assertion should be placed. |
| 383 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_SPDY_SERVER) { | 383 if (acceptor_->flip_handler_type_ == FLIP_HANDLER_SPDY_SERVER) { |
| 384 if (!memory_cache_->AssignFileData(filename, &mci)) { | 384 if (!memory_cache_->AssignFileData(filename, &mci)) { |
| 385 // error creating new stream. | 385 // error creating new stream. |
| 386 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending ErrorNotFound"; | 386 VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending ErrorNotFound"; |
| 387 SendErrorNotFound(stream_id); | 387 SendErrorNotFound(stream_id); |
| 388 } else { | 388 } else { |
| 389 AddToOutputOrder(mci); | 389 AddToOutputOrder(mci); |
| 390 } | 390 } |
| 391 } else { | 391 } else { |
| 392 AddToOutputOrder(mci); | 392 AddToOutputOrder(mci); |
| 393 } | 393 } |
| 394 } | 394 } |
| 395 | 395 |
| 396 void SpdySM::AddToOutputOrder(const MemCacheIter& mci) { | 396 void SpdySM::AddToOutputOrder(const MemCacheIter& mci) { |
| 397 client_output_ordering_.AddToOutputOrder(mci); | 397 client_output_ordering_.AddToOutputOrder(mci); |
| 398 } | 398 } |
| 399 | 399 |
| 400 void SpdySM::SendEOF(uint32 stream_id) { SendEOFImpl(stream_id); } | 400 void SpdySM::SendEOF(uint32_t stream_id) { |
| 401 SendEOFImpl(stream_id); |
| 402 } |
| 401 | 403 |
| 402 void SpdySM::SendErrorNotFound(uint32 stream_id) { | 404 void SpdySM::SendErrorNotFound(uint32_t stream_id) { |
| 403 SendErrorNotFoundImpl(stream_id); | 405 SendErrorNotFoundImpl(stream_id); |
| 404 } | 406 } |
| 405 | 407 |
| 406 size_t SpdySM::SendSynStream(uint32 stream_id, const BalsaHeaders& headers) { | 408 size_t SpdySM::SendSynStream(uint32_t stream_id, const BalsaHeaders& headers) { |
| 407 return SendSynStreamImpl(stream_id, headers); | 409 return SendSynStreamImpl(stream_id, headers); |
| 408 } | 410 } |
| 409 | 411 |
| 410 size_t SpdySM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) { | 412 size_t SpdySM::SendSynReply(uint32_t stream_id, const BalsaHeaders& headers) { |
| 411 return SendSynReplyImpl(stream_id, headers); | 413 return SendSynReplyImpl(stream_id, headers); |
| 412 } | 414 } |
| 413 | 415 |
| 414 void SpdySM::SendDataFrame(uint32 stream_id, | 416 void SpdySM::SendDataFrame(uint32_t stream_id, |
| 415 const char* data, | 417 const char* data, |
| 416 int64 len, | 418 int64_t len, |
| 417 uint32 flags, | 419 uint32_t flags, |
| 418 bool compress) { | 420 bool compress) { |
| 419 SpdyDataFlags spdy_flags = static_cast<SpdyDataFlags>(flags); | 421 SpdyDataFlags spdy_flags = static_cast<SpdyDataFlags>(flags); |
| 420 SendDataFrameImpl(stream_id, data, len, spdy_flags, compress); | 422 SendDataFrameImpl(stream_id, data, len, spdy_flags, compress); |
| 421 } | 423 } |
| 422 | 424 |
| 423 void SpdySM::SendEOFImpl(uint32 stream_id) { | 425 void SpdySM::SendEOFImpl(uint32_t stream_id) { |
| 424 SendDataFrame(stream_id, NULL, 0, DATA_FLAG_FIN, false); | 426 SendDataFrame(stream_id, NULL, 0, DATA_FLAG_FIN, false); |
| 425 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending EOF: " << stream_id; | 427 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending EOF: " << stream_id; |
| 426 KillStream(stream_id); | 428 KillStream(stream_id); |
| 427 stream_to_smif_.erase(stream_id); | 429 stream_to_smif_.erase(stream_id); |
| 428 } | 430 } |
| 429 | 431 |
| 430 void SpdySM::SendErrorNotFoundImpl(uint32 stream_id) { | 432 void SpdySM::SendErrorNotFoundImpl(uint32_t stream_id) { |
| 431 BalsaHeaders my_headers; | 433 BalsaHeaders my_headers; |
| 432 my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found"); | 434 my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found"); |
| 433 SendSynReplyImpl(stream_id, my_headers); | 435 SendSynReplyImpl(stream_id, my_headers); |
| 434 SendDataFrame(stream_id, "wtf?", 4, DATA_FLAG_FIN, false); | 436 SendDataFrame(stream_id, "wtf?", 4, DATA_FLAG_FIN, false); |
| 435 client_output_ordering_.RemoveStreamId(stream_id); | 437 client_output_ordering_.RemoveStreamId(stream_id); |
| 436 } | 438 } |
| 437 | 439 |
| 438 void SpdySM::KillStream(uint32 stream_id) { | 440 void SpdySM::KillStream(uint32_t stream_id) { |
| 439 client_output_ordering_.RemoveStreamId(stream_id); | 441 client_output_ordering_.RemoveStreamId(stream_id); |
| 440 } | 442 } |
| 441 | 443 |
| 442 void SpdySM::CopyHeaders(SpdyHeaderBlock& dest, const BalsaHeaders& headers) { | 444 void SpdySM::CopyHeaders(SpdyHeaderBlock& dest, const BalsaHeaders& headers) { |
| 443 for (BalsaHeaders::const_header_lines_iterator hi = | 445 for (BalsaHeaders::const_header_lines_iterator hi = |
| 444 headers.header_lines_begin(); | 446 headers.header_lines_begin(); |
| 445 hi != headers.header_lines_end(); | 447 hi != headers.header_lines_end(); |
| 446 ++hi) { | 448 ++hi) { |
| 447 // It is illegal to send SPDY headers with empty value or header | 449 // It is illegal to send SPDY headers with empty value or header |
| 448 // names. | 450 // names. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 459 dest[key] = (std::string(fhi->second.data(), fhi->second.size()) + "\0" + | 461 dest[key] = (std::string(fhi->second.data(), fhi->second.size()) + "\0" + |
| 460 std::string(hi->second.data(), hi->second.size())); | 462 std::string(hi->second.data(), hi->second.size())); |
| 461 } | 463 } |
| 462 } | 464 } |
| 463 | 465 |
| 464 // These headers have no value | 466 // These headers have no value |
| 465 dest.erase("X-Associated-Content"); // TODO(mbelshe): case-sensitive | 467 dest.erase("X-Associated-Content"); // TODO(mbelshe): case-sensitive |
| 466 dest.erase("X-Original-Url"); // TODO(mbelshe): case-sensitive | 468 dest.erase("X-Original-Url"); // TODO(mbelshe): case-sensitive |
| 467 } | 469 } |
| 468 | 470 |
| 469 size_t SpdySM::SendSynStreamImpl(uint32 stream_id, | 471 size_t SpdySM::SendSynStreamImpl(uint32_t stream_id, |
| 470 const BalsaHeaders& headers) { | 472 const BalsaHeaders& headers) { |
| 471 SpdyHeaderBlock block; | 473 SpdyHeaderBlock block; |
| 472 CopyHeaders(block, headers); | 474 CopyHeaders(block, headers); |
| 473 if (spdy_version() == SPDY2) { | 475 if (spdy_version() == SPDY2) { |
| 474 block["method"] = headers.request_method().as_string(); | 476 block["method"] = headers.request_method().as_string(); |
| 475 if (!headers.HasHeader("version")) | 477 if (!headers.HasHeader("version")) |
| 476 block["version"] = headers.request_version().as_string(); | 478 block["version"] = headers.request_version().as_string(); |
| 477 if (headers.HasHeader("X-Original-Url")) { | 479 if (headers.HasHeader("X-Original-Url")) { |
| 478 std::string original_url = | 480 std::string original_url = |
| 479 headers.GetHeader("X-Original-Url").as_string(); | 481 headers.GetHeader("X-Original-Url").as_string(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 502 SpdyFrame* fsrcf = buffered_spdy_framer_->CreateSynStream( | 504 SpdyFrame* fsrcf = buffered_spdy_framer_->CreateSynStream( |
| 503 stream_id, 0, 0, CONTROL_FLAG_NONE, &block); | 505 stream_id, 0, 0, CONTROL_FLAG_NONE, &block); |
| 504 size_t df_size = fsrcf->size(); | 506 size_t df_size = fsrcf->size(); |
| 505 EnqueueDataFrame(new SpdyFrameDataFrame(fsrcf)); | 507 EnqueueDataFrame(new SpdyFrameDataFrame(fsrcf)); |
| 506 | 508 |
| 507 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending SynStreamheader " | 509 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending SynStreamheader " |
| 508 << stream_id; | 510 << stream_id; |
| 509 return df_size; | 511 return df_size; |
| 510 } | 512 } |
| 511 | 513 |
| 512 size_t SpdySM::SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) { | 514 size_t SpdySM::SendSynReplyImpl(uint32_t stream_id, |
| 515 const BalsaHeaders& headers) { |
| 513 SpdyHeaderBlock block; | 516 SpdyHeaderBlock block; |
| 514 CopyHeaders(block, headers); | 517 CopyHeaders(block, headers); |
| 515 if (spdy_version() == SPDY2) { | 518 if (spdy_version() == SPDY2) { |
| 516 block["status"] = headers.response_code().as_string() + " " + | 519 block["status"] = headers.response_code().as_string() + " " + |
| 517 headers.response_reason_phrase().as_string(); | 520 headers.response_reason_phrase().as_string(); |
| 518 block["version"] = headers.response_version().as_string(); | 521 block["version"] = headers.response_version().as_string(); |
| 519 } else { | 522 } else { |
| 520 block[":status"] = headers.response_code().as_string() + " " + | 523 block[":status"] = headers.response_code().as_string() + " " + |
| 521 headers.response_reason_phrase().as_string(); | 524 headers.response_reason_phrase().as_string(); |
| 522 block[":version"] = headers.response_version().as_string(); | 525 block[":version"] = headers.response_version().as_string(); |
| 523 } | 526 } |
| 524 | 527 |
| 525 DCHECK(buffered_spdy_framer_); | 528 DCHECK(buffered_spdy_framer_); |
| 526 SpdyFrame* fsrcf = buffered_spdy_framer_->CreateSynReply( | 529 SpdyFrame* fsrcf = buffered_spdy_framer_->CreateSynReply( |
| 527 stream_id, CONTROL_FLAG_NONE, &block); | 530 stream_id, CONTROL_FLAG_NONE, &block); |
| 528 size_t df_size = fsrcf->size(); | 531 size_t df_size = fsrcf->size(); |
| 529 EnqueueDataFrame(new SpdyFrameDataFrame(fsrcf)); | 532 EnqueueDataFrame(new SpdyFrameDataFrame(fsrcf)); |
| 530 | 533 |
| 531 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending SynReplyheader " | 534 VLOG(2) << ACCEPTOR_CLIENT_IDENT << "SpdySM: Sending SynReplyheader " |
| 532 << stream_id; | 535 << stream_id; |
| 533 return df_size; | 536 return df_size; |
| 534 } | 537 } |
| 535 | 538 |
| 536 void SpdySM::SendDataFrameImpl(uint32 stream_id, | 539 void SpdySM::SendDataFrameImpl(uint32_t stream_id, |
| 537 const char* data, | 540 const char* data, |
| 538 int64 len, | 541 int64_t len, |
| 539 SpdyDataFlags flags, | 542 SpdyDataFlags flags, |
| 540 bool compress) { | 543 bool compress) { |
| 541 DCHECK(buffered_spdy_framer_); | 544 DCHECK(buffered_spdy_framer_); |
| 542 // TODO(mbelshe): We can't compress here - before going into the | 545 // TODO(mbelshe): We can't compress here - before going into the |
| 543 // priority queue. Compression needs to be done | 546 // priority queue. Compression needs to be done |
| 544 // with late binding. | 547 // with late binding. |
| 545 if (len == 0) { | 548 if (len == 0) { |
| 546 SpdyFrame* fdf = | 549 SpdyFrame* fdf = |
| 547 buffered_spdy_framer_->CreateDataFrame(stream_id, data, len, flags); | 550 buffered_spdy_framer_->CreateDataFrame(stream_id, data, len, flags); |
| 548 EnqueueDataFrame(new SpdyFrameDataFrame(fdf)); | 551 EnqueueDataFrame(new SpdyFrameDataFrame(fdf)); |
| 549 return; | 552 return; |
| 550 } | 553 } |
| 551 | 554 |
| 552 // Chop data frames into chunks so that one stream can't monopolize the | 555 // Chop data frames into chunks so that one stream can't monopolize the |
| 553 // output channel. | 556 // output channel. |
| 554 while (len > 0) { | 557 while (len > 0) { |
| 555 int64 size = std::min(len, static_cast<int64>(kSpdySegmentSize)); | 558 int64_t size = std::min(len, static_cast<int64_t>(kSpdySegmentSize)); |
| 556 SpdyDataFlags chunk_flags = flags; | 559 SpdyDataFlags chunk_flags = flags; |
| 557 | 560 |
| 558 // If we chunked this block, and the FIN flag was set, there is more | 561 // If we chunked this block, and the FIN flag was set, there is more |
| 559 // data coming. So, remove the flag. | 562 // data coming. So, remove the flag. |
| 560 if ((size < len) && (flags & DATA_FLAG_FIN)) | 563 if ((size < len) && (flags & DATA_FLAG_FIN)) |
| 561 chunk_flags = static_cast<SpdyDataFlags>(chunk_flags & ~DATA_FLAG_FIN); | 564 chunk_flags = static_cast<SpdyDataFlags>(chunk_flags & ~DATA_FLAG_FIN); |
| 562 | 565 |
| 563 SpdyFrame* fdf = buffered_spdy_framer_->CreateDataFrame( | 566 SpdyFrame* fdf = buffered_spdy_framer_->CreateDataFrame( |
| 564 stream_id, data, size, chunk_flags); | 567 stream_id, data, size, chunk_flags); |
| 565 EnqueueDataFrame(new SpdyFrameDataFrame(fdf)); | 568 EnqueueDataFrame(new SpdyFrameDataFrame(fdf)); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 } | 642 } |
| 640 } | 643 } |
| 641 | 644 |
| 642 void SpdySM::CreateFramer(SpdyMajorVersion spdy_version) { | 645 void SpdySM::CreateFramer(SpdyMajorVersion spdy_version) { |
| 643 DCHECK(!buffered_spdy_framer_); | 646 DCHECK(!buffered_spdy_framer_); |
| 644 buffered_spdy_framer_.reset(new BufferedSpdyFramer(spdy_version, true)); | 647 buffered_spdy_framer_.reset(new BufferedSpdyFramer(spdy_version, true)); |
| 645 buffered_spdy_framer_->set_visitor(this); | 648 buffered_spdy_framer_->set_visitor(this); |
| 646 } | 649 } |
| 647 | 650 |
| 648 } // namespace net | 651 } // namespace net |
| OLD | NEW |