Core: WebSocket improvements

git-svn-id: svn://ultimatepp.org/upp/trunk@11817 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2018-03-03 09:18:48 +00:00
parent ce4590cbfe
commit 4f555f9b80
3 changed files with 46 additions and 39 deletions

View file

@ -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();

View file

@ -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;
}

View file

@ -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