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)
123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/gtest_prod_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/host_port_pair.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.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 SpdySession;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // RequestStream may only be called if |for_websockets| is false.
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // RequestWebSocketHandshakeStream may only be called if |for_websockets|
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // is true.
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpStreamFactoryImpl(HttpNetworkSession* session, bool for_websockets);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~HttpStreamFactoryImpl();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpStreamFactory interface
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual HttpStreamRequest* RequestStream(
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const HttpRequestInfo& info,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RequestPriority priority,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const SSLConfig& server_ssl_config,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const SSLConfig& proxy_ssl_config,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HttpStreamRequest::Delegate* delegate,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const BoundNetLog& net_log) OVERRIDE;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const HttpRequestInfo& info,
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      RequestPriority priority,
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const SSLConfig& server_ssl_config,
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const SSLConfig& proxy_ssl_config,
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      HttpStreamRequest::Delegate* delegate,
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      WebSocketHandshakeStreamBase::CreateHelper* create_helper,
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const BoundNetLog& net_log) OVERRIDE;
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PreconnectStreams(int num_streams,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const HttpRequestInfo& info,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 RequestPriority priority,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const SSLConfig& server_ssl_config,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const SSLConfig& proxy_ssl_config) OVERRIDE;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t num_orphaned_jobs() const { return orphaned_job_set_.size(); }
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(HttpStreamFactoryImplRequestTest, SetPriority);
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  class NET_EXPORT_PRIVATE Request;
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  class NET_EXPORT_PRIVATE Job;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::set<Request*> RequestSet;
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  typedef std::map<SpdySessionKey, RequestSet> SpdySessionRequestMap;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpStreamRequest* RequestStreamInternal(
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const HttpRequestInfo& info,
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      RequestPriority priority,
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const SSLConfig& server_ssl_config,
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const SSLConfig& proxy_ssl_config,
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      HttpStreamRequest::Delegate* delegate,
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      WebSocketHandshakeStreamBase::CreateHelper* create_helper,
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const BoundNetLog& net_log);
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AlternateProtocolInfo GetAlternateProtocolRequestFor(
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const GURL& original_url,
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GURL* alternate_url);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Detaches |job| from |request|.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OrphanJob(Job* job, const Request* request);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a SpdySession is ready. It will find appropriate Requests and
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fulfill them. |direct| indicates whether or not |spdy_session| uses a
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy.
89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void OnNewSpdySessionReady(const base::WeakPtr<SpdySession>& spdy_session,
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             bool direct,
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             const SSLConfig& used_ssl_config,
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             const ProxyInfo& used_proxy_info,
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             bool was_npn_negotiated,
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             NextProto protocol_negotiated,
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             bool using_spdy,
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             const BoundNetLog& net_log);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the Job detects that the endpoint indicated by the
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Alternate-Protocol does not work. Lets the factory update
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpAlternateProtocols with the failure and resets the SPDY session key.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnBrokenAlternateProtocol(const Job*, const HostPortPair& origin);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked when an orphaned Job finishes.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnOrphanedJobComplete(const Job* job);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked when the Job finishes preconnecting sockets.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnPreconnectsComplete(const Job* job);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the Preconnect completes. Used for testing.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnPreconnectsCompleteInternal() {}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpNetworkSession* const session_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All Requests are handed out to clients. By the time HttpStreamFactoryImpl
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is destroyed, all Requests should be deleted (which should remove them from
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |request_map_|. The Requests will delete the corresponding job.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<const Job*, Request*> request_map_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionRequestMap spdy_session_request_map_;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These jobs correspond to jobs orphaned by Requests and now owned by
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpStreamFactoryImpl. Since they are no longer tied to Requests, they will
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not be canceled when Requests are canceled. Therefore, in
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ~HttpStreamFactoryImpl, it is possible for some jobs to still exist in this
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // set. Leftover jobs will be deleted when the factory is destroyed.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<const Job*> orphaned_job_set_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These jobs correspond to preconnect requests and have no associated Request
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object. They're owned by HttpStreamFactoryImpl. Leftover jobs will be
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted when the factory is destroyed.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<const Job*> preconnect_job_set_;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const bool for_websockets_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImpl);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_HTTP_HTTP_STREAM_FACTORY_IMPL_H_
140