SocketStreamHandle.cpp [plain text]
#include "config.h"
#include "SocketStreamHandle.h"
#if ENABLE(WEB_SOCKETS)
#include "Logging.h"
#include "NotImplemented.h"
#include "SocketStreamHandleClient.h"
#include "WebData.h"
#include "WebKit.h"
#include "WebKitClient.h"
#include "WebSocketStreamHandle.h"
#include "WebSocketStreamHandleClient.h"
#include "WebURL.h"
#include <wtf/PassOwnPtr.h>
using namespace WebKit;
namespace WebCore {
class SocketStreamHandleInternal : public WebSocketStreamHandleClient {
public:
static PassOwnPtr<SocketStreamHandleInternal> create(SocketStreamHandle* handle)
{
return new SocketStreamHandleInternal(handle);
}
virtual ~SocketStreamHandleInternal();
void connect(const KURL&);
int send(const char*, int);
void close();
virtual void didOpenStream(WebSocketStreamHandle*, int);
virtual void didSendData(WebSocketStreamHandle*, int);
virtual void didReceiveData(WebSocketStreamHandle*, const WebData&);
virtual void didClose(WebSocketStreamHandle*);
virtual void didFail(WebSocketStreamHandle*, const WebSocketStreamError&);
private:
explicit SocketStreamHandleInternal(SocketStreamHandle*);
SocketStreamHandle* m_handle;
OwnPtr<WebSocketStreamHandle> m_socket;
int m_maxPendingSendAllowed;
int m_pendingAmountSent;
};
SocketStreamHandleInternal::SocketStreamHandleInternal(SocketStreamHandle* handle)
: m_handle(handle)
, m_maxPendingSendAllowed(0)
, m_pendingAmountSent(0)
{
}
SocketStreamHandleInternal::~SocketStreamHandleInternal()
{
m_handle = 0;
}
void SocketStreamHandleInternal::connect(const KURL& url)
{
m_socket.set(webKitClient()->createSocketStreamHandle());
LOG(Network, "connect");
ASSERT(m_socket.get());
m_socket->connect(url, this);
}
int SocketStreamHandleInternal::send(const char* data, int len)
{
LOG(Network, "send len=%d", len);
ASSERT(m_socket.get());
if (m_pendingAmountSent + len >= m_maxPendingSendAllowed)
len = m_maxPendingSendAllowed - m_pendingAmountSent - 1;
if (len <= 0)
return len;
WebData webdata(data, len);
if (m_socket->send(webdata)) {
m_pendingAmountSent += len;
LOG(Network, "sent");
return len;
}
LOG(Network, "busy. buffering");
return 0;
}
void SocketStreamHandleInternal::close()
{
LOG(Network, "close");
m_socket->close();
}
void SocketStreamHandleInternal::didOpenStream(WebSocketStreamHandle* socketHandle, int maxPendingSendAllowed)
{
LOG(Network, "SocketStreamHandleInternal::didOpen %d",
maxPendingSendAllowed);
ASSERT(maxPendingSendAllowed > 0);
if (m_handle && m_socket.get()) {
ASSERT(socketHandle == m_socket.get());
m_maxPendingSendAllowed = maxPendingSendAllowed;
m_handle->m_state = SocketStreamHandleBase::Open;
if (m_handle->m_client) {
m_handle->m_client->didOpen(m_handle);
return;
}
}
LOG(Network, "no m_handle or m_socket?");
}
void SocketStreamHandleInternal::didSendData(WebSocketStreamHandle* socketHandle, int amountSent)
{
LOG(Network, "SocketStreamHandleInternal::didSendData %d", amountSent);
ASSERT(amountSent > 0);
if (m_handle && m_socket.get()) {
ASSERT(socketHandle == m_socket.get());
m_pendingAmountSent -= amountSent;
ASSERT(m_pendingAmountSent >= 0);
m_handle->sendPendingData();
}
}
void SocketStreamHandleInternal::didReceiveData(WebSocketStreamHandle* socketHandle, const WebData& data)
{
LOG(Network, "didReceiveData");
if (m_handle && m_socket.get()) {
ASSERT(socketHandle == m_socket.get());
if (m_handle->m_client)
m_handle->m_client->didReceiveData(m_handle, data.data(), data.size());
}
}
void SocketStreamHandleInternal::didClose(WebSocketStreamHandle* socketHandle)
{
LOG(Network, "didClose");
if (m_handle && m_socket.get()) {
ASSERT(socketHandle == m_socket.get());
m_socket.clear();
SocketStreamHandle* h = m_handle;
m_handle = 0;
if (h->m_client)
h->m_client->didClose(h);
}
}
void SocketStreamHandleInternal::didFail(WebSocketStreamHandle* socketHandle, const WebSocketStreamError& err)
{
LOG(Network, "didFail");
if (m_handle && m_socket.get()) {
ASSERT(socketHandle == m_socket.get());
m_socket.clear();
SocketStreamHandle* h = m_handle;
m_handle = 0;
if (h->m_client)
h->m_client->didClose(h); }
}
SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client)
: SocketStreamHandleBase(url, client)
{
m_internal = SocketStreamHandleInternal::create(this);
m_internal->connect(m_url);
}
SocketStreamHandle::~SocketStreamHandle()
{
setClient(0);
m_internal.clear();
}
int SocketStreamHandle::platformSend(const char* buf, int len)
{
if (!m_internal.get())
return 0;
return m_internal->send(buf, len);
}
void SocketStreamHandle::platformClose()
{
if (m_internal.get())
m_internal->close();
}
void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge)
{
if (m_client)
m_client->didReceiveAuthenticationChallenge(this, challenge);
}
void SocketStreamHandle::receivedCredential(const AuthenticationChallenge& challenge, const Credential& credential)
{
notImplemented();
}
void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& challenge)
{
notImplemented();
}
}
#endif // ENABLE(WEB_SOCKETS)