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