/cpw/tomkiewicz/http: 704de181d1d2: Let's request
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Sat Oct 13 06:06:22 EDT 2012
Changeset: 704de181d1d219c8806dec7c75f21fa1cda0817a
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2012-10-13 12:06 +0200
Branch: default
URL: http://hg.pidgin.im/cpw/tomkiewicz/http/rev/704de181d1d2
Description:
Let's request
diffstat:
libpurple/http.c | 149 ++++++++++++++++++++++++++++++++++++++++++-
libpurple/protocols/gg/gg.c | 4 +-
2 files changed, 148 insertions(+), 5 deletions(-)
diffs (234 lines):
diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -61,6 +61,8 @@ struct _PurpleHttpConnection
PurpleHttpResponse *response;
PurpleHttpSocket socket;
+ GString *request_header;
+ int request_header_written;
};
struct _PurpleHttpResponse
@@ -109,6 +111,10 @@ static void purple_http_dummy_success(Pu
static void _purple_http_disconnect(PurpleHttpConnection *hc);
+static void _purple_http_gen_headers(PurpleHttpConnection *hc);
+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,
@@ -138,13 +144,125 @@ static void _purple_http_error(PurpleHtt
purple_http_conn_cancel(hc);
}
+static void _purple_http_gen_headers(PurpleHttpConnection *hc)
+{
+ GString *h;
+ PurpleHttpURL *url;
+ PurpleProxyInfo *proxy;
+
+ g_return_if_fail(hc != NULL);
+
+ if (hc->request_header != NULL)
+ return;
+
+ url = hc->url;
+ proxy = purple_proxy_get_setup(hc->gc ?
+ purple_connection_get_account(hc->gc) : NULL);
+
+ hc->request_header = h = g_string_new("");
+ hc->request_header_written = 0;
+
+ g_string_append_printf(h, "GET %s HTTP/%s\r\n", url->path, "1.1");
+ g_string_append_printf(h, "Host: %s\r\n", url->host);
+ g_string_append_printf(h, "Connection: close\r\n");
+
+ /* TODO: don't put here, if exists */
+ g_string_append_printf(h, "Accept: */*\r\n");
+
+
+ if (purple_proxy_info_get_username(proxy) != NULL &&
+ (purple_proxy_info_get_type(proxy) == PURPLE_PROXY_USE_ENVVAR ||
+ purple_proxy_info_get_type(proxy) == PURPLE_PROXY_HTTP)) {
+ purple_debug_error("http",
+ "Proxy authorization is not yet supported\n");
+ }
+
+ g_string_append_printf(h, "\r\n");
+
+ if (purple_debug_is_unsafe() && purple_debug_is_verbose()) {
+ purple_debug_misc("http", "Generated request headers:\n%s",
+ h->str);
+ }
+}
+
+static void _purple_http_recv(gpointer _hc, gint fd, PurpleInputCondition cond)
+{
+ PurpleHttpConnection *hc = _hc;
+ PurpleHttpSocket *hs = &hc->socket;
+ int len;
+ char buf[4096];
+
+ purple_debug_misc("http", "[tmp] reading...\n");
+
+ if (hs->is_ssl)
+ len = purple_ssl_read(hs->ssl_connection, buf, sizeof(buf));
+ else
+ len = read(fd, buf, sizeof(buf));
+
+ if (len < 0 && errno == EAGAIN)
+ return;
+
+ if (len < 0) {
+ _purple_http_error(hc, _("Error reading from %s: %s"),
+ hc->url->host, g_strerror(errno));
+ return;
+ }
+
+ if (len == 0) { /* TODO: eof only? */
+ purple_http_dummy_success(hc);
+ }
+}
+
+static void _purple_http_recv_ssl(gpointer _hc,
+ PurpleSslConnection *ssl_connection, PurpleInputCondition cond)
+{
+ _purple_http_recv(_hc, -1, cond);
+}
+
static void _purple_http_send(gpointer _hc, gint fd, PurpleInputCondition cond)
-{ // url_fetch_send_cb
+{
PurpleHttpConnection *hc = _hc;
+ PurpleHttpSocket *hs = &hc->socket;
+ int written, write_len;
+ const gchar *write_from;
+
+ _purple_http_gen_headers(hc);
purple_debug_misc("http", "[tmp] sending...\n");
- purple_http_dummy_success(hc);
+ write_from = hc->request_header->str + hc->request_header_written;
+ write_len = hc->request_header->len - hc->request_header_written;
+
+ if (hs->is_ssl)
+ written = purple_ssl_write(hs->ssl_connection,
+ write_from, write_len);
+ else
+ written = write(hs->fd, write_from, write_len);
+
+ if (written < 0 && errno == EAGAIN)
+ return;
+
+ if (written < 0) {
+ _purple_http_error(hc, _("Error writing to %s: %s"),
+ hc->url->host, g_strerror(errno));
+ return;
+ }
+
+ hc->request_header_written += written;
+ if (hc->request_header_written < hc->request_header->len)
+ return;
+
+ /* TODO: write contents */
+
+ /* request is completely written, let's read the response */
+ purple_input_remove(hs->inpa);
+ hs->inpa = 0;
+ if (hs->is_ssl)
+ purple_ssl_input_add(hs->ssl_connection,
+ _purple_http_recv_ssl, hc);
+ else
+ hs->inpa = purple_input_add(hs->fd, PURPLE_INPUT_READ,
+ _purple_http_recv, hc);
}
static void _purple_http_connected_raw(gpointer _hc, gint fd,
@@ -164,7 +282,6 @@ static void _purple_http_connected_raw(g
hs->fd = fd;
hs->inpa = purple_input_add(fd, PURPLE_INPUT_WRITE,
_purple_http_send, hc);
- _purple_http_send(hc, fd, PURPLE_INPUT_WRITE);
}
static void _purple_http_connected_ssl(gpointer _hc,
@@ -176,7 +293,6 @@ static void _purple_http_connected_ssl(g
hs->fd = hs->ssl_connection->fd;
hs->inpa = purple_input_add(hs->fd, PURPLE_INPUT_WRITE,
_purple_http_send, hc);
- _purple_http_send(hc, hs->fd, PURPLE_INPUT_WRITE);
}
static void _purple_http_connected_ssl_error(
@@ -197,6 +313,10 @@ static void _purple_http_disconnect(Purp
g_return_if_fail(hc != NULL);
+ if (hc->request_header)
+ g_string_free(hc->request_header, TRUE);
+ hc->request_header = NULL;
+
hs = &hc->socket;
if (!hs->is_connected)
@@ -246,6 +366,12 @@ static gboolean _purple_http_reconnect(P
hc->socket.is_ssl = is_ssl;
if (is_ssl) {
+ if (!purple_ssl_is_supported()) {
+ _purple_http_error(hc, _("Unable to connect to %s: %s"),
+ url->host, _("Server requires TLS/SSL, "
+ "but no TLS/SSL support was found."));
+ return FALSE;
+ }
hc->socket.ssl_connection = purple_ssl_connect(account,
url->host, url->port,
_purple_http_connected_ssl,
@@ -337,6 +463,9 @@ static void purple_http_connection_free(
purple_http_request_unref(hc->request);
purple_http_response_free(hc->response);
+ if (hc->request_header)
+ g_string_free(hc->request_header, TRUE);
+
if (hc->socket.is_connected)
purple_debug_error("http", "Socket is still connected!");
@@ -487,6 +616,18 @@ static PurpleHttpURL * purple_http_url_p
return NULL;
}
+ if (parsed_url->host[0] != '\0' &&
+ parsed_url->path[0] != '\0') {
+ gchar *tmp = parsed_url->path;
+ parsed_url->path = g_strdup_printf("/%s", parsed_url->path);
+ g_free(tmp);
+ }
+
+ if (parsed_url->path[0] == '\0') {
+ g_free(parsed_url->path);
+ parsed_url->path = g_strdup("/");
+ }
+
return parsed_url;
}
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -78,7 +78,9 @@ static void ggp_action_test_http(PurpleP
purple_debug_info("http-test", "Testing http...\n");
// purple_http_get(gc, "http://www.wasilczyk.pl/x_ip_simple.htm",
// ggp_test_http_cb, NULL);
- purple_http_get(gc, "https://google.com",
+// purple_http_get(gc, "http://google.com",
+// ggp_test_http_cb, NULL);
+ purple_http_get(gc, "http://wp.pl",
ggp_test_http_cb, NULL);
purple_debug_info("http-test", "Testing http started.\n");
}
More information about the Commits
mailing list