From 6cd0dae2a8f616150ea7174fce321d7fb7cea9dc Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 25 May 2023 22:43:17 +1000 Subject: [PATCH] Http client: able to login now --- src/Http_Worker.c | 43 +++++++++++++++++++++++++++++++------------ src/LWeb.c | 31 +++++++++++++++++++++++-------- src/LWeb.h | 2 +- 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/Http_Worker.c b/src/Http_Worker.c index b9ab1fa02..fcd443d4e 100644 --- a/src/Http_Worker.c +++ b/src/Http_Worker.c @@ -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 { HTTP_RESPONSE_STATE_HEADER, HTTP_RESPONSE_STATE_BODY_INIT, @@ -496,6 +511,7 @@ enum HTTP_RESPONSE_STATE { struct HttpClientState { enum HTTP_RESPONSE_STATE state; + struct HttpConnection conn; struct HttpRequest* req; int chunked; 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, "User-Agent", &userAgent); + if (req->data) String_Format1(buffer, "Content-Length: %i\r\n", &req->size); + Http_SetRequestHeaders(req); String_AppendConst(buffer, "\r\n"); @@ -541,7 +559,7 @@ static void HttpClient_Serialise(struct HttpClientState* state) { } /* 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]; cc_string inputMsg; cc_uint32 wrote; @@ -552,7 +570,7 @@ static cc_result HttpClient_SendRequest(cc_socket socket, struct HttpClientState HttpClient_Serialise(state); /* 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); Mem_Copy(req->data + req->size, buffer + offset, read); Http_BufferExpanded(req, read); + offset += read; if (req->size >= req->contentLength) { state->state = HTTP_RESPONSE_STATE_DONE; @@ -737,13 +756,13 @@ static cc_result HttpClient_Process(struct HttpClientState* state, char* buffer, return 0; } -static cc_result HttpClient_ParseResponse(cc_socket socket, struct HttpClientState* state) { +static cc_result HttpClient_ParseResponse(struct HttpClientState* state) { char buffer[8192]; cc_uint32 total; cc_result res; for (;;) { - res = Socket_Read(socket, buffer, 8192, &total); + res = Socket_Read(state->conn.socket, buffer, 8192, &total); if (res) return res; 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); HttpRequest_Free(state->req); + Platform_Log1(" Redirecting to: %s", &url); state->req->contentLength = 0; /* TODO */ return 0; } 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) { struct HttpClientState state; - cc_socket socket = 0; - cc_result res; int redirects = 0; + cc_result res; HttpClientState_Init(&state); HttpUrl_Parse(urlStr, &state.url); state.req = req; for (;;) { - res = Socket_Connect(&socket, &state.url.address, state.url.port, false); - if (res) { Socket_Close(socket); return res; } + res = HttpConnection_Open(&state.conn, &state.url); + if (res) { HttpConnection_Close(&state.conn); return res; } - res = HttpClient_SendRequest(socket, &state); - if (res) { Socket_Close(socket); return res; } + res = HttpClient_SendRequest(&state); + if (res) { HttpConnection_Close(&state.conn); return res; } - res = HttpClient_ParseResponse(socket, &state); + res = HttpClient_ParseResponse(&state); http_curProgress = 100; - Socket_Close(socket); + HttpConnection_Close(&state.conn); if (res || !HttpClient_IsRedirect(req)) break; /* TODO BETTER ERROR CODE */ diff --git a/src/LWeb.c b/src/LWeb.c index 641b764c0..3cf6124a7 100644 --- a/src/LWeb.c +++ b/src/LWeb.c @@ -182,15 +182,17 @@ void Json_Init(struct JsonContext* ctx, STRING_REF char* str, int len) { String_InitArray(ctx->_tmp, ctx->_tmpBuffer); } -void Json_Parse(struct JsonContext* ctx) { +cc_bool Json_Parse(struct JsonContext* ctx) { int token; do { token = Json_ConsumeToken(ctx); Json_ConsumeValue(token, ctx); } 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) { struct JsonContext ctx; /* 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 (newArr) ctx.OnNewArray = newArr; 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) { - 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) { @@ -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) { - 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) { @@ -438,7 +446,10 @@ static void FetchServersTask_Next(struct JsonContext* ctx) { } 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; + cc_bool success; Mem_Free(FetchServersTask.servers); Mem_Free(FetchServersTask.orders); Session_Save(); @@ -448,9 +459,10 @@ static void FetchServersTask_Handle(cc_uint8* data, cc_uint32 len) { FetchServersTask.orders = NULL; FetchServersTask.numServers = 0; - Json_Handle(data, len, NULL, NULL, FetchServersTask_Count); - count = FetchServersTask.numServers; + success = Json_Handle(data, len, NULL, NULL, FetchServersTask_Count); + count = FetchServersTask.numServers; + if (!success) Logger_WarnFunc(&err_msg); if (count <= 0) return; FetchServersTask.servers = (struct ServerInfo*)Mem_Alloc(count, sizeof(struct ServerInfo), "servers list"); 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) { - 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) { diff --git a/src/LWeb.h b/src/LWeb.h index 54aa1659c..66e919931 100644 --- a/src/LWeb.h +++ b/src/LWeb.h @@ -29,7 +29,7 @@ struct JsonContext { void Json_Init(struct JsonContext* ctx, STRING_REF char* str, int len); /* Parses the JSON text, invoking callbacks when value/array/objects are read. */ /* 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. */ struct ServerInfo {