add HTTP POST support

This commit is contained in:
Brad Parker 2017-03-02 17:36:25 -05:00
parent c99d83f15c
commit c31823aa94
5 changed files with 109 additions and 9 deletions

View File

@ -34,7 +34,7 @@ RETRO_BEGIN_DECLS
struct http_t;
struct http_connection_t;
struct http_connection_t *net_http_connection_new(const char *url);
struct http_connection_t *net_http_connection_new(const char *url, const char *method, const char *data);
bool net_http_connection_iterate(struct http_connection_t *conn);

View File

@ -68,10 +68,12 @@ struct http_connection_t
char *location;
char *urlcopy;
char *scan;
char *methodcopy;
char *contenttypecopy;
char *postdatacopy;
int port;
};
static int net_http_new_socket(const char *domain, int port)
{
int ret;
@ -140,7 +142,7 @@ static char* urlencode(const char* url)
return ret;
}
struct http_connection_t *net_http_connection_new(const char *url)
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,
@ -151,6 +153,12 @@ struct http_connection_t *net_http_connection_new(const char *url)
conn->urlcopy = urlencode(url);
if (method)
conn->methodcopy = strdup(method);
if (data)
conn->postdatacopy = strdup(data);
if (!conn->urlcopy)
goto error;
@ -166,7 +174,13 @@ struct http_connection_t *net_http_connection_new(const char *url)
error:
if (conn->urlcopy)
free(conn->urlcopy);
if (conn->methodcopy)
free(conn->methodcopy);
if (conn->postdatacopy)
free(conn->postdatacopy);
conn->urlcopy = NULL;
conn->methodcopy = NULL;
conn->postdatacopy = NULL;
free(conn);
return NULL;
}
@ -221,6 +235,20 @@ void net_http_connection_free(struct http_connection_t *conn)
if (conn->urlcopy)
free(conn->urlcopy);
if (conn->methodcopy)
free(conn->methodcopy);
if (conn->contenttypecopy)
free(conn->contenttypecopy);
if (conn->postdatacopy)
free(conn->postdatacopy);
conn->urlcopy = NULL;
conn->methodcopy = NULL;
conn->contenttypecopy = NULL;
conn->postdatacopy = NULL;
free(conn);
}
@ -245,7 +273,16 @@ struct http_t *net_http_new(struct http_connection_t *conn)
error = false;
/* This is a bit lazy, but it works. */
net_http_send_str(fd, &error, "GET /");
if (conn->methodcopy)
{
net_http_send_str(fd, &error, conn->methodcopy);
net_http_send_str(fd, &error, " /");
}
else
{
net_http_send_str(fd, &error, "GET /");
}
net_http_send_str(fd, &error, conn->location);
net_http_send_str(fd, &error, " HTTP/1.1\r\n");
@ -263,9 +300,45 @@ struct http_t *net_http_new(struct http_connection_t *conn)
}
net_http_send_str(fd, &error, "\r\n");
/* this is not being set anywhere yet */
if (conn->contenttypecopy)
{
net_http_send_str(fd, &error, "Content-Type: ");
net_http_send_str(fd, &error, conn->contenttypecopy);
net_http_send_str(fd, &error, "\r\n");
}
if (conn->methodcopy && string_is_equal(conn->methodcopy, "POST"))
{
size_t post_len, len;
char *len_str;
if (!conn->postdatacopy)
goto error;
if (!conn->contenttypecopy)
net_http_send_str(fd, &error, "Content-Type: application/x-www-form-urlencoded\r\n");
net_http_send_str(fd, &error, "Content-Length: ");
post_len = strlen(conn->postdatacopy);
len = snprintf(NULL, 0, "%lu", post_len);
len_str = (char*)malloc(len);
snprintf(len_str, len, "%lu", post_len);
len_str[len - 1] = '\0';
net_http_send_str(fd, &error, len_str);
}
net_http_send_str(fd, &error, "Connection: close\r\n");
net_http_send_str(fd, &error, "\r\n");
if (conn->methodcopy && string_is_equal(conn->methodcopy, "POST"))
net_http_send_str(fd, &error, conn->postdatacopy);
if (error)
goto error;
@ -287,6 +360,13 @@ struct http_t *net_http_new(struct http_connection_t *conn)
return state;
error:
if (conn->methodcopy)
free(conn->methodcopy);
if (conn->contenttypecopy)
free(conn->contenttypecopy);
conn->methodcopy = NULL;
conn->contenttypecopy = NULL;
conn->postdatacopy = NULL;
if (fd >= 0)
socket_close(fd);
if (state)

View File

@ -30,7 +30,7 @@ int net_http_get(const char **result, size_t *size, const char *url, retro_time_
int ret = NET_HTTP_GET_OK;
struct http_t* http = NULL;
retro_time_t t0 = cpu_features_get_time_usec();
struct http_connection_t *conn = net_http_connection_new(url);
struct http_connection_t *conn = net_http_connection_new(url, "GET", NULL);
*result = NULL;

View File

@ -235,12 +235,11 @@ static bool task_http_retriever(retro_task_t *task, void *data)
return true;
}
void *task_push_http_transfer(const char *url, bool mute, const char *type,
static void* task_push_http_transfer_generic(struct http_connection_t *conn, const char *url, bool mute, const char *type,
retro_task_callback_t cb, void *user_data)
{
task_finder_data_t find_data;
char tmp[255];
struct http_connection_t *conn = NULL;
retro_task_t *t = NULL;
http_handle_t *http = NULL;
@ -259,8 +258,6 @@ void *task_push_http_transfer(const char *url, bool mute, const char *type,
return NULL;
}
conn = net_http_connection_new(url);
if (!conn)
return NULL;
@ -308,6 +305,26 @@ error:
return NULL;
}
void* task_push_http_transfer(const char *url, bool mute, const char *type,
retro_task_callback_t cb, void *user_data)
{
struct http_connection_t *conn;
conn = net_http_connection_new(url, "GET", NULL);
return task_push_http_transfer_generic(conn, url, mute, type, cb, user_data);
}
void* task_push_http_post_transfer(const char *url, const char *post_data, bool mute,
const char *type, retro_task_callback_t cb, void *user_data)
{
struct http_connection_t *conn;
conn = net_http_connection_new(url, "POST", post_data);
return task_push_http_transfer_generic(conn, url, mute, type, cb, user_data);
}
task_retriever_info_t *http_task_get_transfer_list(void)
{
task_retriever_data_t retrieve_data;

View File

@ -86,6 +86,9 @@ typedef struct
void *task_push_http_transfer(const char *url, bool mute, const char *type,
retro_task_callback_t cb, void *userdata);
void *task_push_http_post_transfer(const char *url, const char *post_data, bool mute, const char *type,
retro_task_callback_t cb, void *userdata);
task_retriever_info_t *http_task_get_transfer_list(void);
bool task_push_wifi_scan(void);