diff --git a/src/Errors.h b/src/Errors.h index 72685438a..b003ee1fe 100644 --- a/src/Errors.h +++ b/src/Errors.h @@ -132,5 +132,7 @@ enum CC_ERRORS { HTTP_ERR_RELATIVE = 0xCCDED069UL, /* Unsupported relative URL format */ HTTP_ERR_INVALID_BODY= 0xCCDED06AUL, /* HTTP message doesn't have Content-Length or use Chunked transfer encoding */ HTTP_ERR_CHUNK_SIZE = 0xCCDED06BUL, /* HTTP message chunk has negative size/length */ + + SSL_ERR_CONTEXT_DEAD = 0xCCDED070UL, /* Server shutdown the SSL context and it must be recreated */ }; #endif diff --git a/src/Http_Worker.c b/src/Http_Worker.c index 5234d34b9..bfed67cc5 100644 --- a/src/Http_Worker.c +++ b/src/Http_Worker.c @@ -943,9 +943,25 @@ static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_st String_Format2((cc_string*)req->meta, "%c:%s\r\n", key, value); } +static cc_result HttpBackend_PerformRequest(struct HttpClientState* state) { + cc_result 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; } + + res = HttpClient_ParseResponse(state); + if (res) HttpConnection_Close(state->conn); + + return res; +} + static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* urlStr) { struct HttpClientState state; - int redirects = 0; + cc_bool retried = false; + int redirects = 0; cc_result res; HttpClientState_Init(&state); @@ -953,15 +969,13 @@ static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* urlStr) { state.req = req; for (;;) { - 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; } - - res = HttpClient_ParseResponse(&state); - http_curProgress = 100; - if (state.autoClose) HttpConnection_Close(state.conn); + res = HttpBackend_PerformRequest(&state); + /* TODO: Can we handle this while preserving the TCP connection */ + if (res == SSL_ERR_CONTEXT_DEAD && !retried) { + Platform_LogConst("KILLIN AND TRYIN AGAIN"); + res = HttpBackend_PerformRequest(&state); + retried = true; + } if (res || !HttpClient_IsRedirect(req)) break; if (redirects >= 20) return HTTP_ERR_REDIRECTS; diff --git a/src/SSL.c b/src/SSL.c index b391229db..c750ad0e8 100644 --- a/src/SSL.c +++ b/src/SSL.c @@ -347,6 +347,9 @@ cc_result SSL_Read(void* ctx_, cc_uint8* data, cc_uint32 count, cc_uint32* read) return SSL_ReadDecrypted(ctx, data, count, read); } + + /* TODO properly close the connection with TLS shutdown when this happens */ + if (sec == SEC_I_CONTEXT_EXPIRED) return SSL_ERR_CONTEXT_DEAD; if (sec != SEC_E_INCOMPLETE_MESSAGE) return sec; /* SEC_E_INCOMPLETE_MESSAGE case - still need to read more data from the server first */