15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_HTTP_HTTP_STREAM_FACTORY_IMPL_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_HTTP_HTTP_STREAM_FACTORY_IMPL_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_port_pair.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_pipelined_host_pool.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream_factory.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_server.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket.h"
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/spdy/spdy_session_key.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HttpNetworkSession;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HttpPipelinedHost;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdySession;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE HttpStreamFactoryImpl :
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public HttpStreamFactory,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public HttpPipelinedHostPool::Delegate {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // RequestStream may only be called if |for_websockets| is false.
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // RequestWebSocketStream may only be called if |for_websockets| is true.
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpStreamFactoryImpl(HttpNetworkSession* session, bool for_websockets);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~HttpStreamFactoryImpl();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpStreamFactory interface
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual HttpStreamRequest* RequestStream(
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const HttpRequestInfo& info,
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RequestPriority priority,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const SSLConfig& server_ssl_config,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const SSLConfig& proxy_ssl_config,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HttpStreamRequest::Delegate* delegate,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const BoundNetLog& net_log) OVERRIDE;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual HttpStreamRequest* RequestWebSocketStream(
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const HttpRequestInfo& info,
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      RequestPriority priority,
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const SSLConfig& server_ssl_config,
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const SSLConfig& proxy_ssl_config,
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      HttpStreamRequest::Delegate* delegate,
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WebSocketStreamBase::Factory* factory,
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const BoundNetLog& net_log) OVERRIDE;
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PreconnectStreams(int num_streams,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const HttpRequestInfo& info,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 RequestPriority priority,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const SSLConfig& server_ssl_config,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const SSLConfig& proxy_ssl_config) OVERRIDE;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::Value* PipelineInfoToValue() const OVERRIDE;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpPipelinedHostPool::Delegate interface
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnHttpPipelinedHostHasAdditionalCapacity(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HttpPipelinedHost* host) OVERRIDE;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t num_orphaned_jobs() const { return orphaned_job_set_.size(); }
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Request;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Job;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::set<Request*> RequestSet;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<Request*> RequestVector;
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  typedef std::map<SpdySessionKey, RequestSet> SpdySessionRequestMap;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<HttpPipelinedHost::Key,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   RequestVector> HttpPipeliningRequestMap;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpStreamRequest* RequestStreamInternal(
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const HttpRequestInfo& info,
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      RequestPriority priority,
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const SSLConfig& server_ssl_config,
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const SSLConfig& proxy_ssl_config,
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      HttpStreamRequest::Delegate* delegate,
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WebSocketStreamBase::Factory* factory,
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const BoundNetLog& net_log);
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PortAlternateProtocolPair GetAlternateProtocolRequestFor(
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const GURL& original_url,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL* alternate_url) const;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Detaches |job| from |request|.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OrphanJob(Job* job, const Request* request);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a SpdySession is ready. It will find appropriate Requests and
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fulfill them. |direct| indicates whether or not |spdy_session| uses a
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy.
97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void OnNewSpdySessionReady(const base::WeakPtr<SpdySession>& spdy_session,
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             bool direct,
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             const SSLConfig& used_ssl_config,
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             const ProxyInfo& used_proxy_info,
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             bool was_npn_negotiated,
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             NextProto protocol_negotiated,
103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             bool using_spdy,
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             const BoundNetLog& net_log);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the Job detects that the endpoint indicated by the
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Alternate-Protocol does not work. Lets the factory update
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpAlternateProtocols with the failure and resets the SPDY session key.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnBrokenAlternateProtocol(const Job*, const HostPortPair& origin);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked when an orphaned Job finishes.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnOrphanedJobComplete(const Job* job);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked when the Job finishes preconnecting sockets.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnPreconnectsComplete(const Job* job);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the Preconnect completes. Used for testing.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnPreconnectsCompleteInternal() {}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AbortPipelinedRequestsWithKey(const Job* job,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const HttpPipelinedHost::Key& key,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int status,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const SSLConfig& used_ssl_config);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpNetworkSession* const session_;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All Requests are handed out to clients. By the time HttpStreamFactoryImpl
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is destroyed, all Requests should be deleted (which should remove them from
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |request_map_|. The Requests will delete the corresponding job.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<const Job*, Request*> request_map_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionRequestMap spdy_session_request_map_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpPipeliningRequestMap http_pipelining_request_map_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpPipelinedHostPool http_pipelined_host_pool_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These jobs correspond to jobs orphaned by Requests and now owned by
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpStreamFactoryImpl. Since they are no longer tied to Requests, they will
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not be canceled when Requests are canceled. Therefore, in
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ~HttpStreamFactoryImpl, it is possible for some jobs to still exist in this
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // set. Leftover jobs will be deleted when the factory is destroyed.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<const Job*> orphaned_job_set_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These jobs correspond to preconnect requests and have no associated Request
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object. They're owned by HttpStreamFactoryImpl. Leftover jobs will be
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted when the factory is destroyed.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<const Job*> preconnect_job_set_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const bool for_websockets_;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImpl);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_HTTP_HTTP_STREAM_FACTORY_IMPL_H_
156