1231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block/*
2231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2009 Google Inc.  All rights reserved.
3231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *
4231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Redistribution and use in source and binary forms, with or without
5231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * modification, are permitted provided that the following conditions are
6231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * met:
7231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *
8231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     * Redistributions of source code must retain the above copyright
9231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * notice, this list of conditions and the following disclaimer.
10231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     * Redistributions in binary form must reproduce the above
11231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * copyright notice, this list of conditions and the following disclaimer
12231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * in the documentation and/or other materials provided with the
13231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * distribution.
14231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     * Neither the name of Google Inc. nor the names of its
15231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * contributors may be used to endorse or promote products derived from
16231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * this software without specific prior written permission.
17231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *
18231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block */
30231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#ifndef WebSocketChannel_h
32231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#define WebSocketChannel_h
33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(WEB_SOCKETS)
35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "SocketStreamHandleClient.h"
37d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "ThreadableWebSocketChannel.h"
386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include "Timer.h"
39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "WebSocketHandshake.h"
40dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include <wtf/Forward.h>
41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/RefCounted.h>
426c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include <wtf/Vector.h>
43231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocknamespace WebCore {
45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    class ScriptExecutionContext;
47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    class SocketStreamHandle;
48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    class SocketStreamError;
49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    class WebSocketChannelClient;
50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
51d0825bca7fe65beaee391d30da42e937db621564Steve Block    class WebSocketChannel : public RefCounted<WebSocketChannel>, public SocketStreamHandleClient, public ThreadableWebSocketChannel {
52ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        WTF_MAKE_FAST_ALLOCATED;
53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    public:
54cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        static PassRefPtr<WebSocketChannel> create(ScriptExecutionContext* context, WebSocketChannelClient* client, const KURL& url, const String& protocol) { return adoptRef(new WebSocketChannel(context, client, url, protocol)); }
55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        virtual ~WebSocketChannel();
56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
57d0825bca7fe65beaee391d30da42e937db621564Steve Block        virtual void connect();
58d0825bca7fe65beaee391d30da42e937db621564Steve Block        virtual bool send(const String& message);
59d0825bca7fe65beaee391d30da42e937db621564Steve Block        virtual unsigned long bufferedAmount() const;
60d0825bca7fe65beaee391d30da42e937db621564Steve Block        virtual void close();
61d0825bca7fe65beaee391d30da42e937db621564Steve Block        virtual void disconnect(); // Will suppress didClose().
62231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
636c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        virtual void suspend();
646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        virtual void resume();
656c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
66231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        virtual void didOpen(SocketStreamHandle*);
67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        virtual void didClose(SocketStreamHandle*);
68231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        virtual void didReceiveData(SocketStreamHandle*, const char*, int);
69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        virtual void didFail(SocketStreamHandle*, const SocketStreamError&);
70643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        virtual void didReceiveAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&);
71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        virtual void didCancelAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&);
72231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
73d0825bca7fe65beaee391d30da42e937db621564Steve Block        using RefCounted<WebSocketChannel>::ref;
74d0825bca7fe65beaee391d30da42e937db621564Steve Block        using RefCounted<WebSocketChannel>::deref;
75d0825bca7fe65beaee391d30da42e937db621564Steve Block
76d0825bca7fe65beaee391d30da42e937db621564Steve Block    protected:
77d0825bca7fe65beaee391d30da42e937db621564Steve Block        virtual void refThreadableWebSocketChannel() { ref(); }
78d0825bca7fe65beaee391d30da42e937db621564Steve Block        virtual void derefThreadableWebSocketChannel() { deref(); }
79d0825bca7fe65beaee391d30da42e937db621564Steve Block
80231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    private:
81d0825bca7fe65beaee391d30da42e937db621564Steve Block        WebSocketChannel(ScriptExecutionContext*, WebSocketChannelClient*, const KURL&, const String& protocol);
82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
83f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        bool appendToBuffer(const char* data, size_t len);
84f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void skipBuffer(size_t len);
856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        bool processBuffer();
8606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        void resumeTimerFired(Timer<WebSocketChannel>* timer);
87231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
88231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ScriptExecutionContext* m_context;
89231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        WebSocketChannelClient* m_client;
90231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        WebSocketHandshake m_handshake;
91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        RefPtr<SocketStreamHandle> m_handle;
92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        char* m_buffer;
93f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        size_t m_bufferSize;
946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
9506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        Timer<WebSocketChannel> m_resumeTimer;
966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        bool m_suspended;
976c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        bool m_closed;
98f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        bool m_shouldDiscardReceivedData;
996c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        unsigned long m_unhandledBufferedAmount;
10068513a70bcd92384395513322f1b801e7bf9c729Steve Block
101e14391e94c850b8bd03680c23b38978db68687a8John Reck        unsigned long m_identifier; // m_identifier == 0 means that we could not obtain a valid identifier.
102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    };
103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
104d0825bca7fe65beaee391d30da42e937db621564Steve Block} // namespace WebCore
105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
106d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif // ENABLE(WEB_SOCKETS)
107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
108d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif // WebSocketChannel_h
109