add full urlencoder and encode lobby announcement POST data

This commit is contained in:
Brad Parker 2017-03-04 12:19:01 -05:00
parent 9c19f16539
commit ad6733b519
3 changed files with 60 additions and 39 deletions

View file

@ -68,6 +68,8 @@ uint8_t* net_http_data(struct http_t *state, size_t* len, bool accept_error);
/* Cleans up all memory. */
void net_http_delete(struct http_t *state);
void net_http_urlencode_full(char **dest, const char *source);
RETRO_END_DECLS
#endif

View file

@ -74,6 +74,45 @@ struct http_connection_t
int port;
};
static char urlencode_lut[256];
static bool urlencode_lut_inited = false;
void urlencode_lut_init()
{
unsigned i;
urlencode_lut_inited = true;
for (i = 0; i < 256; i++)
{
urlencode_lut[i] = isalnum(i) || i == '*' || i == '-' || i == '.' || i == '_' ? i : (i == ' ') ? '+' : 0;
}
}
/* caller is responsible for deleting the destination buffer */
void net_http_urlencode_full(char **dest, const char *source) {
/* Assume every character will be encoded, so we need 3 times the space. */
size_t len = strlen(source) * 3 + 1;
char *enc;
if (!urlencode_lut_inited)
urlencode_lut_init();
enc = (char*)calloc(1, len);
*dest = enc;
for (; *source; source++)
{
if (urlencode_lut[(int)*source]) sprintf(enc, "%c", urlencode_lut[(int)*source]);
else sprintf(enc, "%%%02X", *source);
while (*++(enc));
}
(*dest)[len - 1] = '\0';
}
static int net_http_new_socket(const char *domain, int port)
{
int ret;
@ -108,50 +147,16 @@ static void net_http_send_str(int fd, bool *error, const char *text)
*error = true;
}
static char* urlencode(const char* url)
{
unsigned i;
unsigned outpos = 0;
unsigned outlen = 0;
char *ret = NULL;
for (i = 0; url[i] != '\0'; i++)
{
outlen++;
if (url[i] == ' ')
outlen += 2;
}
ret = (char*)malloc(outlen + 1);
if (!ret)
return NULL;
for (i = 0; url[i]; i++)
{
if (url[i] == ' ')
{
ret[outpos++] = '%';
ret[outpos++] = '2';
ret[outpos++] = '0';
}
else
ret[outpos++] = url[i];
}
ret[outpos] = '\0';
return ret;
}
struct http_connection_t *net_http_connection_new(const char *url, const char *method, const char *data)
{
char **domain = NULL;
struct http_connection_t *conn = (struct http_connection_t*)calloc(1,
struct http_connection_t *conn = (struct http_connection_t*)calloc(1,
sizeof(struct http_connection_t));
if (!conn)
if (!conn || !url)
return NULL;
conn->urlcopy = urlencode(url);
conn->urlcopy = strdup(url);
if (method)
conn->methodcopy = strdup(method);

View file

@ -22,6 +22,7 @@
#include <compat/strl.h>
#include <retro_assert.h>
#include <string/stdstring.h>
#include <net/net_http.h>
#include "netplay_private.h"
@ -525,6 +526,15 @@ static void netplay_announce(void)
rarch_system_info_t *system = NULL;
settings_t *settings = config_get_ptr();
uint32_t *content_crc_ptr = NULL;
char *username;
char *corename;
char *gamename;
char *coreversion;
net_http_urlencode_full(&username, settings->username);
net_http_urlencode_full(&corename, system->info.library_name);
net_http_urlencode_full(&gamename, !string_is_empty(path_basename(path_get(RARCH_PATH_BASENAME))) ? path_basename(path_get(RARCH_PATH_BASENAME)) : "N/A");
net_http_urlencode_full(&coreversion, system->info.library_version);
content_get_crc(&content_crc_ptr);
@ -534,11 +544,15 @@ static void netplay_announce(void)
snprintf(buf, sizeof(buf), "username=%s&core_name=%s&core_version=%s&"
"game_name=%s&game_crc=%d&port=%d&has_password=%d&has_spectate_password=%d",
settings->username, system->info.library_name, system->info.library_version,
!string_is_empty(path_basename(path_get(RARCH_PATH_BASENAME))) ? path_basename(path_get(RARCH_PATH_BASENAME)) : "N/A", *content_crc_ptr,
username, corename, coreversion, gamename, *content_crc_ptr,
settings->netplay.port, settings->netplay.password ? 1 : 0, settings->netplay.spectate_password ? 1 : 0);
task_push_http_post_transfer(url, buf, true, NULL, netplay_announce_cb, NULL);
free(username);
free(corename);
free(gamename);
free(coreversion);
}
int16_t input_state_net(unsigned port, unsigned device,