/soc/2013/ankitkv/gobjectification: 1312b429aba1: Merged default...
Ankit Vani
a at nevitus.org
Fri Jul 19 18:56:31 EDT 2013
Changeset: 1312b429aba19a2a603cbf5c7583f3d9e7eebd67
Author: Ankit Vani <a at nevitus.org>
Date: 2013-07-20 04:26 +0530
Branch: soc.2013.gobjectification
URL: https://hg.pidgin.im/soc/2013/ankitkv/gobjectification/rev/1312b429aba1
Description:
Merged default branch
diffstat:
libpurple/http.c | 402 +++++++++++++++++++++++++++++++++++++-----------------
libpurple/http.h | 63 ++++++++
2 files changed, 340 insertions(+), 125 deletions(-)
diffs (truncated from 665 to 300 lines):
diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -44,6 +44,9 @@ typedef struct _PurpleHttpSocket PurpleH
typedef struct _PurpleHttpHeaders PurpleHttpHeaders;
+typedef void (*PurpleHttpSocketConnectCb)(PurpleHttpSocket *hs,
+ const gchar *error, gpointer user_data);
+
struct _PurpleHttpSocket
{
gboolean is_ssl;
@@ -51,6 +54,9 @@ struct _PurpleHttpSocket
PurpleProxyConnectData *raw_connection;
int fd;
guint inpa;
+ PurpleInputFunction watch_cb;
+ PurpleHttpSocketConnectCb connect_cb;
+ gpointer cb_data;
};
struct _PurpleHttpRequest
@@ -61,6 +67,7 @@ struct _PurpleHttpRequest
gchar *method;
PurpleHttpHeaders *headers;
PurpleHttpCookieJar *cookie_jar;
+ PurpleHttpKeepalivePool *keepalive_pool;
gchar *contents;
int contents_length;
@@ -81,12 +88,13 @@ struct _PurpleHttpConnection
PurpleHttpCallback callback;
gpointer user_data;
gboolean is_reading;
+ gboolean is_keepalive;
PurpleHttpURL *url;
PurpleHttpRequest *request;
PurpleHttpResponse *response;
- PurpleHttpSocket socket;
+ PurpleHttpSocket *socket;
GString *request_header;
int request_header_written, request_contents_written;
gboolean main_header_got, headers_got;
@@ -153,6 +161,11 @@ struct _PurpleHttpCookieJar
GHashTable *tab;
};
+struct _PurpleHttpKeepalivePool
+{
+ int ref_count;
+};
+
static time_t purple_http_rfc1123_to_time(const gchar *str);
static gboolean purple_http_request_is_method(PurpleHttpRequest *request,
@@ -247,6 +260,163 @@ static time_t purple_http_rfc1123_to_tim
return t;
}
+/*** HTTP Sockets *************************************************************/
+
+static void _purple_http_socket_connected_raw(gpointer _hs, gint fd,
+ const gchar *error_message)
+{
+ PurpleHttpSocket *hs = _hs;
+
+ hs->raw_connection = NULL;
+
+ if (fd == -1 || error_message != NULL) {
+ if (error_message == NULL)
+ error_message = _("Unknown error");
+ hs->connect_cb(hs, error_message, hs->cb_data);
+ return;
+ }
+
+ hs->fd = fd;
+ hs->connect_cb(hs, NULL, hs->cb_data);
+}
+
+static void _purple_http_socket_connected_ssl(gpointer _hs,
+ PurpleSslConnection *ssl_connection, PurpleInputCondition cond)
+{
+ PurpleHttpSocket *hs = _hs;
+
+ hs->fd = hs->ssl_connection->fd;
+ hs->connect_cb(hs, NULL, hs->cb_data);
+}
+
+static void _purple_http_socket_connected_ssl_error(
+ PurpleSslConnection *ssl_connection, PurpleSslErrorType error,
+ gpointer _hs)
+{
+ PurpleHttpSocket *hs = _hs;
+
+ hs->ssl_connection = NULL;
+ hs->connect_cb(hs, purple_ssl_strerror(error), hs->cb_data);
+}
+
+static PurpleHttpSocket *
+purple_http_socket_connect_new(PurpleConnection *gc, const gchar *host, int port, gboolean is_ssl, PurpleHttpSocketConnectCb cb, gpointer user_data)
+{
+ PurpleHttpSocket *hs = g_new0(PurpleHttpSocket, 1);
+ PurpleAccount *account = NULL;
+
+ if (gc != NULL)
+ account = purple_connection_get_account(gc);
+
+ hs->is_ssl = is_ssl;
+ hs->connect_cb = cb;
+ hs->cb_data = user_data;
+ hs->fd = -1;
+
+ if (is_ssl) {
+ if (!purple_ssl_is_supported()) {
+ g_free(hs);
+ return NULL;
+ }
+
+ hs->ssl_connection = purple_ssl_connect(account,
+ host, port,
+ _purple_http_socket_connected_ssl,
+ _purple_http_socket_connected_ssl_error, hs);
+/* TODO
+ purple_ssl_set_compatibility_level(hs->ssl_connection,
+ PURPLE_SSL_COMPATIBILITY_SECURE);
+*/
+ } else {
+ hs->raw_connection = purple_proxy_connect(gc, account,
+ host, port,
+ _purple_http_socket_connected_raw, hs);
+ }
+
+ if (hs->ssl_connection == NULL &&
+ hs->raw_connection == NULL) {
+ g_free(hs);
+ return NULL;
+ }
+
+ return hs;
+}
+
+static int
+purple_http_socket_read(PurpleHttpSocket *hs, gchar *buf, size_t len)
+{
+ g_return_val_if_fail(hs != NULL, -1);
+ g_return_val_if_fail(buf != NULL, -1);
+
+ if (hs->is_ssl)
+ return purple_ssl_read(hs->ssl_connection, buf, sizeof(buf));
+ else
+ return read(hs->fd, buf, sizeof(buf));
+}
+
+static int
+purple_http_socket_write(PurpleHttpSocket *hs, const gchar *buf, size_t len)
+{
+ g_return_val_if_fail(hs != NULL, -1);
+ g_return_val_if_fail(buf != NULL, -1);
+
+ if (hs->is_ssl)
+ return purple_ssl_write(hs->ssl_connection, buf, len);
+ else
+ return write(hs->fd, buf, len);
+}
+
+static void _purple_http_socket_watch_recv_ssl(gpointer _hs,
+ PurpleSslConnection *ssl_connection, PurpleInputCondition cond)
+{
+ PurpleHttpSocket *hs = _hs;
+
+ g_return_if_fail(hs != NULL);
+
+ hs->watch_cb(hs->cb_data, hs->fd, cond);
+}
+
+static void
+purple_http_socket_watch(PurpleHttpSocket *hs, PurpleInputCondition cond,
+ PurpleInputFunction func, gpointer user_data)
+{
+ g_return_if_fail(hs != NULL);
+
+ if (hs->inpa > 0)
+ purple_input_remove(hs->inpa);
+ hs->inpa = 0;
+
+ if (cond == PURPLE_INPUT_READ && hs->is_ssl) {
+ hs->watch_cb = func;
+ hs->cb_data = user_data;
+ purple_ssl_input_add(hs->ssl_connection,
+ _purple_http_socket_watch_recv_ssl, hs);
+ }
+ else
+ hs->inpa = purple_input_add(hs->fd, cond, func, user_data);
+}
+
+static void
+purple_http_socket_close_free(PurpleHttpSocket *hs)
+{
+ if (hs == NULL)
+ return;
+
+ if (hs->inpa != 0)
+ purple_input_remove(hs->inpa);
+
+ if (hs->is_ssl) {
+ if (hs->ssl_connection != NULL)
+ purple_ssl_close(hs->ssl_connection);
+ } else {
+ if (hs->raw_connection != NULL)
+ purple_proxy_connect_cancel(hs->raw_connection);
+ if (hs->fd > 0)
+ close(hs->fd);
+ }
+ g_free(hs);
+}
+
/*** Headers collection *******************************************************/
static PurpleHttpHeaders * purple_http_headers_new(void);
@@ -431,18 +601,8 @@ static void _purple_http_gen_headers(Pur
static gboolean _purple_http_recv_loopbody(PurpleHttpConnection *hc, gint fd);
static void _purple_http_recv(gpointer _hc, gint fd,
PurpleInputCondition cond);
-static void _purple_http_recv_ssl(gpointer _hc,
- PurpleSslConnection *ssl_connection, PurpleInputCondition cond);
static void _purple_http_send(gpointer _hc, gint fd, PurpleInputCondition cond);
-static void _purple_http_connected_raw(gpointer _hc, gint source,
- const gchar *error_message);
-static void _purple_http_connected_ssl(gpointer _hc,
- PurpleSslConnection *ssl_connection, PurpleInputCondition cond);
-static void _purple_http_connected_ssl_error(
- PurpleSslConnection *ssl_connection, PurpleSslErrorType error,
- gpointer _hc);
-
/* closes current connection (if exists), estabilishes one and proceeds with
* request */
static gboolean _purple_http_reconnect(PurpleHttpConnection *hc);
@@ -511,8 +671,11 @@ static void _purple_http_gen_headers(Pur
if (!purple_http_headers_get(hdrs, "host"))
g_string_append_printf(h, "Host: %s\r\n", url->host);
- if (!purple_http_headers_get(hdrs, "connection"))
- g_string_append(h, "Connection: close\r\n");
+ if (!purple_http_headers_get(hdrs, "connection")) {
+ g_string_append(h, "Connection: ");
+ g_string_append(h, hc->is_keepalive ?
+ "Keep-Alive\r\n" : "close\r\n");
+ }
if (!purple_http_headers_get(hdrs, "accept"))
g_string_append(h, "Accept: */*\r\n");
@@ -525,7 +688,7 @@ static void _purple_http_gen_headers(Pur
}
if (proxy_http)
- g_string_append(h, "Proxy-Connection: close\r\n");
+ g_string_append(h, "Proxy-Connection: close\r\n"); /* TEST: proxy+KeepAlive */
proxy_username = purple_proxy_info_get_username(proxy);
if (proxy_http && proxy_username != NULL && proxy_username[0] != '\0') {
@@ -548,7 +711,7 @@ static void _purple_http_gen_headers(Pur
proxy_auth);
g_string_append_printf(h, "Proxy-Authorization: NTLM %s\r\n",
ntlm_type1);
- g_string_append(h, "Proxy-Connection: Close\r\n");
+ g_string_append(h, "Proxy-Connection: close\r\n"); /* TEST: proxy+KeepAlive */
memset(proxy_auth, 0, strlen(proxy_auth));
g_free(proxy_auth);
@@ -799,15 +962,11 @@ static gboolean _purple_http_recv_body(P
static gboolean _purple_http_recv_loopbody(PurpleHttpConnection *hc, gint fd)
{
- PurpleHttpSocket *hs = &hc->socket;
int len;
gchar buf[4096];
gboolean got_anything;
- if (hs->is_ssl)
- len = purple_ssl_read(hs->ssl_connection, buf, sizeof(buf));
- else
- len = read(fd, buf, sizeof(buf));
+ len = purple_http_socket_read(hc->socket, buf, sizeof(buf));
got_anything = (len > 0);
if (len < 0 && errno == EAGAIN)
@@ -946,12 +1105,6 @@ static void _purple_http_recv(gpointer _
while (_purple_http_recv_loopbody(hc, fd));
}
-static void _purple_http_recv_ssl(gpointer _hc,
- PurpleSslConnection *ssl_connection, PurpleInputCondition cond)
-{
- _purple_http_recv(_hc, -1, cond);
-}
-
More information about the Commits
mailing list