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 3 // found in the LICENSE file. 4 5 #include "net/http/http_pipelined_host_forced.h" 6 7 #include "base/values.h" 8 #include "net/http/http_pipelined_connection_impl.h" 9 #include "net/http/http_pipelined_stream.h" 10 #include "net/socket/buffered_write_stream_socket.h" 11 #include "net/socket/client_socket_handle.h" 12 13 namespace net { 14 15 HttpPipelinedHostForced::HttpPipelinedHostForced( 16 HttpPipelinedHost::Delegate* delegate, 17 const Key& key, 18 HttpPipelinedConnection::Factory* factory) 19 : delegate_(delegate), 20 key_(key), 21 factory_(factory) { 22 if (!factory) { 23 factory_.reset(new HttpPipelinedConnectionImpl::Factory()); 24 } 25 } 26 27 HttpPipelinedHostForced::~HttpPipelinedHostForced() { 28 CHECK(!pipeline_.get()); 29 } 30 31 HttpPipelinedStream* HttpPipelinedHostForced::CreateStreamOnNewPipeline( 32 ClientSocketHandle* connection, 33 const SSLConfig& used_ssl_config, 34 const ProxyInfo& used_proxy_info, 35 const BoundNetLog& net_log, 36 bool was_npn_negotiated, 37 NextProto protocol_negotiated) { 38 CHECK(!pipeline_.get()); 39 scoped_ptr<BufferedWriteStreamSocket> buffered_socket( 40 new BufferedWriteStreamSocket(connection->PassSocket())); 41 connection->SetSocket(buffered_socket.PassAs<StreamSocket>()); 42 pipeline_.reset(factory_->CreateNewPipeline( 43 connection, this, key_.origin(), used_ssl_config, used_proxy_info, 44 net_log, was_npn_negotiated, protocol_negotiated)); 45 return pipeline_->CreateNewStream(); 46 } 47 48 HttpPipelinedStream* HttpPipelinedHostForced::CreateStreamOnExistingPipeline() { 49 if (!pipeline_.get()) { 50 return NULL; 51 } 52 return pipeline_->CreateNewStream(); 53 } 54 55 bool HttpPipelinedHostForced::IsExistingPipelineAvailable() const { 56 return pipeline_.get() != NULL; 57 } 58 59 const HttpPipelinedHost::Key& HttpPipelinedHostForced::GetKey() const { 60 return key_; 61 } 62 63 void HttpPipelinedHostForced::OnPipelineEmpty( 64 HttpPipelinedConnection* pipeline) { 65 CHECK_EQ(pipeline_.get(), pipeline); 66 pipeline_.reset(); 67 delegate_->OnHostIdle(this); 68 // WARNING: We'll probably be deleted here. 69 } 70 71 void HttpPipelinedHostForced::OnPipelineHasCapacity( 72 HttpPipelinedConnection* pipeline) { 73 CHECK_EQ(pipeline_.get(), pipeline); 74 delegate_->OnHostHasAdditionalCapacity(this); 75 if (!pipeline->depth()) { 76 OnPipelineEmpty(pipeline); 77 // WARNING: We might be deleted here. 78 } 79 } 80 81 void HttpPipelinedHostForced::OnPipelineFeedback( 82 HttpPipelinedConnection* pipeline, 83 HttpPipelinedConnection::Feedback feedback) { 84 // We don't care. We always pipeline. 85 } 86 87 base::Value* HttpPipelinedHostForced::PipelineInfoToValue() const { 88 base::ListValue* list_value = new base::ListValue(); 89 if (pipeline_.get()) { 90 base::DictionaryValue* pipeline_dict = new base::DictionaryValue; 91 pipeline_dict->SetString("host", key_.origin().ToString()); 92 pipeline_dict->SetBoolean("forced", true); 93 pipeline_dict->SetInteger("depth", pipeline_->depth()); 94 pipeline_dict->SetInteger("capacity", 1000); 95 pipeline_dict->SetBoolean("usable", pipeline_->usable()); 96 pipeline_dict->SetBoolean("active", pipeline_->active()); 97 pipeline_dict->SetInteger("source_id", pipeline_->net_log().source().id); 98 list_value->Append(pipeline_dict); 99 } 100 return list_value; 101 } 102 103 } // namespace net 104