mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 12:05:14 -04:00
Windows: Return a different error code when DNS lookup cannot resolve the provided hostname to an IP address
Also slightly reorganise http client code, and support root relative URLs for redirection now
This commit is contained in:
parent
e9e77ad03b
commit
85c8d22568
@ -97,6 +97,8 @@ enum CC_ERRORS {
|
||||
JAVA_ERR_JOBJECT_FLAGS = 0xCCDED04BUL, /* Object class isn't deserialisable */
|
||||
JAVA_ERR_JVALUE_TYPE = 0xCCDED04CUL, /* Value data type is invalid */
|
||||
|
||||
SOCK_ERR_UNKNOWN_HOST = 0xCCDED04FUL, /* Host (e.g. "example.com") was unknown to the DNS server(s) */
|
||||
|
||||
NBT_ERR_UNKNOWN = 0xCCDED050UL, /* NBT tag has an unknown type */
|
||||
CW_ERR_ROOT_TAG = 0xCCDED051UL, /* NBT root tag isn't a Compound tag */
|
||||
CW_ERR_STRING_LEN = 0xCCDED052UL, /* NBT string is too long */
|
||||
|
@ -421,12 +421,9 @@ static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* url) {
|
||||
#include "PackedCol.h"
|
||||
#include "SSL.h"
|
||||
|
||||
static void HttpBackend_Init(void) {
|
||||
SSLBackend_Init(httpsVerify);
|
||||
//httpOnly = true; // TODO: insecure
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------HttpUrl---------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
/* Components of a URL */
|
||||
struct HttpUrl {
|
||||
cc_bool https; /* Whether HTTPS or just HTTP protocol */
|
||||
@ -476,7 +473,28 @@ static void HttpUrl_Parse(const cc_string* src, struct HttpUrl* url) {
|
||||
HttpUrl_EncodeUrl(&url->resource, &resource);
|
||||
}
|
||||
|
||||
static cc_result HttpUrl_ResolveRedirect(struct HttpUrl* parts, const cc_string* url) {
|
||||
/* absolute URL */
|
||||
if (String_IndexOfConst(url, "http://") == 0 || String_IndexOfConst(url, "https://") == 0) {
|
||||
HttpUrl_Parse(url, parts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Root relative URL */
|
||||
if (url->buffer[0] == '/' && (url->length == 1 || url->buffer[1] != '/')) {
|
||||
parts->resource.length = 0;
|
||||
HttpUrl_EncodeUrl(&parts->resource, url);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO scheme relative or relative URL or invalid */
|
||||
return HTTP_ERR_RELATIVE;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*------------------------------------------------------HttpConnection-----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
struct HttpConnection {
|
||||
cc_socket socket;
|
||||
void* sslCtx;
|
||||
@ -501,7 +519,7 @@ static cc_result HttpConnection_Open(struct HttpConnection* conn, const struct H
|
||||
return SSL_Init(conn->socket, &host, &conn->sslCtx);
|
||||
}
|
||||
|
||||
static cc_result HttpConnection_Read(struct HttpConnection* conn, cc_uint8* data, cc_uint32 count, cc_uint32* read) {
|
||||
static cc_result HttpConnection_Read(struct HttpConnection* conn, cc_uint8* data, cc_uint32 count, cc_uint32* read) {
|
||||
if (conn->sslCtx)
|
||||
return SSL_Read(conn->sslCtx, data, count, read);
|
||||
return Socket_Read(conn->socket, data, count, read);
|
||||
@ -526,6 +544,9 @@ static void HttpConnection_Close(struct HttpConnection* conn) {
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------HttpClient-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
enum HTTP_RESPONSE_STATE {
|
||||
HTTP_RESPONSE_STATE_HEADER,
|
||||
HTTP_RESPONSE_STATE_BODY_INIT,
|
||||
@ -805,18 +826,22 @@ static cc_bool HttpClient_IsRedirect(struct HttpRequest* req) {
|
||||
}
|
||||
|
||||
static cc_result HttpClient_HandleRedirect(struct HttpClientState* state) {
|
||||
cc_string url = state->location;
|
||||
/* TODO wrong */
|
||||
if (String_IndexOfConst(&url, "http://") == 0 || String_IndexOfConst(&url, "https://")) {
|
||||
HttpUrl_Parse(&url, &state->url);
|
||||
HttpRequest_Free(state->req);
|
||||
cc_result res = HttpUrl_ResolveRedirect(&state->url, &state->location);
|
||||
if (res) return res;
|
||||
|
||||
Platform_Log1(" Redirecting to: %s", &url);
|
||||
state->req->contentLength = 0; /* TODO */
|
||||
return 0;
|
||||
} else {
|
||||
return HTTP_ERR_RELATIVE;
|
||||
}
|
||||
HttpRequest_Free(state->req);
|
||||
Platform_Log1(" Redirecting to: %s", &state->location);
|
||||
state->req->contentLength = 0; /* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-----------------------------------------------Http backend implementation-----------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void HttpBackend_Init(void) {
|
||||
SSLBackend_Init(httpsVerify);
|
||||
//httpOnly = true; // TODO: insecure
|
||||
}
|
||||
|
||||
static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_string* value) {
|
||||
|
@ -99,6 +99,7 @@ static const char* GetCCErrorDesc(cc_result res) {
|
||||
case NBT_ERR_ARR_TOO_SMALL:return "ByteArray NBT tag too small";
|
||||
|
||||
case HTTP_ERR_NO_SSL: return "HTTPS URLs are not currently supported";
|
||||
case SOCK_ERR_UNKNOWN_HOST: return "Host could not be resolved to an IP address";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -457,9 +457,18 @@ static void LoadWinsockFuncs(void) {
|
||||
static int ParseHost(void* dst, char* host, int port) {
|
||||
SOCKADDR_IN* addr4 = (SOCKADDR_IN*)dst;
|
||||
struct hostent* res;
|
||||
cc_result wsa_res;
|
||||
|
||||
res = _gethostbyname(host);
|
||||
if (!res || res->h_addrtype != AF_INET) return false;
|
||||
if (!res) {
|
||||
wsa_res = _WSAGetLastError();
|
||||
|
||||
if (wsa_res == WSAHOST_NOT_FOUND) return SOCK_ERR_UNKNOWN_HOST;
|
||||
return ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
/* per MSDN, should only be getting AF_INET returned from this */
|
||||
if (res->h_addrtype != AF_INET) return ERR_INVALID_ARGUMENT;
|
||||
|
||||
/* Must have at least one IPv4 address */
|
||||
if (!res->h_addr_list[0]) return false;
|
||||
@ -467,7 +476,7 @@ static int ParseHost(void* dst, char* host, int port) {
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = _htons(port);
|
||||
addr4->sin_addr = *(IN_ADDR*)res->h_addr_list[0];
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Socket_ParseAddress(void* dst, INT* size, const cc_string* address, int port) {
|
||||
@ -479,13 +488,13 @@ static int Socket_ParseAddress(void* dst, INT* size, const cc_string* address, i
|
||||
*size = sizeof(*addr4);
|
||||
if (!_WSAStringToAddressW(addr.uni, AF_INET, NULL, addr4, size)) {
|
||||
addr4->sin_port = _htons(port);
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*size = sizeof(*addr6);
|
||||
if (!_WSAStringToAddressW(addr.uni, AF_INET6, NULL, addr6, size)) {
|
||||
addr6->sin6_port = _htons(port);
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*size = sizeof(*addr4);
|
||||
@ -495,7 +504,7 @@ static int Socket_ParseAddress(void* dst, INT* size, const cc_string* address, i
|
||||
int Socket_ValidAddress(const cc_string* address) {
|
||||
SOCKADDR_STORAGE addr;
|
||||
INT addrSize;
|
||||
return Socket_ParseAddress(&addr, &addrSize, address, 0);
|
||||
return Socket_ParseAddress(&addr, &addrSize, address, 0) == 0;
|
||||
}
|
||||
|
||||
cc_result Socket_Connect(cc_socket* s, const cc_string* address, int port, cc_bool nonblocking) {
|
||||
@ -503,9 +512,9 @@ cc_result Socket_Connect(cc_socket* s, const cc_string* address, int port, cc_bo
|
||||
cc_result res;
|
||||
INT addrSize;
|
||||
|
||||
*s = -1;
|
||||
if (!Socket_ParseAddress(&addr, &addrSize, address, port))
|
||||
return ERR_INVALID_ARGUMENT;
|
||||
*s = -1;
|
||||
res = Socket_ParseAddress(&addr, &addrSize, address, port);
|
||||
if (res) return res;
|
||||
|
||||
*s = _socket(addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (*s == -1) return _WSAGetLastError();
|
||||
|
Loading…
x
Reference in New Issue
Block a user