diff --git a/uppsrc/Core/Inet.h b/uppsrc/Core/Inet.h index c15af29bc..75660d6a0 100644 --- a/uppsrc/Core/Inet.h +++ b/uppsrc/Core/Inet.h @@ -677,9 +677,13 @@ class WebSocket { public: WebSocket& NonBlocking(bool b = true) { socket->Timeout(b ? 0 : Null); return *this; } - WebSocket& RequestHeaders(const String& s) { request_headers = s; return *this; } - String StandardHeaders(); + WebSocket& Headers(const String& h) { request_headers = h; return *this; } + WebSocket& ClearHeaders() { return Headers(Null); } + WebSocket& AddHeaders(const String& h) { request_headers.Cat(h); return *this; } + WebSocket& Header(const char *id, const String& data); + + String GetHeaders() { return request_headers; } bool IsBlocking() const { return IsNull(socket->GetTimeout()); } @@ -688,6 +692,8 @@ public: bool Accept(TcpSocket& listener_socket); bool Connect(const String& url); + bool Connect(const String& uri, const String& host, bool ssl, int port); + bool Connect(const String& uri, const String& host, bool ssl) { return Connect(uri, host, ssl, ssl ? 440 : 80); } void Do(); diff --git a/uppsrc/Core/WebSocket.cpp b/uppsrc/Core/WebSocket.cpp index e5fa8a978..eb6ff83a0 100644 --- a/uppsrc/Core/WebSocket.cpp +++ b/uppsrc/Core/WebSocket.cpp @@ -19,6 +19,17 @@ String WebSocket::FormatBlock(const String& s) WebSocket::WebSocket() { Clear(); + + static String request_headers_const = + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" + "Accept-Language: cs,en-US;q=0.7,en;q=0.3\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Extensions: permessage-deflate\r\n" + "Connection: keep-alive, Upgrade\r\n" + "Pragma: no-cache\r\n" + "Cache-Control: no-cache\r\n" + "Upgrade: websocket\r\n"; + request_headers = request_headers_const; } void WebSocket::Clear() @@ -54,15 +65,16 @@ bool WebSocket::Accept(TcpSocket& listen_socket) return true; } +WebSocket& WebSocket::Header(const char *id, const String& data) +{ + request_headers << id << ": " << data << "\r\n"; + return *this; +} + bool WebSocket::Connect(const String& url) { - Clear(); - - client = true; - - uri = url; const char *u = url; - ssl = memcmp(u, "wss", 3) == 0; + bool ssl = memcmp(u, "wss", 3) == 0; const char *t = u; while(*t && *t != '?') if(*t++ == '/' && *t == '/') { @@ -72,11 +84,24 @@ bool WebSocket::Connect(const String& url) t = u; while(*u && *u != ':' && *u != '/' && *u != '?') u++; - host = String(t, u); + String host = String(t, u); int port = ssl ? 443 : 80; if(*u == ':') port = ScanInt(u + 1, &u); + return Connect(url, host, ssl, port); +} + +bool WebSocket::Connect(const String& uri_, const String& host_, bool ssl_, int port) +{ + Clear(); + + client = true; + + uri = uri_; + host = host_; + ssl = ssl_; + if(socket->IsBlocking()) { if(!addrinfo.Execute(host, port)) { Error("Not found"); @@ -97,31 +122,18 @@ bool WebSocket::Connect(const String& url) return true; } -String WebSocket::StandardHeaders() -{ - String h; - for(int i = 0; i < 20; i++) - h.Cat(Random()); - return - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" - "Accept-Language: cs,en-US;q=0.7,en;q=0.3\r\n" - "Sec-WebSocket-Version: 13\r\n" - "Sec-WebSocket-Extensions: permessage-deflate\r\n" - "Sec-WebSocket-Key: " + Base64Encode(h) + "\r\n" - "Connection: keep-alive, Upgrade\r\n" - "Pragma: no-cache\r\n" - "Cache-Control: no-cache\r\n" - "Upgrade: websocket\r\n"; -} - void WebSocket::SendRequest() { LLOG("Sending connection request"); + String h; + for(int i = 0; i < 20; i++) + h.Cat(Random()); Out( // needs to be the first thing to sent after the connection is established "GET " + uri + " HTTP/1.1\r\n" "Host: " + host + "\r\n" + - Nvl(request_headers, StandardHeaders()) - + "\r\n" + "Sec-WebSocket-Key: " + Base64Encode(h) + "\r\n" + + request_headers + + "\r\n" ); opcode = HTTP_RESPONSE_HEADER; } diff --git a/uppsrc/Core/src.tpp/WebSocket_en-us.tpp b/uppsrc/Core/src.tpp/WebSocket_en-us.tpp index 4d98ca921..8f04cd455 100644 --- a/uppsrc/Core/src.tpp/WebSocket_en-us.tpp +++ b/uppsrc/Core/src.tpp/WebSocket_en-us.tpp @@ -22,17 +22,6 @@ topic "WebSocket"; ]_[* NonBlocking]([@(0.0.255) bool]_[*@3 b]_`=_[@(0.0.255) true])&] [s2;%% If [%-*@3 b] is true, activates non`-blocking mode. Default is blocking mode.&] -[s3; &] -[s4; &] -[s5;:Upp`:`:WebSocket`:`:RequestHeaders`(const Upp`:`:String`&`): [_^Upp`:`:WebSocket^ W -ebSocket][@(0.0.255) `&]_[* RequestHeaders]([@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `& -]_[*@3 s])&] -[s2;%% Overrides HTTP headers used with Connect.&] -[s3;%% &] -[s4; &] -[s5;:Upp`:`:WebSocket`:`:StandardHeaders`(`): [_^Upp`:`:String^ String]_[* StandardHeader -s]()&] -[s2;%% Returns standard HTTP headers to be used with Connect.&] [s3;%% &] [s4; &] [s5;:Upp`:`:WebSocket`:`:IsBlocking`(`)const: [@(0.0.255) bool]_[* IsBlocking]()_[@(0.0.255) c