diff options
author | Marius Halden <marius.h@lden.org> | 2018-04-19 10:23:08 +0200 |
---|---|---|
committer | Marius Halden <marius.h@lden.org> | 2018-04-19 10:23:08 +0200 |
commit | db02ac8971379f9fee2f3a618bb08b8076d1a83d (patch) | |
tree | 0e7d46bad6162509300aa73ae6d77e571a5b26d0 /protocols/msn/gw.c | |
parent | 6dc54671e368d03ed447d0fbd2d662af6c36b7fd (diff) | |
parent | 246b98bbdf221448fd7a638fea04373ed1612de5 (diff) |
Merge branch 'master' into patched-master
Diffstat (limited to 'protocols/msn/gw.c')
-rw-r--r-- | protocols/msn/gw.c | 223 |
1 files changed, 0 insertions, 223 deletions
diff --git a/protocols/msn/gw.c b/protocols/msn/gw.c deleted file mode 100644 index f9cc74fd..00000000 --- a/protocols/msn/gw.c +++ /dev/null @@ -1,223 +0,0 @@ -#include "bitlbee.h" -#include "lib/http_client.h" -#include "msn.h" - -#define GATEWAY_HOST "geo.gateway.messenger.live.com" -#define GATEWAY_PORT 443 - -#define REQUEST_TEMPLATE \ - "POST /gateway/gateway.dll?SessionID=%s&%s HTTP/1.1\r\n" \ - "Host: %s\r\n" \ - "Content-Length: %zd\r\n" \ - "\r\n" \ - "%s" - -static gboolean msn_gw_poll_timeout(gpointer data, gint source, b_input_condition cond); - -struct msn_gw *msn_gw_new(struct im_connection *ic) -{ - struct msn_gw *gw = g_new0(struct msn_gw, 1); - gw->last_host = g_strdup(GATEWAY_HOST); - gw->port = GATEWAY_PORT; - gw->ssl = (GATEWAY_PORT == 443); - gw->poll_timeout = -1; - gw->write_timeout = -1; - gw->ic = ic; - gw->md = ic->proto_data; - gw->in = g_byte_array_new(); - gw->out = g_byte_array_new(); - return gw; -} - -void msn_gw_free(struct msn_gw *gw) -{ - if (gw->poll_timeout != -1) { - b_event_remove(gw->poll_timeout); - } - - if (gw->write_timeout != -1) { - b_event_remove(gw->write_timeout); - } - - g_byte_array_free(gw->in, TRUE); - g_byte_array_free(gw->out, TRUE); - g_free(gw->session_id); - g_free(gw->last_host); - g_free(gw); -} - -static struct msn_gw *msn_gw_from_ic(struct im_connection *ic) -{ - if (g_slist_find(msn_connections, ic) == NULL) { - return NULL; - } else { - struct msn_data *md = ic->proto_data; - return md->gw; - } -} - -static gboolean msn_gw_parse_session_header(struct msn_gw *gw, char *value) -{ - int i; - char **subvalues; - gboolean closed = FALSE; - - subvalues = g_strsplit(value, "; ", 0); - - for (i = 0; subvalues[i]; i++) { - if (strcmp(subvalues[i], "Session=close") == 0) { - /* gateway closed, signal the death of the socket */ - closed = TRUE; - } else if (g_str_has_prefix(subvalues[i], "SessionID=")) { - /* copy the part after the = to session_id*/ - g_free(gw->session_id); - gw->session_id = g_strdup(subvalues[i] + 10); - } - } - - g_strfreev(subvalues); - - return !closed; -} - -void msn_gw_callback(struct http_request *req) -{ - struct msn_gw *gw; - char *value; - - if (!(gw = msn_gw_from_ic(req->data))) { - return; - } - - gw->waiting = FALSE; - gw->polling = FALSE; - - if (req->status_code != 200 || !req->reply_body) { - gw->callback(gw->md, -1, B_EV_IO_READ); - return; - } - - if (getenv("BITLBEE_DEBUG")) { - fprintf(stderr, "\n\x1b[90mHTTP:%s\n", req->reply_body); - fprintf(stderr, "\n\x1b[97m\n"); - } - - if ((value = get_rfc822_header(req->reply_headers, "X-MSN-Messenger", 0))) { - if (!msn_gw_parse_session_header(gw, value)) { - gw->callback(gw->md, -1, B_EV_IO_READ); - g_free(value); - return; - } - g_free(value); - } - - if ((value = get_rfc822_header(req->reply_headers, "X-MSN-Host", 0))) { - g_free(gw->last_host); - gw->last_host = value; /* transfer */ - } - - if (req->body_size) { - g_byte_array_append(gw->in, (const guint8 *) req->reply_body, req->body_size); - - if (!gw->callback(gw->md, -1, B_EV_IO_READ)) { - return; - } - } - - if (gw->poll_timeout != -1) { - b_event_remove(gw->poll_timeout); - } - gw->poll_timeout = b_timeout_add(500, msn_gw_poll_timeout, gw->ic); - -} - -void msn_gw_dorequest(struct msn_gw *gw, char *args) -{ - char *request = NULL; - char *body = NULL; - size_t bodylen = 0; - - if (gw->out) { - bodylen = gw->out->len; - g_byte_array_append(gw->out, (guint8 *) "", 1); /* nullnullnull */ - body = (char *) g_byte_array_free(gw->out, FALSE); - gw->out = g_byte_array_new(); - } - - if (!bodylen && !args) { - args = "Action=poll&Lifespan=60"; - gw->polling = TRUE; - } - - request = g_strdup_printf(REQUEST_TEMPLATE, - gw->session_id ? : "", args ? : "", gw->last_host, bodylen, body ? : ""); - - http_dorequest(gw->last_host, gw->port, gw->ssl, request, msn_gw_callback, gw->ic); - gw->open = TRUE; - gw->waiting = TRUE; - - g_free(body); - g_free(request); -} - -void msn_gw_open(struct msn_gw *gw) -{ - msn_gw_dorequest(gw, "Action=open&Server=NS"); -} - -static gboolean msn_gw_poll_timeout(gpointer data, gint source, b_input_condition cond) -{ - struct msn_gw *gw; - - if (!(gw = msn_gw_from_ic(data))) { - return FALSE; - } - - gw->poll_timeout = -1; - if (!gw->waiting) { - msn_gw_dorequest(gw, NULL); - } - return FALSE; -} - -ssize_t msn_gw_read(struct msn_gw *gw, char **buf) -{ - size_t bodylen; - if (!gw->open) { - return 0; - } - - bodylen = gw->in->len; - g_byte_array_append(gw->in, (guint8 *) "", 1); /* nullnullnull */ - *buf = (char *) g_byte_array_free(gw->in, FALSE); - gw->in = g_byte_array_new(); - return bodylen; -} - -static gboolean msn_gw_write_cb(gpointer data, gint source, b_input_condition cond) -{ - struct msn_gw *gw; - - if (!(gw = msn_gw_from_ic(data))) { - return FALSE; - } - - if (!gw->open) { - msn_gw_open(gw); - } else if (gw->polling || !gw->waiting) { - msn_gw_dorequest(gw, NULL); - } - - gw->write_timeout = -1; - return FALSE; -} - -void msn_gw_write(struct msn_gw *gw, char *buf, size_t len) -{ - g_byte_array_append(gw->out, (const guint8 *) buf, len); - - /* do a bit of buffering here to send several commands with a single request */ - if (gw->write_timeout == -1) { - gw->write_timeout = b_timeout_add(1, msn_gw_write_cb, gw->ic); - } -} |