Http client: able to login now

This commit is contained in:
UnknownShadow200 2023-05-25 22:43:17 +10:00
parent be925a7780
commit 6cd0dae2a8
3 changed files with 55 additions and 21 deletions

View File

@ -482,6 +482,21 @@ static void HttpUrl_Parse(const cc_string* src, struct HttpUrl* url) {
} }
struct HttpConnection {
cc_socket socket;
};
static cc_result HttpConnection_Open(struct HttpConnection* conn, const struct HttpUrl* url) {
conn->socket = 0;
return Socket_Connect(&conn->socket, &url->address, url->port, false);
}
static void HttpConnection_Close(struct HttpConnection* conn) {
Socket_Close(conn->socket);
conn->socket = 0;
}
enum HTTP_RESPONSE_STATE { enum HTTP_RESPONSE_STATE {
HTTP_RESPONSE_STATE_HEADER, HTTP_RESPONSE_STATE_HEADER,
HTTP_RESPONSE_STATE_BODY_INIT, HTTP_RESPONSE_STATE_BODY_INIT,
@ -496,6 +511,7 @@ enum HTTP_RESPONSE_STATE {
struct HttpClientState { struct HttpClientState {
enum HTTP_RESPONSE_STATE state; enum HTTP_RESPONSE_STATE state;
struct HttpConnection conn;
struct HttpRequest* req; struct HttpRequest* req;
int chunked; int chunked;
int chunkRead, chunkLength; int chunkRead, chunkLength;
@ -531,6 +547,8 @@ static void HttpClient_Serialise(struct HttpClientState* state) {
Http_AddHeader(req, "Host", &state->url.address); /* TODO port for non-standard*/ Http_AddHeader(req, "Host", &state->url.address); /* TODO port for non-standard*/
Http_AddHeader(req, "User-Agent", &userAgent); Http_AddHeader(req, "User-Agent", &userAgent);
if (req->data) String_Format1(buffer, "Content-Length: %i\r\n", &req->size);
Http_SetRequestHeaders(req); Http_SetRequestHeaders(req);
String_AppendConst(buffer, "\r\n"); String_AppendConst(buffer, "\r\n");
@ -541,7 +559,7 @@ static void HttpClient_Serialise(struct HttpClientState* state) {
} /* TODO post redirect handling */ } /* TODO post redirect handling */
} }
static cc_result HttpClient_SendRequest(cc_socket socket, struct HttpClientState* state) { static cc_result HttpClient_SendRequest(struct HttpClientState* state) {
char inputBuffer[16384]; char inputBuffer[16384];
cc_string inputMsg; cc_string inputMsg;
cc_uint32 wrote; cc_uint32 wrote;
@ -552,7 +570,7 @@ static cc_result HttpClient_SendRequest(cc_socket socket, struct HttpClientState
HttpClient_Serialise(state); HttpClient_Serialise(state);
/* TODO check wrote is >= inputMsg.length */ /* TODO check wrote is >= inputMsg.length */
return Socket_Write(socket, inputBuffer, inputMsg.length, &wrote); return Socket_Write(state->conn.socket, inputBuffer, inputMsg.length, &wrote);
} }
@ -650,6 +668,7 @@ static cc_result HttpClient_Process(struct HttpClientState* state, char* buffer,
Http_BufferEnsure(req, read); Http_BufferEnsure(req, read);
Mem_Copy(req->data + req->size, buffer + offset, read); Mem_Copy(req->data + req->size, buffer + offset, read);
Http_BufferExpanded(req, read); Http_BufferExpanded(req, read);
offset += read;
if (req->size >= req->contentLength) { if (req->size >= req->contentLength) {
state->state = HTTP_RESPONSE_STATE_DONE; state->state = HTTP_RESPONSE_STATE_DONE;
@ -737,13 +756,13 @@ static cc_result HttpClient_Process(struct HttpClientState* state, char* buffer,
return 0; return 0;
} }
static cc_result HttpClient_ParseResponse(cc_socket socket, struct HttpClientState* state) { static cc_result HttpClient_ParseResponse(struct HttpClientState* state) {
char buffer[8192]; char buffer[8192];
cc_uint32 total; cc_uint32 total;
cc_result res; cc_result res;
for (;;) { for (;;) {
res = Socket_Read(socket, buffer, 8192, &total); res = Socket_Read(state->conn.socket, buffer, 8192, &total);
if (res) return res; if (res) return res;
if (total == 0) return ERR_END_OF_STREAM; if (total == 0) return ERR_END_OF_STREAM;
@ -764,6 +783,7 @@ static cc_result HttpClient_HandleRedirect(struct HttpClientState* state) {
HttpUrl_Parse(&url, &state->url); HttpUrl_Parse(&url, &state->url);
HttpRequest_Free(state->req); HttpRequest_Free(state->req);
Platform_Log1(" Redirecting to: %s", &url);
state->req->contentLength = 0; /* TODO */ state->req->contentLength = 0; /* TODO */
return 0; return 0;
} else { } else {
@ -777,24 +797,23 @@ static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_st
static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* urlStr) { static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* urlStr) {
struct HttpClientState state; struct HttpClientState state;
cc_socket socket = 0;
cc_result res;
int redirects = 0; int redirects = 0;
cc_result res;
HttpClientState_Init(&state); HttpClientState_Init(&state);
HttpUrl_Parse(urlStr, &state.url); HttpUrl_Parse(urlStr, &state.url);
state.req = req; state.req = req;
for (;;) { for (;;) {
res = Socket_Connect(&socket, &state.url.address, state.url.port, false); res = HttpConnection_Open(&state.conn, &state.url);
if (res) { Socket_Close(socket); return res; } if (res) { HttpConnection_Close(&state.conn); return res; }
res = HttpClient_SendRequest(socket, &state); res = HttpClient_SendRequest(&state);
if (res) { Socket_Close(socket); return res; } if (res) { HttpConnection_Close(&state.conn); return res; }
res = HttpClient_ParseResponse(socket, &state); res = HttpClient_ParseResponse(&state);
http_curProgress = 100; http_curProgress = 100;
Socket_Close(socket); HttpConnection_Close(&state.conn);
if (res || !HttpClient_IsRedirect(req)) break; if (res || !HttpClient_IsRedirect(req)) break;
/* TODO BETTER ERROR CODE */ /* TODO BETTER ERROR CODE */

View File

@ -182,15 +182,17 @@ void Json_Init(struct JsonContext* ctx, STRING_REF char* str, int len) {
String_InitArray(ctx->_tmp, ctx->_tmpBuffer); String_InitArray(ctx->_tmp, ctx->_tmpBuffer);
} }
void Json_Parse(struct JsonContext* ctx) { cc_bool Json_Parse(struct JsonContext* ctx) {
int token; int token;
do { do {
token = Json_ConsumeToken(ctx); token = Json_ConsumeToken(ctx);
Json_ConsumeValue(token, ctx); Json_ConsumeValue(token, ctx);
} while (token != TOKEN_NONE); } while (token != TOKEN_NONE);
return !ctx->failed;
} }
static void Json_Handle(cc_uint8* data, cc_uint32 len, static cc_bool Json_Handle(cc_uint8* data, cc_uint32 len,
JsonOnValue onVal, JsonOnNew newArr, JsonOnNew newObj) { JsonOnValue onVal, JsonOnNew newArr, JsonOnNew newObj) {
struct JsonContext ctx; struct JsonContext ctx;
/* NOTE: classicube.net uses \u JSON for non ASCII, no need to UTF8 convert characters here */ /* NOTE: classicube.net uses \u JSON for non ASCII, no need to UTF8 convert characters here */
@ -199,7 +201,7 @@ static void Json_Handle(cc_uint8* data, cc_uint32 len,
if (onVal) ctx.OnValue = onVal; if (onVal) ctx.OnValue = onVal;
if (newArr) ctx.OnNewArray = newArr; if (newArr) ctx.OnNewArray = newArr;
if (newObj) ctx.OnNewObject = newObj; if (newObj) ctx.OnNewObject = newObj;
Json_Parse(&ctx); return Json_Parse(&ctx);
} }
@ -254,7 +256,10 @@ static void GetTokenTask_OnValue(struct JsonContext* ctx, const cc_string* str)
} }
static void GetTokenTask_Handle(cc_uint8* data, cc_uint32 len) { static void GetTokenTask_Handle(cc_uint8* data, cc_uint32 len) {
Json_Handle(data, len, GetTokenTask_OnValue, NULL, NULL); static cc_string err_msg = String_FromConst("Error parsing get login token response JSON");
cc_bool success = Json_Handle(data, len, GetTokenTask_OnValue, NULL, NULL);
if (!success) Logger_WarnFunc(&err_msg);
} }
void GetTokenTask_Run(void) { void GetTokenTask_Run(void) {
@ -310,7 +315,10 @@ static void SignInTask_OnValue(struct JsonContext* ctx, const cc_string* str) {
} }
static void SignInTask_Handle(cc_uint8* data, cc_uint32 len) { static void SignInTask_Handle(cc_uint8* data, cc_uint32 len) {
Json_Handle(data, len, SignInTask_OnValue, NULL, NULL); static cc_string err_msg = String_FromConst("Error parsing sign in response JSON");
cc_bool success = Json_Handle(data, len, SignInTask_OnValue, NULL, NULL);
if (!success) Logger_WarnFunc(&err_msg);
} }
static void SignInTask_Append(cc_string* dst, const char* key, const cc_string* value) { static void SignInTask_Append(cc_string* dst, const char* key, const cc_string* value) {
@ -438,7 +446,10 @@ static void FetchServersTask_Next(struct JsonContext* ctx) {
} }
static void FetchServersTask_Handle(cc_uint8* data, cc_uint32 len) { static void FetchServersTask_Handle(cc_uint8* data, cc_uint32 len) {
static cc_string err_msg = String_FromConst("Error parsing servers list response JSON");
int count; int count;
cc_bool success;
Mem_Free(FetchServersTask.servers); Mem_Free(FetchServersTask.servers);
Mem_Free(FetchServersTask.orders); Mem_Free(FetchServersTask.orders);
Session_Save(); Session_Save();
@ -448,9 +459,10 @@ static void FetchServersTask_Handle(cc_uint8* data, cc_uint32 len) {
FetchServersTask.orders = NULL; FetchServersTask.orders = NULL;
FetchServersTask.numServers = 0; FetchServersTask.numServers = 0;
Json_Handle(data, len, NULL, NULL, FetchServersTask_Count); success = Json_Handle(data, len, NULL, NULL, FetchServersTask_Count);
count = FetchServersTask.numServers; count = FetchServersTask.numServers;
if (!success) Logger_WarnFunc(&err_msg);
if (count <= 0) return; if (count <= 0) return;
FetchServersTask.servers = (struct ServerInfo*)Mem_Alloc(count, sizeof(struct ServerInfo), "servers list"); FetchServersTask.servers = (struct ServerInfo*)Mem_Alloc(count, sizeof(struct ServerInfo), "servers list");
FetchServersTask.orders = (cc_uint16*)Mem_Alloc(count, 2, "servers order"); FetchServersTask.orders = (cc_uint16*)Mem_Alloc(count, 2, "servers order");
@ -507,7 +519,10 @@ static void CheckUpdateTask_OnValue(struct JsonContext* ctx, const cc_string* st
} }
static void CheckUpdateTask_Handle(cc_uint8* data, cc_uint32 len) { static void CheckUpdateTask_Handle(cc_uint8* data, cc_uint32 len) {
Json_Handle(data, len, CheckUpdateTask_OnValue, NULL, NULL); static cc_string err_msg = String_FromConst("Error parsing update check response JSON");
cc_bool success = Json_Handle(data, len, CheckUpdateTask_OnValue, NULL, NULL);
if (!success) Logger_WarnFunc(&err_msg);
} }
void CheckUpdateTask_Run(void) { void CheckUpdateTask_Run(void) {

View File

@ -29,7 +29,7 @@ struct JsonContext {
void Json_Init(struct JsonContext* ctx, STRING_REF char* str, int len); void Json_Init(struct JsonContext* ctx, STRING_REF char* str, int len);
/* Parses the JSON text, invoking callbacks when value/array/objects are read. */ /* Parses the JSON text, invoking callbacks when value/array/objects are read. */
/* NOTE: DO NOT persist the value argument in OnValue. */ /* NOTE: DO NOT persist the value argument in OnValue. */
void Json_Parse(struct JsonContext* ctx); cc_bool Json_Parse(struct JsonContext* ctx);
/* Represents all known details about a server. */ /* Represents all known details about a server. */
struct ServerInfo { struct ServerInfo {