mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 10:05:44 -04:00
HttpClient: WIP on basic connection cache
This commit is contained in:
parent
0f5b32c0b9
commit
9b7dd188c5
@ -498,6 +498,7 @@ static cc_result HttpUrl_ResolveRedirect(struct HttpUrl* parts, const cc_string*
|
||||
struct HttpConnection {
|
||||
cc_socket socket;
|
||||
void* sslCtx;
|
||||
cc_bool valid;
|
||||
};
|
||||
|
||||
static cc_result HttpConnection_Open(struct HttpConnection* conn, const struct HttpUrl* url) {
|
||||
@ -515,6 +516,7 @@ static cc_result HttpConnection_Open(struct HttpConnection* conn, const struct H
|
||||
conn->sslCtx = NULL;
|
||||
if ((res = Socket_Connect(&conn->socket, &host, portNum, false))) return res;
|
||||
|
||||
conn->valid = true;
|
||||
if (!url->https) return 0;
|
||||
return SSL_Init(conn->socket, &host, &conn->sslCtx);
|
||||
}
|
||||
@ -541,6 +543,53 @@ static void HttpConnection_Close(struct HttpConnection* conn) {
|
||||
Socket_Close(conn->socket);
|
||||
conn->socket = 0;
|
||||
}
|
||||
conn->valid = false;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-----------------------------------------------------Connection Pool-----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static struct ConnectionPoolEntry {
|
||||
struct HttpConnection conn;
|
||||
cc_string addr;
|
||||
char addrBuffer[STRING_SIZE];
|
||||
cc_bool https;
|
||||
} connection_pool[10];
|
||||
|
||||
static cc_result ConnectionPool_Insert(int i, struct HttpConnection** conn, const struct HttpUrl* url) {
|
||||
struct ConnectionPoolEntry* e = &connection_pool[i];
|
||||
*conn = &e->conn;
|
||||
|
||||
String_InitArray(e->addr, e->addrBuffer);
|
||||
String_Copy(&e->addr, &url->address);
|
||||
e->https = url->https;
|
||||
return HttpConnection_Open(&e->conn, url);
|
||||
}
|
||||
|
||||
static cc_result ConnectionPool_Open(struct HttpConnection** conn, const struct HttpUrl* url) {
|
||||
struct ConnectionPoolEntry* e;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Array_Elems(connection_pool); i++)
|
||||
{
|
||||
e = &connection_pool[i];
|
||||
if (e->conn.valid && e->https == url->https && String_Equals(&e->addr, &url->address)) {
|
||||
*conn = &connection_pool[i].conn;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < Array_Elems(connection_pool); i++)
|
||||
{
|
||||
e = &connection_pool[i];
|
||||
if (!e->conn.valid) return ConnectionPool_Insert(i, conn, url);
|
||||
}
|
||||
|
||||
/* TODO: Should we be consistent in which entry gets evicted? */
|
||||
i = (cc_uint8)Stopwatch_Measure() % Array_Elems(connection_pool);
|
||||
HttpConnection_Close(&connection_pool[i].conn);
|
||||
return ConnectionPool_Insert(i, conn, url);
|
||||
}
|
||||
|
||||
|
||||
@ -561,7 +610,7 @@ enum HTTP_RESPONSE_STATE {
|
||||
|
||||
struct HttpClientState {
|
||||
enum HTTP_RESPONSE_STATE state;
|
||||
struct HttpConnection conn;
|
||||
struct HttpConnection* conn;
|
||||
struct HttpRequest* req;
|
||||
int chunked;
|
||||
int chunkRead, chunkLength;
|
||||
@ -620,7 +669,7 @@ static cc_result HttpClient_SendRequest(struct HttpClientState* state) {
|
||||
HttpClient_Serialise(state);
|
||||
|
||||
/* TODO check that wrote is >= inputMsg.length */
|
||||
return HttpConnection_Write(&state->conn, inputBuffer, inputMsg.length, &wrote);
|
||||
return HttpConnection_Write(state->conn, inputBuffer, inputMsg.length, &wrote);
|
||||
}
|
||||
|
||||
|
||||
@ -811,7 +860,7 @@ static cc_result HttpClient_ParseResponse(struct HttpClientState* state) {
|
||||
cc_result res;
|
||||
|
||||
for (;;) {
|
||||
res = HttpConnection_Read(&state->conn, buffer, 8192, &total);
|
||||
res = HttpConnection_Read(state->conn, buffer, 8192, &total);
|
||||
if (res) return res;
|
||||
if (total == 0) return ERR_END_OF_STREAM;
|
||||
|
||||
@ -858,15 +907,14 @@ static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* urlStr) {
|
||||
state.req = req;
|
||||
|
||||
for (;;) {
|
||||
res = HttpConnection_Open(&state.conn, &state.url);
|
||||
if (res) { HttpConnection_Close(&state.conn); return res; }
|
||||
res = ConnectionPool_Open(&state.conn, &state.url);
|
||||
if (res) { HttpConnection_Close(state.conn); return res; }
|
||||
|
||||
res = HttpClient_SendRequest(&state);
|
||||
if (res) { HttpConnection_Close(&state.conn); return res; }
|
||||
if (res) { HttpConnection_Close(state.conn); return res; }
|
||||
|
||||
res = HttpClient_ParseResponse(&state);
|
||||
http_curProgress = 100;
|
||||
HttpConnection_Close(&state.conn);
|
||||
|
||||
if (res || !HttpClient_IsRedirect(req)) break;
|
||||
if (redirects >= 20) return HTTP_ERR_REDIRECTS;
|
||||
|
Loading…
x
Reference in New Issue
Block a user