implemented keepalive

This commit is contained in:
winsped
2026-08-06 17:40:27 +03:00
parent 271121ec07
commit f32ec710ff
6 changed files with 477 additions and 350 deletions
+1 -1
View File
@@ -10,9 +10,9 @@
- [X] ChatView with proper message alignment - [X] ChatView with proper message alignment
- [X] Showing mention counts - [X] Showing mention counts
- [X] Keep-Alive HTTP implementation - [X] Keep-Alive HTTP implementation
- [X] Switch to keep-alive HTTP use
- [ ] Add support for GCs - [ ] Add support for GCs
- [ ] Rendering replies - [ ] Rendering replies
- [ ] Switch to keep-alive HTTP
- [ ] Add support for guild folders - [ ] Add support for guild folders
- [ ] Use the root guild folder to order the guilds properly - [ ] Use the root guild folder to order the guilds properly
- [ ] File uploading - [ ] File uploading
+20 -8
View File
@@ -1,6 +1,7 @@
#include "discordtypes.h" #include "discordtypes.h"
#include "http.h" #include "http.h"
#include "config.h" #include "config.h"
#include <openssl/core.h>
#include <windows.h> #include <windows.h>
#include <winnt.h> #include <winnt.h>
#include <winternl.h> #include <winternl.h>
@@ -12,6 +13,8 @@
hmap GuildsTable = NULL; hmap GuildsTable = NULL;
hmap ChannelsTable = NULL; hmap ChannelsTable = NULL;
DiscordChannel *PrivateChannels = NULL; DiscordChannel *PrivateChannels = NULL;
HTTPConnection* maincon;
HTTPConnection* cdncon;
int PrivateChannelCount = 0; int PrivateChannelCount = 0;
static uint64_t GuildHash(const void *item, uint64_t seed0, uint64_t seed1) { static uint64_t GuildHash(const void *item, uint64_t seed0, uint64_t seed1) {
const DiscordGuild *e = item; const DiscordGuild *e = item;
@@ -33,6 +36,15 @@ static void ChannelFree(void *item) {}
extern void onDiscordGuildLoad(DiscordGuild *guild, char *id); extern void onDiscordGuildLoad(DiscordGuild *guild, char *id);
extern void onDiscordUpdatedGuildReadState(DiscordGuild gld); extern void onDiscordUpdatedGuildReadState(DiscordGuild gld);
extern void onDiscordReady(DiscordUser user, DiscordGuild *guilds, int guildscount); extern void onDiscordReady(DiscordUser user, DiscordGuild *guilds, int guildscount);
int DiscordHTTPConnect(){
maincon=HTTPConnect("discord.com");
cdncon=HTTPConnect("cdn.discordapp.com");
return maincon->connected && cdncon->connected;
}
void DiscordHTTPClose(){
CloseHTTPConnection(maincon);
CloseHTTPConnection(cdncon);
}
int DiscordSendMessage(const char *channelID, const char *content) { int DiscordSendMessage(const char *channelID, const char *content) {
cJSON *payload = cJSON_CreateObject(); cJSON *payload = cJSON_CreateObject();
cJSON *name = cJSON_CreateString(content); cJSON *name = cJSON_CreateString(content);
@@ -46,8 +58,8 @@ int DiscordSendMessage(const char *channelID, const char *content) {
char *payld = cJSON_Print(payload); char *payld = cJSON_Print(payload);
long resplen; long resplen;
char headers[17 + strlen(token) + 1]; char headers[17 + strlen(token) + 1];
wsprintf(headers, "Authorization: %s\r\n", token); wsprintf(headers, "Authorization: %s", token);
SendShortHTTPReq("discord.com", "POST", endpoint, headers, user_agent, SendHTTPRequest(maincon,"POST", endpoint, headers, user_agent,
"application/json", payld, strlen(payld), &forNothingGng, "application/json", payld, strlen(payld), &forNothingGng,
&resplen); &resplen);
free(payld); free(payld);
@@ -74,8 +86,8 @@ char *DiscordFetchTmpPfp(char *userID, char *hash) {
char *HTTPResp; char *HTTPResp;
long resplen; long resplen;
char headers[17 + strlen(token) + 1]; char headers[17 + strlen(token) + 1];
wsprintf(headers, "Authorization: %s\r\n", token); wsprintf(headers, "Authorization: %s", token);
SendShortHTTPReq("cdn.discordapp.com", "GET", endpoint, headers, user_agent, SendHTTPRequest(cdncon, "GET", endpoint, headers, user_agent,
"application/json", NULL, 0, &HTTPResp, &resplen); "application/json", NULL, 0, &HTTPResp, &resplen);
free(endpoint); free(endpoint);
@@ -105,8 +117,8 @@ char *DiscordFetchTmpGuildIcon(char *guildID, char *hash) {
char *HTTPResp; char *HTTPResp;
long resplen; long resplen;
char headers[17 + strlen(token) + 1]; char headers[17 + strlen(token) + 1];
wsprintf(headers, "Authorization: %s\r\n", token); wsprintf(headers, "Authorization: %s", token);
SendShortHTTPReq("cdn.discordapp.com", "GET", endpoint, headers, user_agent, SendHTTPRequest(cdncon, "GET", endpoint, headers, user_agent,
"application/json", NULL, 0, &HTTPResp, &resplen); "application/json", NULL, 0, &HTTPResp, &resplen);
free(endpoint); free(endpoint);
@@ -146,9 +158,9 @@ int DiscordGetChannelHistory(const char *channelID, unsigned int amount,
long resplen; long resplen;
char headers[17 + strlen(token) + 1]; char headers[17 + strlen(token) + 1];
wsprintf(headers, "Authorization: %s\r\n", token); wsprintf(headers, "Authorization: %s", token);
SendShortHTTPReq("discord.com", "GET", endpoint, headers, user_agent, SendHTTPRequest(maincon, "GET", endpoint, headers, user_agent,
"application/json", NULL, 0, &HTTPResp, &resplen); "application/json", NULL, 0, &HTTPResp, &resplen);
cJSON *resp = cJSON_Parse(HTTPResp); cJSON *resp = cJSON_Parse(HTTPResp);
if (!resp) if (!resp)
+2
View File
@@ -13,3 +13,5 @@ int DiscordGetChannelHistory(const char* channelID, unsigned int amount, Discord
char *DiscordFetchTmpPfp(char *userID, char *hash); char *DiscordFetchTmpPfp(char *userID, char *hash);
char *DiscordFetchTmpGuildIcon(char *guildID, char *hash); char *DiscordFetchTmpGuildIcon(char *guildID, char *hash);
int DiscordListPrivateChannels(DiscordChannel** out); int DiscordListPrivateChannels(DiscordChannel** out);
int DiscordHTTPConnect();
void DiscordHTTPClose();
+426 -339
View File
@@ -7,378 +7,465 @@
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
// keepalive state static void AppendHeader(char *buf, const char *key, const char *value) {
typedef struct { strcat(buf, key);
SOCKET sock; strcat(buf, ": ");
SSL* ssl; strcat(buf, value);
SSL_CTX* ctx; strcat(buf, "\r\n");
char hostname[256];
int connected;
} HTTPConnection;
static void AppendHeader(char* buf,
const char* key, const char* value)
{
strcat(buf, key);
strcat(buf, ": ");
strcat(buf, value);
strcat(buf, "\r\n");
} }
char* ProcessChunkedTransfer(char* chunked, size_t chunked_len, size_t *out_len) { char *ProcessChunkedTransfer(char *chunked, size_t chunked_len,
char* result = malloc(chunked_len); size_t *out_len) {
size_t written = 0; char *result = malloc(chunked_len);
char* curpos = chunked; size_t written = 0;
char *curpos = chunked;
while(1) { while (1) {
char* crlf = strstr(curpos, "\r\n"); char *crlf = strstr(curpos, "\r\n");
if(!crlf) break; if (!crlf)
break;
int chunklen = (int)strtol(curpos, NULL, 16); int chunklen = (int)strtol(curpos, NULL, 16);
if(chunklen == 0) break; if (chunklen == 0)
break;
char* data = crlf + 2; char *data = crlf + 2;
memcpy(result + written, data, chunklen); memcpy(result + written, data, chunklen);
written += chunklen; written += chunklen;
curpos = data + chunklen + 2; curpos = data + chunklen + 2;
}
*out_len = written;
return result;
}
HTTPConnection* ConnectOverHTTP(const char* hostname) {
HTTPConnection* conn = malloc(sizeof(HTTPConnection));
RtlZeroMemory(conn, sizeof(HTTPConnection));
strncpy(conn->hostname, hostname, 255);
conn->hostname[255] = '\0';
conn->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (conn->sock == INVALID_SOCKET) {
MessageBoxA(NULL, "socket failed :(", "sad http announcement", 0);
free(conn);
return NULL;
}
struct sockaddr_in server;
RtlZeroMemory(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(443);
server.sin_addr = **(struct in_addr**)gethostbyname(hostname)->h_addr_list; // why is a part of this in bold
if (connect(conn->sock, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {
MessageBoxA(NULL, "connect failed :(", "sad http announcement", 0);
closesocket(conn->sock);
free(conn);
return NULL;
}
conn->ctx = SSL_CTX_new(TLS_client_method());
if (!conn->ctx) {
MessageBoxA(NULL, "SSL_CTX_new failed :(", "sad http announcement", 0);
closesocket(conn->sock);
free(conn);
return NULL;
}
conn->ssl = SSL_new(conn->ctx);
if (!conn->ssl) {
MessageBoxA(NULL, "SSL_new failed :(", "sad http announcement", 0);
SSL_CTX_free(conn->ctx);
closesocket(conn->sock);
free(conn);
return NULL;
}
SSL_set_fd(conn->ssl, (int)conn->sock);
SSL_set_tlsext_host_name(conn->ssl, hostname);
if (SSL_connect(conn->ssl) <= 0) {
MessageBoxA(NULL, "SSL_connect failed :(", "sad http announcement", 0);
SSL_free(conn->ssl);
SSL_CTX_free(conn->ctx);
closesocket(conn->sock);
free(conn);
return NULL;
}
conn->connected = 1;
return conn;
}
int SendHTTPRequest(HTTPConnection* conn, const char* method, const char* endpoint,
const char* user_agent, const char* content_type, void* payload,
unsigned long payload_size, char** response, long* responselen)
{
if (!conn || !conn->connected) {
MessageBoxA(NULL, "connection not established :(", "sad http announcement", 0);
return 1;
}
char headerbuf[2048];
RtlZeroMemory(headerbuf, sizeof(headerbuf));
wsprintfA(headerbuf, "%s %s HTTP/1.1\r\n", method, endpoint);
strcat(headerbuf, "Host: ");
strcat(headerbuf, conn->hostname);
strcat(headerbuf, "\r\n");
strcat(headerbuf, "User-Agent: ");
strcat(headerbuf, user_agent);
strcat(headerbuf, "\r\n");
if (payload) {
strcat(headerbuf, "Content-Type: ");
strcat(headerbuf, content_type);
strcat(headerbuf, "\r\n");
char contentlen[128];
RtlZeroMemory(contentlen, sizeof(contentlen));
wsprintfA(contentlen, "Content-Length: %lu\r\n", payload_size);
strcat(headerbuf, contentlen);
}
strcat(headerbuf, "Connection: keep-alive\r\n");
strcat(headerbuf, "\r\n");
if (SSL_write(conn->ssl, headerbuf, (int)strlen(headerbuf)) <= 0) {
MessageBoxA(NULL, "SSL_write headers failed :(", "sad http announcement", 0);
return 1;
}
if (payload && payload_size > 0) {
if (SSL_write(conn->ssl, payload, (int)payload_size) <= 0) {
MessageBoxA(NULL, "SSL_write payload failed :(", "sad http announcement", 0);
return 1;
}
}
char* buffer = malloc(8192);
size_t sizeofbuf = 8192;
size_t total_bytes = 0;
int bytes_read;
while ((bytes_read = SSL_read(conn->ssl, buffer + total_bytes, (int)(sizeofbuf - total_bytes - 1))) > 0) {
total_bytes += bytes_read;
if (total_bytes + 1 >= sizeofbuf) {
sizeofbuf += 8192;
char* newbuf = realloc(buffer, sizeofbuf);
if (!newbuf) {
MessageBoxA(NULL, "realloc failed :(", "sad http announcement", 0);
free(buffer);
return -1;
}
buffer = newbuf;
}
}
buffer[total_bytes] = '\0';
char* endofhdr = strstr(buffer, "\r\n\r\n");
if (!endofhdr) {
MessageBoxA(NULL, "malformed response :(", "sad http announcement", 0);
free(buffer);
return -1;
}
char* body_start = endofhdr + 4;
size_t body_len = total_bytes - (body_start - buffer);
if (strstr(buffer, "Transfer-Encoding: chunked")) {
size_t outlen;
*response = ProcessChunkedTransfer(body_start, body_len, &outlen);
*responselen = (long)outlen;
free(buffer);
} else {
char* copy = malloc(body_len + 1);
memcpy(copy, body_start, body_len);
copy[body_len] = '\0';
*response = copy;
*responselen = (long)body_len;
free(buffer);
}
return 0;
}
int CloseHTTPConnection(HTTPConnection* conn) {
if (!conn) {
return 1;
}
if (conn->ssl) {
SSL_shutdown(conn->ssl);
SSL_free(conn->ssl);
}
if (conn->ctx) {
SSL_CTX_free(conn->ctx);
}
if (conn->sock != INVALID_SOCKET) {
closesocket(conn->sock);
}
free(conn);
return 0;
}
int SendShortHTTPReq(const char* hostname,const char* reqtype, const char* endpoint, const char* extra_headers, const char* user_agent, const char* content_type, void* payload, unsigned long payload_size, char** response, long* responselen)
{
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
MessageBoxA(NULL, "socket failed", "Aa", 0);
return 1;
}
struct sockaddr_in server;
RtlZeroMemory(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(443); // HTTPS brotatochippiee
server.sin_addr = **(struct in_addr**)gethostbyname(hostname)->h_addr_list;
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {
MessageBoxA(NULL, "connect failed", "Aa", 0);
closesocket(sock);
return 1;
} }
// this debugging thing served us well yall MessageBoxA(NULL, "onto ze ctx", "Aa", 0); *out_len = written;
SSL_CTX* ctx = SSL_CTX_new(TLS_client_method()); return result;
if (!ctx) { }
HTTPConnection *HTTPConnect(const char *hostname) {
HTTPConnection *conn = malloc(sizeof(HTTPConnection));
RtlZeroMemory(conn, sizeof(HTTPConnection));
strncpy(conn->hostname, hostname, 255);
conn->hostname[255] = '\0';
conn->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (conn->sock == INVALID_SOCKET) {
char msg[128];
wsprintfA(msg, "socket failed: WSAGetLastError=%d", WSAGetLastError());
MessageBoxA(NULL, msg, "sad http announcement", 0);
free(conn);
return NULL;
}
struct sockaddr_in server;
RtlZeroMemory(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(443);
server.sin_addr = **(struct in_addr **)gethostbyname(hostname)
->h_addr_list; // why is a part of this in bold
if (connect(conn->sock, (struct sockaddr *)&server, sizeof(server)) ==
SOCKET_ERROR) {
MessageBoxA(NULL, "connect failed :(", "sad http announcement", 0);
closesocket(conn->sock);
free(conn);
return NULL;
}
conn->ctx = SSL_CTX_new(TLS_client_method());
if (!conn->ctx) {
MessageBoxA(NULL, "SSL_CTX_new failed :(", "sad http announcement", 0);
closesocket(conn->sock);
free(conn);
return NULL;
}
conn->ssl = SSL_new(conn->ctx);
if (!conn->ssl) {
MessageBoxA(NULL, "SSL_new failed :(", "sad http announcement", 0);
SSL_CTX_free(conn->ctx);
closesocket(conn->sock);
free(conn);
return NULL;
}
SSL_set_fd(conn->ssl, (int)conn->sock);
SSL_set_tlsext_host_name(conn->ssl, hostname);
if (SSL_connect(conn->ssl) <= 0) {
MessageBoxA(NULL, "SSL_connect failed :(", "sad http announcement", 0);
SSL_free(conn->ssl);
SSL_CTX_free(conn->ctx);
closesocket(conn->sock);
free(conn);
return NULL;
}
conn->connected = 1;
return conn;
}
char *GetHeaderValue(char *source, char *field) {
size_t flen = strlen(field);
for (char *curs = source; curs; curs = strstr(curs + 1, "\r\n")
? strstr(curs + 1, "\r\n") + 2
: NULL) {
if (strncmp(field, curs, flen) == 0 && curs[flen] == ':') {
char *dat = curs + flen + 1;
while (*dat == ' ')
dat++;
char *end = strstr(curs + 1, "\r\n");
char *ret = malloc(end - dat + 1);
memcpy(ret, dat, end - dat);
ret[end - dat] = '\0';
return ret;
}
}
return NULL;
}
int SendHTTPRequest(HTTPConnection *conn, const char *method,
const char *endpoint, const char *extra_headers,
const char *user_agent, const char *content_type,
void *payload, unsigned long payload_size, char **response,
long *responselen) {
if (!conn || !conn->connected) {
MessageBoxA(NULL, "connection not established :(",
"sad http announcement", 0);
return 1;
}
char headerbuf[4096];
RtlZeroMemory(headerbuf, sizeof(headerbuf));
wsprintfA(headerbuf, "%s %s HTTP/1.1\r\n", method, endpoint);
strcat(headerbuf, "Host: ");
strcat(headerbuf, conn->hostname);
strcat(headerbuf, "\r\n");
strcat(headerbuf, extra_headers);
strcat(headerbuf, "\r\n");
strcat(headerbuf, "User-Agent: ");
strcat(headerbuf, user_agent);
strcat(headerbuf, "\r\n");
if (payload) {
strcat(headerbuf, "Content-Type: ");
strcat(headerbuf, content_type);
strcat(headerbuf, "\r\n");
char contentlen[128];
RtlZeroMemory(contentlen, sizeof(contentlen));
wsprintfA(contentlen, "Content-Length: %lu\r\n", payload_size);
strcat(headerbuf, contentlen);
}
strcat(headerbuf, "Connection: keep-alive\r\n");
strcat(headerbuf, "\r\n");
char dbg[64];
wsprintfA(dbg, "headerbuf len: %d", (int)strlen(headerbuf));
MessageBoxA(NULL, dbg, "debug", 0);
if (SSL_write(conn->ssl, headerbuf, (int)strlen(headerbuf)) <= 0) {
MessageBoxA(NULL, "SSL_write headers failed :(",
"sad http announcement", 0);
return 1;
}
if (payload && payload_size > 0) {
if (SSL_write(conn->ssl, payload, (int)payload_size) <= 0) {
MessageBoxA(NULL, "SSL_write payload failed :(",
"sad http announcement", 0);
return 1;
}
}
char *buffer = malloc(8192);
memset(buffer, 0, 8192);
size_t sizeofbuf = 8192;
size_t total_bytes = 0;
int bytes_read;
int headerlen;
while (strstr(buffer, "\r\n\r\n") == NULL) {
bytes_read = SSL_read(conn->ssl, buffer + total_bytes,
(int)(sizeofbuf - total_bytes - 1));
total_bytes += bytes_read;
if (total_bytes + 1 >= sizeofbuf) {
sizeofbuf += 8192;
char *newbuf = realloc(buffer, sizeofbuf);
if (!newbuf) {
MessageBoxA(NULL, "realloc failed :(", "sad http announcement",
0);
free(buffer);
return -1;
}
buffer = newbuf;
}
}
char *endofhdr = strstr(buffer, "\r\n\r\n");
headerlen = endofhdr - buffer;
char *headers = malloc(headerlen + 1);
memcpy(headers, buffer, headerlen);
headers[headerlen] = '\0';
char *cclen = GetHeaderValue(headers, "Content-Length");
unsigned long long clen = cclen ? strtoull(cclen, NULL, 10) : 0;
free(cclen);
char *body_start = buffer + headerlen + 4;
size_t body_have =
total_bytes - (body_start - buffer); // body bytes already buffered
int is_chunked = 0;
char *cte = GetHeaderValue(headers, "Transfer-Encoding");
if (cte) {
if (strstr(cte, "chunked"))
is_chunked = 1;
free(cte);
}
free(headers);
if (is_chunked) {
while (!strstr(body_start, "0\r\n\r\n")) {
if (total_bytes + 1 >= sizeofbuf) {
sizeofbuf += 8192;
char *newbuf = realloc(buffer, sizeofbuf);
if (!newbuf) {
free(buffer);
return -1;
}
buffer = newbuf;
body_start = buffer + headerlen + 4;
}
int n = SSL_read(conn->ssl, buffer + total_bytes,
(int)(sizeofbuf - total_bytes - 1));
if (n <= 0)
break;
total_bytes += n;
buffer[total_bytes] = '\0';
}
} else {
while (body_have < clen) {
if (total_bytes + 1 >= sizeofbuf) {
sizeofbuf += 8192;
char *newbuf = realloc(buffer, sizeofbuf);
if (!newbuf) {
free(buffer);
return -1;
}
buffer = newbuf;
body_start = buffer + headerlen + 4;
}
int n = SSL_read(conn->ssl, buffer + total_bytes,
(int)(sizeofbuf - total_bytes - 1));
if (n <= 0)
break;
total_bytes += n;
body_have += n;
}
}
buffer[total_bytes] = '\0';
if (!endofhdr) {
MessageBoxA(NULL, "malformed response :(", "sad http announcement", 0);
free(buffer);
return -1;
}
size_t body_len = total_bytes - (body_start - buffer);
if (is_chunked) {
size_t outlen;
*response = ProcessChunkedTransfer(body_start, body_len, &outlen);
*responselen = (long)outlen;
free(buffer);
} else {
char *copy = malloc(body_len + 1);
memcpy(copy, body_start, body_len);
copy[body_len] = '\0';
*response = copy;
*responselen = (long)body_len;
free(buffer);
}
return 0;
}
int CloseHTTPConnection(HTTPConnection *conn) {
if (!conn) {
return 1;
}
if (conn->ssl) {
SSL_shutdown(conn->ssl);
SSL_free(conn->ssl);
}
if (conn->ctx) {
SSL_CTX_free(conn->ctx);
}
if (conn->sock != INVALID_SOCKET) {
closesocket(conn->sock);
}
free(conn);
return 0;
}
int SendShortHTTPReq(const char *hostname, const char *reqtype,
const char *endpoint, const char *extra_headers,
const char *user_agent, const char *content_type,
void *payload, unsigned long payload_size, char **response,
long *responselen) {
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
MessageBoxA(NULL, "socket failed", "Aa", 0);
return 1;
}
struct sockaddr_in server;
RtlZeroMemory(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(443); // HTTPS brotatochippiee
server.sin_addr = **(struct in_addr **)gethostbyname(hostname)->h_addr_list;
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) ==
SOCKET_ERROR) {
MessageBoxA(NULL, "connect failed", "Aa", 0);
closesocket(sock);
return 1;
}
// this debugging thing served us well yall MessageBoxA(NULL, "onto ze ctx",
// "Aa", 0);
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
if (!ctx) {
MessageBoxA(NULL, "SSL_CTX_new failed", "Aa", 0); MessageBoxA(NULL, "SSL_CTX_new failed", "Aa", 0);
unsigned long err = ERR_get_error(); unsigned long err = ERR_get_error();
if (err == 0) { if (err == 0) {
MessageBoxA(NULL, "unknown OpenSSL error", "title", MB_ICONERROR); MessageBoxA(NULL, "unknown OpenSSL error", "title", MB_ICONERROR);
return 1; return 1;
} }
char buf[256]; char buf[256];
ERR_error_string_n(err, buf, sizeof(buf)); ERR_error_string_n(err, buf, sizeof(buf));
MessageBoxA(NULL, buf, "title", MB_ICONERROR); MessageBoxA(NULL, buf, "title", MB_ICONERROR);
return 1; return 1;
} }
SSL* ssl = SSL_new(ctx); SSL *ssl = SSL_new(ctx);
if (!ssl) { if (!ssl) {
MessageBoxA(NULL, "SSL_new failed qwq", "Aa", 0); MessageBoxA(NULL, "SSL_new failed qwq", "Aa", 0);
return 1; return 1;
} }
// Attach socket to SSL // Attach socket to SSL
SSL_set_fd(ssl, (int)sock); SSL_set_fd(ssl, (int)sock);
// SNI (importante shi) // SNI (importante shi)
SSL_set_tlsext_host_name(ssl, hostname); SSL_set_tlsext_host_name(ssl, hostname);
if (SSL_connect(ssl) <= 0) { if (SSL_connect(ssl) <= 0) {
MessageBoxA(NULL, "SSL_connect failed", "Aa", 0); MessageBoxA(NULL, "SSL_connect failed", "Aa", 0);
SSL_free(ssl); SSL_free(ssl);
SSL_CTX_free(ctx); SSL_CTX_free(ctx);
closesocket(sock); closesocket(sock);
return 1; return 1;
} }
SSL_write(ssl, reqtype, (int)strlen(reqtype)); // Sends request type
SSL_write(ssl, reqtype, (int)strlen(reqtype)); // Sends request type SSL_write(ssl, " ", 1); // stupid fuckass space
SSL_write(ssl, " ", 1); // stupid fuckass space
SSL_write(ssl, endpoint, (int)strlen(endpoint)); // endpoint SSL_write(ssl, endpoint, (int)strlen(endpoint)); // endpoint
SSL_write(ssl, " HTTP/1.1\r\n", 11); // the protocol thing.. ykw i will be more formal SSL_write(ssl, " HTTP/1.1\r\n",
SSL_write(ssl, "Host: ", 6); // Host beginning 11); // the protocol thing.. ykw i will be more formal
SSL_write(ssl, "Host: ", 6); // Host beginning
SSL_write(ssl, hostname, (int)(strlen(hostname))); // Host data SSL_write(ssl, hostname, (int)(strlen(hostname))); // Host data
SSL_write(ssl, "\r\n", 2); // Host end SSL_write(ssl, "\r\n", 2); // Host end
SSL_write(ssl, "User-Agent: ", 12); // User Agent beginning SSL_write(ssl, "User-Agent: ", 12); // User Agent beginning
SSL_write(ssl, user_agent, (int)(strlen(user_agent))); // User Agent data SSL_write(ssl, user_agent, (int)(strlen(user_agent))); // User Agent data
SSL_write(ssl, "\r\n", 2); // User Agent end SSL_write(ssl, "\r\n", 2); // User Agent end
if (payload != 0) { if (payload != 0) {
SSL_write(ssl, "Content-Type: ", 14); // Content Type beginning SSL_write(ssl, "Content-Type: ", 14); // Content Type beginning
SSL_write(ssl, content_type, (int)strlen(content_type)); SSL_write(ssl, content_type, (int)strlen(content_type));
SSL_write(ssl, "\r\n", 2); // Content Type end SSL_write(ssl, "\r\n", 2); // Content Type end
SSL_write(ssl, "Content-Length: ", 16); // Content Length beginning
char lenstr[64];
RtlZeroMemory(lenstr,64);
wsprintfA(lenstr,"%d",payload_size);
SSL_write(ssl, lenstr, (int)(strlen(lenstr))); // Content Length data
SSL_write(ssl, "\r\n", 2); // Content Length end
}
SSL_write(ssl, "Content-Length: ", 16); // Content Length beginning
char lenstr[64];
RtlZeroMemory(lenstr, 64);
wsprintfA(lenstr, "%d", payload_size);
SSL_write(ssl, lenstr, (int)(strlen(lenstr))); // Content Length data
SSL_write(ssl, "\r\n", 2); // Content Length end
}
SSL_write(ssl, extra_headers, (int)(strlen(extra_headers))); // Extra Header SSL_write(ssl, extra_headers, (int)(strlen(extra_headers))); // Extra Header
SSL_write(ssl, "Connection: close\r\n", 19); //Short-term connection SSL_write(ssl, "\r\n", 2);
SSL_write(ssl, "\r\n", 2); //Ends the header SSL_write(ssl, "Connection: close\r\n", 19); // Short-term connection
if(payload) SSL_write(ssl, "\r\n", 2); // Ends the header
SSL_write(ssl, payload, (int)payload_size); //Payload if (payload)
SSL_write(ssl, payload, (int)payload_size); // Payload
char* buffer = malloc(4096); char *buffer = malloc(4096);
size_t sizeofbuf = 4096; size_t sizeofbuf = 4096;
size_t total_bytes = 0; size_t total_bytes = 0;
int bytes_read; int bytes_read;
while ((bytes_read = SSL_read(ssl, buffer + total_bytes, (int)(sizeofbuf - total_bytes - 1))) > 0) { while ((bytes_read = SSL_read(ssl, buffer + total_bytes,
total_bytes += bytes_read; (int)(sizeofbuf - total_bytes - 1))) > 0) {
total_bytes += bytes_read;
if (total_bytes + 1 >= sizeofbuf) { if (total_bytes + 1 >= sizeofbuf) {
sizeofbuf += 4096; sizeofbuf += 4096;
char* newbuf = realloc(buffer, sizeofbuf); char *newbuf = realloc(buffer, sizeofbuf);
if (!newbuf) { if (!newbuf) {
//what the fuck had possibly happened on bros pc :sob: // what the fuck had possibly happened on bros pc :sob:
free(buffer); free(buffer);
SSL_shutdown(ssl); SSL_shutdown(ssl);
SSL_free(ssl); SSL_free(ssl);
SSL_CTX_free(ctx); SSL_CTX_free(ctx);
closesocket(sock); closesocket(sock);
return -1; return -1;
} }
buffer = newbuf; buffer = newbuf;
} }
} }
buffer[total_bytes] = '\0'; buffer[total_bytes] = '\0';
char *endofhdr = strstr(buffer, "\r\n\r\n"); char *endofhdr = strstr(buffer, "\r\n\r\n");
if (!endofhdr) { if (!endofhdr) {
free(buffer); free(buffer);
SSL_shutdown(ssl); SSL_free(ssl); SSL_CTX_free(ctx); SSL_shutdown(ssl);
closesocket(sock); SSL_free(ssl);
return -1; SSL_CTX_free(ctx);
} closesocket(sock);
return -1;
}
char *body_start = endofhdr + 4; char *body_start = endofhdr + 4;
size_t body_len = total_bytes - (body_start - buffer); size_t body_len = total_bytes - (body_start - buffer);
if (strstr(buffer, "Transfer-Encoding: chunked")) { if (strstr(buffer, "Transfer-Encoding: chunked")) {
size_t outlen; size_t outlen;
*response = ProcessChunkedTransfer(body_start,body_len,&outlen); *response = ProcessChunkedTransfer(body_start, body_len, &outlen);
*responselen = (long)outlen; *responselen = (long)outlen;
free(buffer); free(buffer);
} else { } else {
char *copy = malloc(body_len + 1); char *copy = malloc(body_len + 1);
memcpy(copy, body_start, body_len); memcpy(copy, body_start, body_len);
copy[body_len] = '\0'; copy[body_len] = '\0';
*response = copy; *response = copy;
*responselen = (long)body_len; *responselen = (long)body_len;
free(buffer); free(buffer);
} }
SSL_shutdown(ssl); SSL_shutdown(ssl);
SSL_free(ssl); SSL_free(ssl);
SSL_CTX_free(ctx); SSL_CTX_free(ctx);
closesocket(sock); closesocket(sock);
return 0; return 0;
} }
int InitHTTP() { int InitHTTP() {
SSL_library_init(); SSL_library_init();
SSL_load_error_strings(); SSL_load_error_strings();
OpenSSL_add_all_algorithms(); OpenSSL_add_all_algorithms();
WSADATA wsaData; WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData); //me when macros WSAStartup(MAKEWORD(2, 2), &wsaData); // me when macros
}
int CleanupHTTP() {
WSACleanup();
} }
int CleanupHTTP() { WSACleanup(); }
+17 -1
View File
@@ -1,10 +1,26 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include <openssl/ssl.h>
// keepalive state
typedef struct {
SOCKET sock;
SSL* ssl;
SSL_CTX* ctx;
char hostname[256];
int connected;
} HTTPConnection;
void InitSockets(); void InitSockets();
int SendShortHTTPReq(const char *hostname, const char *reqtype, int SendShortHTTPReq(const char *hostname, const char *reqtype,
const char *endpoint, const char *extra_headers, const char *endpoint, const char *extra_headers,
const char *user_agent, const char *content_type, const char *user_agent, const char *content_type,
void *payload, unsigned long payload_size, char** response, long* responselen); void *payload, unsigned long payload_size, char** response, long* responselen);
HTTPConnection* HTTPConnect(const char* hostname);
int SendHTTPRequest(HTTPConnection* conn, const char* method, const char* endpoint, const char* extra_headers,
const char* user_agent, const char* content_type, void* payload,
unsigned long payload_size, char** response, long* responselen);
int CloseHTTPConnection(HTTPConnection* conn);
static void AppendHeader(char *buf, const char *key, const char *value); static void AppendHeader(char *buf, const char *key, const char *value);
int InitHTTP(); int InitHTTP();
+10
View File
@@ -264,6 +264,15 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
HFONT BoldSysFont = CreateFontIndirect(&ncm.lfMessageFont); HFONT BoldSysFont = CreateFontIndirect(&ncm.lfMessageFont);
InitHTTP(); InitHTTP();
/* HTTPConnection* hc = HTTPConnect("httpbin.org");
long responselen;
char* response;
SendHTTPRequest(hc, "GET", "/get", "", user_agent, NULL, NULL, 0, &response, &responselen);
MessageBoxA(NULL,response,"HTTP Test",0);
if(responselen==strlen(response)){
MessageBoxA(NULL,"pass","HTTP Test",0);
}*/
DiscordHTTPConnect();
RECT rc; RECT rc;
GetClientRect(hwnd, &rc); GetClientRect(hwnd, &rc);
@@ -623,6 +632,7 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
PostQuitMessage(0); PostQuitMessage(0);
case WM_DESTROY: case WM_DESTROY:
CleanupHTTP(); CleanupHTTP();
DiscordHTTPClose();
return TRUE; return TRUE;
break; break;
} }