359 lines
5.9 KiB
C++
359 lines
5.9 KiB
C++
|
|
#include "fmod_settings.h"
|
||
|
|
|
||
|
|
#include "fmod.h"
|
||
|
|
#include "fmod_net.h"
|
||
|
|
#include "fmod_string.h"
|
||
|
|
#include "fmod_memory.h"
|
||
|
|
|
||
|
|
#include <stdlib.h>
|
||
|
|
|
||
|
|
|
||
|
|
enum
|
||
|
|
{
|
||
|
|
FMOD_NET_VERSION_HTTP_1_0 = 0,
|
||
|
|
FMOD_NET_VERSION_HTTP_1_1,
|
||
|
|
FMOD_NET_VERSION_ICY,
|
||
|
|
CT_FMOD_NET_VERSION
|
||
|
|
};
|
||
|
|
|
||
|
|
static const char *FMOD_Net_VersionString[CT_FMOD_NET_VERSION] =
|
||
|
|
{
|
||
|
|
"HTTP/1.0",
|
||
|
|
"HTTP/1.1",
|
||
|
|
"ICY",
|
||
|
|
};
|
||
|
|
|
||
|
|
static const char base64_code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||
|
|
|
||
|
|
char *FMOD_Net_ProxyString = 0;
|
||
|
|
char *FMOD_Net_ProxyHostname = 0;
|
||
|
|
int FMOD_Net_ProxyPort = 0;
|
||
|
|
char *FMOD_Net_ProxyAuth = 0; // Base64 encoded, user:pass pair
|
||
|
|
int FMOD_Net_Timeout = 5000;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT FMOD_Net_ParseHTTPStatus(char *buf, int buflen, int *version, int *statuscode)
|
||
|
|
{
|
||
|
|
int i, j, k;
|
||
|
|
|
||
|
|
for (i=0;(i < buflen) && (buf[i] != 0) && (buf[i] != ' ');i++);
|
||
|
|
|
||
|
|
if (i < buflen)
|
||
|
|
{
|
||
|
|
buf[i] = 0;
|
||
|
|
|
||
|
|
for (j=0;j < CT_FMOD_NET_VERSION;j++)
|
||
|
|
{
|
||
|
|
if (!FMOD_strcmp(buf, FMOD_Net_VersionString[j]))
|
||
|
|
{
|
||
|
|
*version = j;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (j < CT_FMOD_NET_VERSION)
|
||
|
|
{
|
||
|
|
i++;
|
||
|
|
k = i;
|
||
|
|
for (;(i < buflen) && (buf[i] != 0) && (buf[i] != ' ');i++);
|
||
|
|
|
||
|
|
if (i < buflen)
|
||
|
|
{
|
||
|
|
buf[i] = 0;
|
||
|
|
*statuscode = atoi(&buf[k]);
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return FMOD_ERR_INVALID_PARAM;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
#define CHECK_LENGTH if (out_cnt == outbuflen) { return FMOD_ERR_INVALID_PARAM; }
|
||
|
|
|
||
|
|
FMOD_RESULT FMOD_Net_EncodeBase64(char *inbuf, char *outbuf, int outbuflen)
|
||
|
|
{
|
||
|
|
int bits = 0, char_count = 0, out_cnt = 0, c;
|
||
|
|
|
||
|
|
if (!inbuf || !outbuf)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_INVALID_PARAM;
|
||
|
|
}
|
||
|
|
|
||
|
|
while ((c = (unsigned char)*inbuf++))
|
||
|
|
{
|
||
|
|
bits += c;
|
||
|
|
char_count++;
|
||
|
|
if (char_count == 3)
|
||
|
|
{
|
||
|
|
CHECK_LENGTH
|
||
|
|
outbuf[out_cnt++] = base64_code[bits >> 18];
|
||
|
|
CHECK_LENGTH
|
||
|
|
outbuf[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
|
||
|
|
CHECK_LENGTH
|
||
|
|
outbuf[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
|
||
|
|
CHECK_LENGTH
|
||
|
|
outbuf[out_cnt++] = base64_code[bits & 0x3f];
|
||
|
|
bits = 0;
|
||
|
|
char_count = 0;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
bits <<= 8;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (char_count != 0)
|
||
|
|
{
|
||
|
|
bits <<= 16 - (8 * char_count);
|
||
|
|
CHECK_LENGTH
|
||
|
|
outbuf[out_cnt++] = base64_code[bits >> 18];
|
||
|
|
CHECK_LENGTH
|
||
|
|
outbuf[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
|
||
|
|
if (char_count == 1)
|
||
|
|
{
|
||
|
|
CHECK_LENGTH
|
||
|
|
outbuf[out_cnt++] = '=';
|
||
|
|
CHECK_LENGTH
|
||
|
|
outbuf[out_cnt++] = '=';
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
CHECK_LENGTH
|
||
|
|
outbuf[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
|
||
|
|
CHECK_LENGTH
|
||
|
|
outbuf[out_cnt++] = '=';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
CHECK_LENGTH
|
||
|
|
outbuf[out_cnt] = 0;
|
||
|
|
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT FMOD_Net_SetProxy(const char *proxy)
|
||
|
|
{
|
||
|
|
char *hostname, *username, *tmp, *p;
|
||
|
|
FMOD_RESULT result;
|
||
|
|
int port;
|
||
|
|
|
||
|
|
if (FMOD_Net_ProxyString)
|
||
|
|
{
|
||
|
|
FMOD_Memory_Free(FMOD_Net_ProxyString);
|
||
|
|
FMOD_Net_ProxyString = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (FMOD_Net_ProxyHostname)
|
||
|
|
{
|
||
|
|
FMOD_Memory_Free(FMOD_Net_ProxyHostname);
|
||
|
|
FMOD_Net_ProxyHostname = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (FMOD_Net_ProxyAuth)
|
||
|
|
{
|
||
|
|
FMOD_Memory_Free(FMOD_Net_ProxyAuth);
|
||
|
|
FMOD_Net_ProxyAuth = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
FMOD_Net_ProxyPort = 0;
|
||
|
|
|
||
|
|
if (FMOD_strlen(proxy))
|
||
|
|
{
|
||
|
|
p = FMOD_strdup(proxy);
|
||
|
|
if (!p)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/*
|
||
|
|
Setting proxy server to null here
|
||
|
|
*/
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
FMOD_Net_ProxyString = FMOD_strdup(proxy);
|
||
|
|
if (!FMOD_Net_ProxyString)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
|
||
|
|
hostname = FMOD_strstr(p, "@");
|
||
|
|
if (hostname)
|
||
|
|
{
|
||
|
|
*hostname = 0;
|
||
|
|
hostname++;
|
||
|
|
username = p;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
hostname = p;
|
||
|
|
username = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (username)
|
||
|
|
{
|
||
|
|
char buf[4096];
|
||
|
|
|
||
|
|
result = FMOD_Net_EncodeBase64(username, buf, 4095);
|
||
|
|
if (result != FMOD_OK)
|
||
|
|
{
|
||
|
|
FMOD_Memory_Free(p);
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
FMOD_Net_ProxyAuth = FMOD_strdup(buf);
|
||
|
|
if (!FMOD_Net_ProxyAuth)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
tmp = FMOD_strstr(hostname, ":");
|
||
|
|
if (tmp)
|
||
|
|
{
|
||
|
|
*tmp = 0;
|
||
|
|
tmp++;
|
||
|
|
port = atoi(tmp);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
port = 80;
|
||
|
|
}
|
||
|
|
|
||
|
|
FMOD_Net_ProxyHostname = FMOD_strdup(hostname);
|
||
|
|
if (!FMOD_Net_ProxyHostname)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
|
||
|
|
FMOD_Net_ProxyPort = port;
|
||
|
|
|
||
|
|
FMOD_Memory_Free(p);
|
||
|
|
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT FMOD_Net_GetProxy(char *proxy, int proxylen)
|
||
|
|
{
|
||
|
|
if (proxy && proxylen)
|
||
|
|
{
|
||
|
|
if (FMOD_Net_ProxyString)
|
||
|
|
{
|
||
|
|
FMOD_strncpy(proxy, FMOD_Net_ProxyString, proxylen);
|
||
|
|
proxy[proxylen - 1] = 0;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
proxy[0] = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT FMOD_Net_SetTimeout(int timeout)
|
||
|
|
{
|
||
|
|
FMOD_Net_Timeout = timeout;
|
||
|
|
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
[
|
||
|
|
[DESCRIPTION]
|
||
|
|
|
||
|
|
[PARAMETERS]
|
||
|
|
|
||
|
|
[RETURN_VALUE]
|
||
|
|
|
||
|
|
[REMARKS]
|
||
|
|
|
||
|
|
[SEE_ALSO]
|
||
|
|
]
|
||
|
|
*/
|
||
|
|
FMOD_RESULT FMOD_Net_GetTimeout(int *timeout)
|
||
|
|
{
|
||
|
|
if (!timeout)
|
||
|
|
{
|
||
|
|
return FMOD_ERR_INVALID_PARAM;
|
||
|
|
}
|
||
|
|
|
||
|
|
*timeout = FMOD_Net_Timeout;
|
||
|
|
|
||
|
|
return FMOD_OK;
|
||
|
|
}
|