Merge pull request #24 from donpillou/httpOrigin
Support for http origin header field
This commit is contained in:
+17
-10
@@ -69,7 +69,7 @@
|
|||||||
|
|
||||||
namespace { // private module-only namespace
|
namespace { // private module-only namespace
|
||||||
|
|
||||||
socket_t hostname_connect(std::string hostname, int port) {
|
socket_t hostname_connect(const std::string& hostname, int port) {
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
struct addrinfo *result;
|
struct addrinfo *result;
|
||||||
struct addrinfo *p;
|
struct addrinfo *p;
|
||||||
@@ -108,10 +108,10 @@ class _DummyWebSocket : public easywsclient::WebSocket
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void poll(int timeout) { }
|
void poll(int timeout) { }
|
||||||
void send(std::string message) { }
|
void send(const std::string& message) { }
|
||||||
void close() { }
|
void close() { }
|
||||||
void _dispatch(Callback & callable) { }
|
void _dispatch(Callback & callable) { }
|
||||||
readyStateValues getReadyState() { return CLOSED; }
|
readyStateValues getReadyState() const { return CLOSED; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ class _RealWebSocket : public easywsclient::WebSocket
|
|||||||
_RealWebSocket(socket_t sockfd, bool useMask) : sockfd(sockfd), readyState(OPEN), useMask(useMask) {
|
_RealWebSocket(socket_t sockfd, bool useMask) : sockfd(sockfd), readyState(OPEN), useMask(useMask) {
|
||||||
}
|
}
|
||||||
|
|
||||||
readyStateValues getReadyState() {
|
readyStateValues getReadyState() const {
|
||||||
return readyState;
|
return readyState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,7 +312,7 @@ class _RealWebSocket : public easywsclient::WebSocket
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void send(std::string message) {
|
void send(const std::string& message) {
|
||||||
// TODO:
|
// TODO:
|
||||||
// Masking key should (must) be derived from a high quality random
|
// Masking key should (must) be derived from a high quality random
|
||||||
// number generator, to mitigate attacks on non-WebSocket friendly
|
// number generator, to mitigate attacks on non-WebSocket friendly
|
||||||
@@ -381,7 +381,7 @@ class _RealWebSocket : public easywsclient::WebSocket
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
easywsclient::WebSocket::pointer from_url(std::string url, bool useMask) {
|
easywsclient::WebSocket::pointer from_url(const std::string& url, bool useMask, const std::string& origin) {
|
||||||
char host[128];
|
char host[128];
|
||||||
int port;
|
int port;
|
||||||
char path[128];
|
char path[128];
|
||||||
@@ -389,6 +389,10 @@ easywsclient::WebSocket::pointer from_url(std::string url, bool useMask) {
|
|||||||
fprintf(stderr, "ERROR: url size limit exceeded: %s\n", url.c_str());
|
fprintf(stderr, "ERROR: url size limit exceeded: %s\n", url.c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (origin.size() >= 200) {
|
||||||
|
fprintf(stderr, "ERROR: origin size limit exceeded: %s\n", origin.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (false) { }
|
if (false) { }
|
||||||
else if (sscanf(url.c_str(), "ws://%[^:/]:%d/%s", host, &port, path) == 3) {
|
else if (sscanf(url.c_str(), "ws://%[^:/]:%d/%s", host, &port, path) == 3) {
|
||||||
}
|
}
|
||||||
@@ -426,6 +430,9 @@ easywsclient::WebSocket::pointer from_url(std::string url, bool useMask) {
|
|||||||
}
|
}
|
||||||
snprintf(line, 256, "Upgrade: websocket\r\n"); ::send(sockfd, line, strlen(line), 0);
|
snprintf(line, 256, "Upgrade: websocket\r\n"); ::send(sockfd, line, strlen(line), 0);
|
||||||
snprintf(line, 256, "Connection: Upgrade\r\n"); ::send(sockfd, line, strlen(line), 0);
|
snprintf(line, 256, "Connection: Upgrade\r\n"); ::send(sockfd, line, strlen(line), 0);
|
||||||
|
if (!origin.empty()) {
|
||||||
|
snprintf(line, 256, "Origin: %s\r\n", origin.c_str()); ::send(sockfd, line, strlen(line), 0);
|
||||||
|
}
|
||||||
snprintf(line, 256, "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n"); ::send(sockfd, line, strlen(line), 0);
|
snprintf(line, 256, "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n"); ::send(sockfd, line, strlen(line), 0);
|
||||||
snprintf(line, 256, "Sec-WebSocket-Version: 13\r\n"); ::send(sockfd, line, strlen(line), 0);
|
snprintf(line, 256, "Sec-WebSocket-Version: 13\r\n"); ::send(sockfd, line, strlen(line), 0);
|
||||||
snprintf(line, 256, "\r\n"); ::send(sockfd, line, strlen(line), 0);
|
snprintf(line, 256, "\r\n"); ::send(sockfd, line, strlen(line), 0);
|
||||||
@@ -463,12 +470,12 @@ WebSocket::pointer WebSocket::create_dummy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WebSocket::pointer WebSocket::from_url(std::string url) {
|
WebSocket::pointer WebSocket::from_url(const std::string& url, const std::string& origin) {
|
||||||
return ::from_url(url, true);
|
return ::from_url(url, true, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocket::pointer WebSocket::from_url_no_mask(std::string url) {
|
WebSocket::pointer WebSocket::from_url_no_mask(const std::string& url, const std::string& origin) {
|
||||||
return ::from_url(url, false);
|
return ::from_url(url, false, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+9
-9
@@ -19,29 +19,29 @@ class WebSocket {
|
|||||||
|
|
||||||
// Factories:
|
// Factories:
|
||||||
static pointer create_dummy();
|
static pointer create_dummy();
|
||||||
static pointer from_url(std::string url);
|
static pointer from_url(const std::string& url, const std::string& origin = std::string());
|
||||||
static pointer from_url_no_mask(std::string url);
|
static pointer from_url_no_mask(const std::string& url, const std::string& origin = std::string());
|
||||||
|
|
||||||
// Interfaces:
|
// Interfaces:
|
||||||
virtual ~WebSocket() { }
|
virtual ~WebSocket() { }
|
||||||
virtual void poll(int timeout = 0) = 0; // timeout in milliseconds
|
virtual void poll(int timeout = 0) = 0; // timeout in milliseconds
|
||||||
virtual void send(std::string message) = 0;
|
virtual void send(const std::string& message) = 0;
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
virtual readyStateValues getReadyState() = 0;
|
virtual readyStateValues getReadyState() const = 0;
|
||||||
template<class Callable>
|
template<class Callable>
|
||||||
void dispatch(Callable callable) { // N.B. this is compatible with both C++11 lambdas, functors and C function pointers
|
void dispatch(Callable callable) { // N.B. this is compatible with both C++11 lambdas, functors and C function pointers
|
||||||
struct _Callback : public Callback {
|
struct _Callback : public Callback {
|
||||||
Callable & callable;
|
Callable& callable;
|
||||||
_Callback(Callable & callable) : callable(callable) { }
|
_Callback(Callable& callable) : callable(callable) { }
|
||||||
void operator()(const std::string & message) { callable(message); }
|
void operator()(const std::string& message) { callable(message); }
|
||||||
};
|
};
|
||||||
_Callback callback(callable);
|
_Callback callback(callable);
|
||||||
_dispatch(callback);
|
_dispatch(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct Callback { virtual void operator()(const std::string & message) = 0; };
|
struct Callback { virtual void operator()(const std::string& message) = 0; };
|
||||||
virtual void _dispatch(Callback & callable) = 0;
|
virtual void _dispatch(Callback& callable) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace easywsclient
|
} // namespace easywsclient
|
||||||
|
|||||||
Reference in New Issue
Block a user