1// Copyright (c) 2011 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#ifndef NET_WEBSOCKETS_WEBSOCKET_JOB_H_
6#define NET_WEBSOCKETS_WEBSOCKET_JOB_H_
7#pragma once
8
9#include <string>
10#include <vector>
11
12#include "base/string16.h"
13#include "net/base/address_list.h"
14#include "net/base/completion_callback.h"
15#include "net/socket_stream/socket_stream_job.h"
16
17class GURL;
18
19namespace net {
20
21class DrainableIOBuffer;
22class WebSocketFrameHandler;
23class WebSocketHandshakeRequestHandler;
24class WebSocketHandshakeResponseHandler;
25
26// WebSocket protocol specific job on SocketStream.
27// It captures WebSocket handshake message and handles cookie operations.
28// Chrome security policy doesn't allow renderer process (except dev tools)
29// see HttpOnly cookies, so it injects cookie header in handshake request and
30// strips set-cookie headers in handshake response.
31// TODO(ukai): refactor websocket.cc to use this.
32class WebSocketJob : public SocketStreamJob, public SocketStream::Delegate {
33 public:
34  // This is state of WebSocket, not SocketStream.
35  enum State {
36    INITIALIZED = -1,
37    CONNECTING = 0,
38    OPEN = 1,
39    CLOSING = 2,
40    CLOSED = 3,
41  };
42
43  explicit WebSocketJob(SocketStream::Delegate* delegate);
44
45  static void EnsureInit();
46
47  State state() const { return state_; }
48  virtual void Connect();
49  virtual bool SendData(const char* data, int len);
50  virtual void Close();
51  virtual void RestartWithAuth(
52      const string16& username,
53      const string16& password);
54  virtual void DetachDelegate();
55
56  // SocketStream::Delegate methods.
57  virtual int OnStartOpenConnection(
58      SocketStream* socket, CompletionCallback* callback);
59  virtual void OnConnected(
60      SocketStream* socket, int max_pending_send_allowed);
61  virtual void OnSentData(
62      SocketStream* socket, int amount_sent);
63  virtual void OnReceivedData(
64      SocketStream* socket, const char* data, int len);
65  virtual void OnClose(SocketStream* socket);
66  virtual void OnAuthRequired(
67      SocketStream* socket, AuthChallengeInfo* auth_info);
68  virtual void OnError(
69      const SocketStream* socket, int error);
70
71 private:
72  friend class WebSocketThrottle;
73  friend class WebSocketJobTest;
74  virtual ~WebSocketJob();
75
76  bool SendHandshakeRequest(const char* data, int len);
77  void AddCookieHeaderAndSend();
78  void OnCanGetCookiesCompleted(int policy);
79
80  void OnSentHandshakeRequest(SocketStream* socket, int amount_sent);
81  void OnReceivedHandshakeResponse(
82      SocketStream* socket, const char* data, int len);
83  void SaveCookiesAndNotifyHeaderComplete();
84  void SaveNextCookie();
85  void OnCanSetCookieCompleted(int policy);
86
87  GURL GetURLForCookies() const;
88
89  const AddressList& address_list() const;
90  void SetWaiting();
91  bool IsWaiting() const;
92  void Wakeup();
93  void DoCallback();
94
95  void SendPending();
96
97  SocketStream::Delegate* delegate_;
98  State state_;
99  bool waiting_;
100  AddressList addresses_;
101  CompletionCallback* callback_;  // for throttling.
102
103  scoped_ptr<WebSocketHandshakeRequestHandler> handshake_request_;
104  scoped_ptr<WebSocketHandshakeResponseHandler> handshake_response_;
105
106  size_t handshake_request_sent_;
107
108  std::vector<std::string> response_cookies_;
109  size_t response_cookies_save_index_;
110
111  scoped_ptr<WebSocketFrameHandler> send_frame_handler_;
112  scoped_refptr<DrainableIOBuffer> current_buffer_;
113  scoped_ptr<WebSocketFrameHandler> receive_frame_handler_;
114
115  DISALLOW_COPY_AND_ASSIGN(WebSocketJob);
116};
117
118}  // namespace
119
120#endif  // NET_WEBSOCKETS_WEBSOCKET_JOB_H_
121