Reputation: 1
I have been digging for a while to see if I can find any fixes for this but I have seemed to hit a wall. At this point, I am not sure what the issue is. Every other host I have tried has worked except for discord.
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
cout << "WSAStartup failed.\n";
system("pause");
return 1;
}
SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct hostent* host;
host = gethostbyname("discordapp.com");
SOCKADDR_IN SockAddr;
SockAddr.sin_port = htons(80);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
cout << "Connecting...\n";
if (connect(Socket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr)) != 0) {
cout << "Could not connect";
system("pause");
return 1;
}
cout << "Connected.\n";
send(Socket, "GET /api/ HTTP/1.1\r\nHost: discordapp.com\r\nConnection: close\r\n\r\n", strlen("GET /api/ HTTP/1.1\r\nHost: discordapp.com\r\nConnection: close\r\n\r\n"), 0);
char buffer[10000];
int nDataLength;
while ((nDataLength = recv(Socket, buffer, 10000, 0)) > 0) {
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
cout << buffer[i];
i += 1;
}
}
closesocket(Socket);
WSACleanup();
system("pause");
return 0;
I keep getting this response no matter what I try:
HTTP/1.1 301 Moved Permanently
Date: Mon, 10 Feb 2020 21:16:57 GMT
Transfer-Encoding: chunked
Connection: close
Cache-Control: max-age=3600
Expires: Mon, 10 Feb 2020 22:16:57 GMT
Location: https://discordapp.com/api/
Set-Cookie: __cfruid=17e1ccd526aa851f5d5563850c5793a999f859c0-1581369417; path=/; domain=.discordapp.com; HttpOnly
Server: cloudflare
CF-RAY: 56311b6b0baba67b-DUB`
Is there something I am missing? The ultimate goal is to be able to post to a webhook using the api.
Upvotes: 0
Views: 1244
Reputation: 85541
You are connecting to port 80 making a plain (unencrypted) HTTP GET request.
The server replies with an HTTP redirect to https://discordapp.com/api/
i.e. switching protocols to secure HTTP (HTTPS).
Apparently the server is not allowing unencrypted traffic. You could try establishing a secure HTTP connection by connecting to port 443 and performing a TLS handshake and validating the server certificate (e.g. using schannel), but that wouldn't be productive. Even if successful, you'll have to additionally implement HTTP 1.1 chunked transfer-encoding and other protocol specifics (most of which you could skip by sending an HTTP/1.0 request, by that's not the point).
The point is, use a proper HTTP client library for making HTTP calls. Windows has a built-in one called WinInet.
For example, like this
#include <windows.h>
#include <wininet.h>
#include <iostream>
#pragma comment(lib, "wininet.lib")
int fail(const char* fmt, ...);
int main() {
HANDLE ih = InternetOpenA("Mozilla/4.0 (compatible)", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!ih) return fail("InternetOpen failed");
HINTERNET ch = InternetConnectA(ih, "discordapp.com", 443, NULL, NULL,
INTERNET_SERVICE_HTTP, 0, 0);
if (!ch) return fail("InternetConnect failed");
const char* acceptTypes[] = { "*/*", NULL };
HINTERNET req = HttpOpenRequestA(ch, NULL, "/api/", NULL, NULL, acceptTypes,
INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_UI, 0);
if (!req) return fail("HttpOpenRequest failed");
if (!HttpSendRequestA(req, NULL, 0, NULL, 0)) return fail("HttpSendRequest failed");
char buffer[4096];
DWORD n;
while (InternetReadFile(req, &buffer, 1, &n)) {
if (n == 0)
break;
std::cout.write(buffer, n);
}
std::cout << std::endl;
InternetCloseHandle(ch);
InternetCloseHandle(req);
InternetCloseHandle(ih);
return 0;
}
// helper function for printing the error message
int fail(const char* fmt, ...) {
DWORD lastError = GetLastError();
LPSTR lpMsgBuf = nullptr;
if (lastError)
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_HMODULE,
GetModuleHandle("wininet.dll"), lastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&lpMsgBuf, 0, NULL);
va_list va;
va_start(va, fmt);
char buf[1024];
_vsnprintf(buf, sizeof(buf), fmt, va);
va_end(va);
buf[1023] = 0;
std::string msg = buf;
if (lpMsgBuf) {
msg += ": ";
auto len = strlen(lpMsgBuf);
while (len && (lpMsgBuf[len - 1] == '\r' || lpMsgBuf[len - 1] == '\n'))
lpMsgBuf[--len] = 0;
msg += lpMsgBuf;
LocalFree(lpMsgBuf);
}
std::cerr << msg << std::endl;
return 1;
}
Upvotes: 1