Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ MT-multithreading and servers » [SOLVED] Discord bot 404 error using WebSocket, any ideas?
[SOLVED] Discord bot 404 error using WebSocket, any ideas? [message #49885] Mon, 28 May 2018 23:32 Go to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 64
Registered: June 2011
Member
HttpRequest is passed a bot token and if it authenticates correctly it passes back the address of a WebSocket. This part works. The problem is when I try to connect to the WebSocket it refuses to upgrade and returns a 404. This bot token works so you should be able to test it before I request a new one. I have successfully done this with curl and others. I don't know if it's an issue with the WebSocket headers, if a specific order is required, etc. Any advice would be greatly appreciated.

Test code:

#include <Core/Core.h>

using namespace Upp;

CONSOLE_APP_MAIN
{
	StdLogSetup(LOG_FILE|LOG_COUT);
	
	HttpRequest::Trace();
	WebSocket::Trace();
	
	HttpRequest req;
	req.Header("User-Agent", "MyBot (None, 0.01)");
	req.Header("Authorization", "Bot NDUwMDA3OTY3NjIyNzU4NDIx.Dezhjw.pu-t0h9mH_zYI3v_uk6dxzO-WTE");
	req.ContentType("application/json");
	
	String response = req.Url("https://discordapp.com/api/gateway/bot").Execute();
	LOG(response);
	
	String gateway = ParseJSON(response)["url"];
	LOG(gateway);
	
	WebSocket ws;
	ws.Header("User-Agent", "MyBot (None, 0.01)");
	ws.Header("Authorization", "Bot NDUwMDA3OTY3NjIyNzU4NDIx.Dezhjw.pu-t0h9mH_zYI3v_uk6dxzO-WTE");
	ws.Connect(gateway);
}


Log:


HTTP START
Using discordapp.com:443
Starting status 2 'Resolving host name', url: discordapp.com
HTTP Execute: Resolving host name
HTTP StartConnect
HTTP AfterConnect
Starting status 5 'SSL handshake', url: discordapp.com
HTTP Execute: SSL handshake
Starting status 6 'Sending request', url: discordapp.com
HTTP REQUEST discordapp.com:0
HTTP request:
GET /api/gateway/bot HTTP/1.1
URL: http://discordapp.com/api/gateway/bot
Host: discordapp.com
Connection: close
Accept: */*
Accept-Encoding: gzip
User-Agent: U++ HTTP request
Content-Type: application/json
User-Agent: MyBot (None, 0.01)
Authorization: Bot NDUwMDA3OTY3NjIyNzU4NDIx.Dezhjw.pu-t0h9mH_zYI3v_uk6dxzO-WTE

HTTP request body:

HTTP Execute: Sending request
Starting status 7 'Receiving header', url: discordapp.com
HTTP Execute: Receiving header
HTTP Header received: 
HTTP/1.1 200 OK
Date: Mon, 28 May 2018 21:21:57 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: close
Set-Cookie: __cfduid=d2946871799170afe071c3c0946c8cfd51527542517; expires=Tue, 28-May-19 21:21:57 GMT; path=/; domain=.discordapp.com; HttpOnly
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-RateLimit-Limit: 2
X-RateLimit-Remaining: 1
X-RateLimit-Reset: 1527542523
Via: 1.1 google
Alt-Svc: clear
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 4223c61c2d291fca-DFW
Content-Encoding: gzip


HTTP status code: 200
Starting status 9 'Receiving chunk header', url: discordapp.com
HTTP Execute: Receiving chunk header
HTTP Chunk header: 0x4a = 74
Starting status 10 'Receiving content chunk', url: discordapp.com
HTTP Execute: Receiving content chunk
HTTP reading body 74
HTTP Out 48
Starting status 11 'Receiving content chunk ending', url: discordapp.com
HTTP Execute: Receiving content chunk ending
Starting status 9 'Receiving chunk header', url: discordapp.com
HTTP Execute: Receiving chunk header
HTTP Chunk header: 0x0 = 0
Starting status 12 'Receiving trailer', url: discordapp.com
HTTP Execute: Receiving trailer
{"url": "wss://gateway.discord.gg", "shards": 1}
wss://gateway.discord.gg
WS CLIENT DNS resolved
WS CLIENT Connect issued
WS CLIENT Blocking SSL handshake finished
WS CLIENT Sending connection request
WS CLIENT Sent 512 bytes: "GET wss://gateway.discord.gg HTTP/1.1\r\nHost: gateway.discord.gg\r\nSec-WebSocket-Key: qv+2H+B4KroFQKbVt0r+YkC3Zuc=\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: cs,en-US;q=0.7,en;q=0.3\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Extensions: permessage-deflate\r\nConnection: keep-alive, Upgrade\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\nUser-Agent: MyBot (None, 0.01)\r\nAuthorization: Bot NDUwMDA3OTY3NjIyNzU4NDIx.Dezhjw.pu-t0h9mH_zYI3v_uk6"
WS CLIENT Block sent complete, 0 remaining blocks in queue
WS CLIENT HTTP header received: "HTTP/1.1 404 Not Found\r\nDate: Mon, 28 May 2018 21:21:57 GMT\r\nContent-Type: text/html; charset=UTF-8\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nSet-Cookie: __cfduid=d4675c765c481944a6f16ee1cb7e7be9a1527542517; expires=Tue, 28-May-19 21:21:57 GMT; path=/; domain=.discord.gg; HttpOnly\r\nReferrer-Policy: no-referrer\r\nServer: cloudflare\r\nCF-RAY: 4223c61dbcc0581f-DFW\r\n\r\n"
WS CLIENT HTTP/1.1 404 Not Found
Date: Mon, 28 May 2018 21:21:57 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=d4675c765c481944a6f16ee1cb7e7be9a1527542517; expires=Tue, 28-May-19 21:21:57 GMT; path=/; domain=.discord.gg; HttpOnly
Referrer-Policy: no-referrer
Server: cloudflare
CF-RAY: 4223c61dbcc0581f-DFW


WS CLIENT ERROR: Invalid server response HTTP header

[Updated on: Sat, 02 March 2019 04:15]

Report message to a moderator

Re: Discord bot 404 error using WebSocket, any ideas? [message #49891 is a reply to message #49885] Thu, 31 May 2018 06:15 Go to previous messageGo to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 64
Registered: June 2011
Member
If I do this with an ordinary browser plugin to wss://gateway.discord.gg I get back:

{"t":null,"s":null,"op":10,"d":{"heartbeat_interval ":41250,"_trace":["gateway-prd-main-1hxr"]}}

but with U++ websocket I just get a 404 error. Does anyone have any idea why this connection might be failing? I confirmed that a connection to wss://echo.websocket.org actually works. Could it be something in the URL?

[Updated on: Thu, 31 May 2018 06:23]

Report message to a moderator

Re: Discord bot 404 error using WebSocket, any ideas? [message #49892 is a reply to message #49885] Thu, 31 May 2018 07:05 Go to previous messageGo to next message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 64
Registered: June 2011
Member
OK, so it successfully upgrades if I use
ws.Connect("https://gateway.discord.gg", "gateway.discord.gg", true, 443);

instead of
ws.Connect("wss://gateway.discord.gg")


The browser plugin I used appears to automatically be converting all WSS GET requests from wss:// to https:// while U++ does not. I don't see where the standards say this conversion is a conformant behavior but it's happening anyway. What would be the fix in U++ source? I could change it to:

bool WebSocket::Connect(const String& url)
{
	const char *u = url;
	bool ssl = memcmp(u, "wss", 3) == 0;
	const char *t = u;
	while(*t && *t != '?')
		if(*t++ == '/' && *t == '/') {
			u = ++t;
			break;
		}
	t = u;
	while(*u && *u != ':' && *u != '/' && *u != '?')
		u++;
	String host = String(t, u);
	int port = ssl ? 443 : 80;
	if(*u == ':')
		port = ScanInt(u + 1, &u);
	
	String uri = url;
	
	if(port == 443) {
		uri.Replace("wss://", "https://");
	}
	else if(port == 80) {
		uri.Replace("ws://", "http://");
	}
	
	return Connect(uri, host, ssl, port);
}


But I don't know if this is the "correct" conformant behavior or if the fix belongs deeper in the U++ source. I'm not a network protocol guy.

[Updated on: Thu, 31 May 2018 11:53]

Report message to a moderator

Re: Discord bot 404 error using WebSocket, any ideas? [message #50188 is a reply to message #49892] Mon, 20 August 2018 09:24 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12574
Registered: November 2005
Ultimate Member
Thank you, specification seems to say the ws/wss should be replaced with http/https:

3.   The "Request-URI" part of the request MUST match the /resource
        name/ defined in Section 3 (a relative URI) or be an absolute
        http/https URI that, when parsed, has a /resource name/, /host/,
        and /port/ that match the corresponding ws/wss URI.


so the code in U++ was wrong (looks like the server the we are testing against ignores this...).

Fixed:

bool WebSocket::Connect(const String& url)
{
	const char *u = url;
	bool ssl = memcmp(u, "wss", 3) == 0;
	const char *t = u;
	while(*t && *t != '?')
		if(*t++ == '/' && *t == '/') {
			u = ++t;
			break;
		}
	t = u;
	while(*u && *u != ':' && *u != '/' && *u != '?')
		u++;
	String host = String(t, u);
	int port = ssl ? 443 : 80;
	if(*u == ':')
		port = ScanInt(u + 1, &u);
	
	return Connect(url.StartsWith("wss:") ? "https:" + url.Mid(4)
	               : url.StartsWith("ws:") ? "http:" + url.Mid(3) : url,
	               host, ssl, port);
}
Re: Discord bot 404 error using WebSocket, any ideas? [message #50192 is a reply to message #50188] Mon, 20 August 2018 17:03 Go to previous message
jjacksonRIAB is currently offline  jjacksonRIAB
Messages: 64
Registered: June 2011
Member
Cool! Thank you, Mirek. That works for me.
Previous Topic: Thread::GetId() returning 0
Next Topic: Windows authenticated web page load
Goto Forum:
  


Current Time: Thu Jul 09 00:13:53 CEST 2020

Total time taken to generate the page: 0.00920 seconds