14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifndef CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_DISPATCHER_HOST_H_
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#define CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_DISPATCHER_HOST_H_
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string>
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <vector>
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/basictypes.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/callback.h"
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/compiler_specific.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/containers/hash_tables.h"
158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/common/content_export.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/common/websocket.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/browser_message_filter.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace net {
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class URLRequestContext;
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace net
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace content {
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct WebSocketHandshakeRequest;
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct WebSocketHandshakeResponse;
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class WebSocketHost;
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Creates a WebSocketHost object for each WebSocket channel, and dispatches
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// WebSocketMsg_* messages sent from renderer to the appropriate WebSocketHost.
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class CONTENT_EXPORT WebSocketDispatcherHost : public BrowserMessageFilter {
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  typedef base::Callback<net::URLRequestContext*()> GetRequestContextCallback;
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Given a routing_id, WebSocketHostFactory returns a new instance of
368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // WebSocketHost or its subclass.
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef base::Callback<WebSocketHost*(int)> WebSocketHostFactory;  // NOLINT
388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Return value for methods that may delete the WebSocketHost. This enum is
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // binary-compatible with net::WebSocketEventInterface::ChannelState, to make
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // conversion cheap. By using a separate enum including net/ header files can
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // be avoided.
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  enum WebSocketHostState {
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    WEBSOCKET_HOST_ALIVE,
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    WEBSOCKET_HOST_DELETED
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  };
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  WebSocketDispatcherHost(
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      int process_id,
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const GetRequestContextCallback& get_context_callback);
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // For testing. Specify a factory method that creates mock version of
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // WebSocketHost.
54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  WebSocketDispatcherHost(int process_id,
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                          const GetRequestContextCallback& get_context_callback,
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                          const WebSocketHostFactory& websocket_host_factory);
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // BrowserMessageFilter:
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // The following methods are used by WebSocketHost::EventInterface to send
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // IPCs from the browser to the renderer or child process. Any of them may
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // return WEBSOCKET_HOST_DELETED and delete the WebSocketHost on failure,
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // leading to the WebSocketChannel and EventInterface also being deleted.
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Sends a WebSocketMsg_AddChannelResponse IPC, and then deletes and
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // unregisters the WebSocketHost if |fail| is true.
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WebSocketHostState SendAddChannelResponse(
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      int routing_id,
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      bool fail,
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      const std::string& selected_protocol,
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      const std::string& extensions) WARN_UNUSED_RESULT;
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Sends a WebSocketMsg_SendFrame IPC.
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WebSocketHostState SendFrame(int routing_id,
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                               bool fin,
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                               WebSocketMessageType type,
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                               const std::vector<char>& data);
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Sends a WebSocketMsg_FlowControl IPC.
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WebSocketHostState SendFlowControl(int routing_id,
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                     int64 quota) WARN_UNUSED_RESULT;
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Sends a WebSocketMsg_NotifyClosing IPC
8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  WebSocketHostState NotifyClosingHandshake(int routing_id) WARN_UNUSED_RESULT;
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Sends a WebSocketMsg_NotifyStartOpeningHandshake IPC.
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  WebSocketHostState NotifyStartOpeningHandshake(
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      int routing_id,
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const WebSocketHandshakeRequest& request) WARN_UNUSED_RESULT;
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Sends a WebSocketMsg_NotifyFinishOpeningHandshake IPC.
9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  WebSocketHostState NotifyFinishOpeningHandshake(
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      int routing_id,
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const WebSocketHandshakeResponse& response) WARN_UNUSED_RESULT;
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Sends a WebSocketMsg_NotifyFailure IPC and deletes and unregisters the
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // channel.
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WebSocketHostState NotifyFailure(
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int routing_id,
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const std::string& message) WARN_UNUSED_RESULT;
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Sends a WebSocketMsg_DropChannel IPC and deletes and unregisters the
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // channel.
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WebSocketHostState DoDropChannel(
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      int routing_id,
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool was_clean,
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      uint16 code,
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      const std::string& reason) WARN_UNUSED_RESULT;
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Returns whether the associated renderer process can read raw cookies.
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool CanReadRawCookies() const;
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int render_process_id() const { return process_id_; }
11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  typedef base::hash_map<int, WebSocketHost*> WebSocketHostTable;
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ~WebSocketDispatcherHost();
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  WebSocketHost* CreateWebSocketHost(int routing_id);
1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Looks up a WebSocketHost object by |routing_id|. Returns the object if one
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // is found, or NULL otherwise.
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebSocketHost* GetHost(int routing_id) const;
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Sends the passed in IPC::Message via the BrowserMessageFilter::Send()
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // method. If sending the IPC fails, assumes that this connection is no
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // longer useable, calls DeleteWebSocketHost(), and returns
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // WEBSOCKET_HOST_DELETED. The behaviour is the same for all message types.
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WebSocketHostState SendOrDrop(IPC::Message* message) WARN_UNUSED_RESULT;
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Deletes the WebSocketHost object associated with the given |routing_id| and
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // removes it from the |hosts_| table.
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void DeleteWebSocketHost(int routing_id);
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Table of WebSocketHost objects, owned by this object, indexed by
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // routing_id.
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebSocketHostTable hosts_;
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // The the process ID of the associated renderer process.
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const int process_id_;
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A callback which returns the appropriate net::URLRequestContext for us to
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // use.
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetRequestContextCallback get_context_callback_;
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  WebSocketHostFactory websocket_host_factory_;
1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebSocketDispatcherHost);
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace content
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_DISPATCHER_HOST_H_
156