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_pool.h" 6 7 #include "base/logging.h" 8 #include "base/stl_util.h" 9 #include "base/values.h" 10 #include "net/http/http_pipelined_host_capability.h" 11 #include "net/http/http_pipelined_host_forced.h" 12 #include "net/http/http_pipelined_host_impl.h" 13 #include "net/http/http_server_properties.h" 14 15 namespace net { 16 17 class HttpPipelinedHostImplFactory : public HttpPipelinedHost::Factory { 18 public: 19 virtual HttpPipelinedHost* CreateNewHost( 20 HttpPipelinedHost::Delegate* delegate, 21 const HttpPipelinedHost::Key& key, 22 HttpPipelinedConnection::Factory* factory, 23 HttpPipelinedHostCapability capability, 24 bool force_pipelining) OVERRIDE { 25 if (force_pipelining) { 26 return new HttpPipelinedHostForced(delegate, key, factory); 27 } else { 28 return new HttpPipelinedHostImpl(delegate, key, factory, capability); 29 } 30 } 31 }; 32 33 HttpPipelinedHostPool::HttpPipelinedHostPool( 34 Delegate* delegate, 35 HttpPipelinedHost::Factory* factory, 36 const base::WeakPtr<HttpServerProperties>& http_server_properties, 37 bool force_pipelining) 38 : delegate_(delegate), 39 factory_(factory), 40 http_server_properties_(http_server_properties), 41 force_pipelining_(force_pipelining) { 42 if (!factory) { 43 factory_.reset(new HttpPipelinedHostImplFactory); 44 } 45 } 46 47 HttpPipelinedHostPool::~HttpPipelinedHostPool() { 48 CHECK(host_map_.empty()); 49 } 50 51 bool HttpPipelinedHostPool::IsKeyEligibleForPipelining( 52 const HttpPipelinedHost::Key& key) { 53 HttpPipelinedHostCapability capability = 54 http_server_properties_->GetPipelineCapability(key.origin()); 55 return capability != PIPELINE_INCAPABLE; 56 } 57 58 HttpPipelinedStream* HttpPipelinedHostPool::CreateStreamOnNewPipeline( 59 const HttpPipelinedHost::Key& key, 60 ClientSocketHandle* connection, 61 const SSLConfig& used_ssl_config, 62 const ProxyInfo& used_proxy_info, 63 const BoundNetLog& net_log, 64 bool was_npn_negotiated, 65 NextProto protocol_negotiated) { 66 HttpPipelinedHost* host = GetPipelinedHost(key, true); 67 if (!host) { 68 return NULL; 69 } 70 return host->CreateStreamOnNewPipeline(connection, used_ssl_config, 71 used_proxy_info, net_log, 72 was_npn_negotiated, 73 protocol_negotiated); 74 } 75 76 HttpPipelinedStream* HttpPipelinedHostPool::CreateStreamOnExistingPipeline( 77 const HttpPipelinedHost::Key& key) { 78 HttpPipelinedHost* host = GetPipelinedHost(key, false); 79 if (!host) { 80 return NULL; 81 } 82 return host->CreateStreamOnExistingPipeline(); 83 } 84 85 bool HttpPipelinedHostPool::IsExistingPipelineAvailableForKey( 86 const HttpPipelinedHost::Key& key) { 87 HttpPipelinedHost* host = GetPipelinedHost(key, false); 88 if (!host) { 89 return false; 90 } 91 return host->IsExistingPipelineAvailable(); 92 } 93 94 HttpPipelinedHost* HttpPipelinedHostPool::GetPipelinedHost( 95 const HttpPipelinedHost::Key& key, bool create_if_not_found) { 96 HostMap::iterator host_it = host_map_.find(key); 97 if (host_it != host_map_.end()) { 98 CHECK(host_it->second); 99 return host_it->second; 100 } else if (!create_if_not_found) { 101 return NULL; 102 } 103 104 HttpPipelinedHostCapability capability = 105 http_server_properties_->GetPipelineCapability(key.origin()); 106 if (capability == PIPELINE_INCAPABLE) { 107 return NULL; 108 } 109 110 HttpPipelinedHost* host = factory_->CreateNewHost( 111 this, key, NULL, capability, force_pipelining_); 112 host_map_[key] = host; 113 return host; 114 } 115 116 void HttpPipelinedHostPool::OnHostIdle(HttpPipelinedHost* host) { 117 const HttpPipelinedHost::Key& key = host->GetKey(); 118 CHECK(ContainsKey(host_map_, key)); 119 host_map_.erase(key); 120 delete host; 121 } 122 123 void HttpPipelinedHostPool::OnHostHasAdditionalCapacity( 124 HttpPipelinedHost* host) { 125 delegate_->OnHttpPipelinedHostHasAdditionalCapacity(host); 126 } 127 128 void HttpPipelinedHostPool::OnHostDeterminedCapability( 129 HttpPipelinedHost* host, 130 HttpPipelinedHostCapability capability) { 131 http_server_properties_->SetPipelineCapability(host->GetKey().origin(), 132 capability); 133 } 134 135 base::Value* HttpPipelinedHostPool::PipelineInfoToValue() const { 136 base::ListValue* list = new base::ListValue(); 137 for (HostMap::const_iterator it = host_map_.begin(); 138 it != host_map_.end(); ++it) { 139 base::Value* value = it->second->PipelineInfoToValue(); 140 list->Append(value); 141 } 142 return list; 143 } 144 145 } // namespace net 146