diff options
author | dequis <dx@dxzone.com.ar> | 2015-03-02 00:43:04 -0300 |
---|---|---|
committer | dequis <dx@dxzone.com.ar> | 2015-04-10 14:10:40 -0300 |
commit | cfeadc32ba56ce1a9bede1077f392c47d30225b8 (patch) | |
tree | 734dd2aa2b087c32d78c769e0fd67d9db21c72f9 | |
parent | d5503584fb11fbe8b4eec3baba6fb6756c1fc4c0 (diff) |
msn: start of the http gateway code
-rw-r--r-- | protocols/msn/Makefile | 2 | ||||
-rw-r--r-- | protocols/msn/gw.c | 126 | ||||
-rw-r--r-- | protocols/msn/msn.h | 22 |
3 files changed, 149 insertions, 1 deletions
diff --git a/protocols/msn/Makefile b/protocols/msn/Makefile index ce4a3325..7d020942 100644 --- a/protocols/msn/Makefile +++ b/protocols/msn/Makefile @@ -12,7 +12,7 @@ _SRCDIR_ := $(_SRCDIR_)protocols/msn/ endif # [SH] Program variables -objects = msn.o msn_util.o ns.o soap.o tables.o +objects = msn.o msn_util.o ns.o soap.o tables.o gw.o LFLAGS += -r diff --git a/protocols/msn/gw.c b/protocols/msn/gw.c new file mode 100644 index 00000000..3d46eeda --- /dev/null +++ b/protocols/msn/gw.c @@ -0,0 +1,126 @@ +#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 msn_data *md) +{ + 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->data = md; + gw->in = g_byte_array_new(); + gw->out = g_byte_array_new(); + return gw; +} + +void msn_gw_free(struct msn_gw *gw) +{ + 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 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) +{ + char *value; + struct msn_gw *gw = req->data; + + if ((value = get_rfc822_header(req->reply_headers, "X-MSN-Messenger", 0))) { + if (!msn_gw_parse_session_header(gw, value)) { + /* XXX handle this */ + } + 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 */ + } + + /* XXX handle reply */ + + if (gw->poll_timeout != -1) { + b_event_remove(gw->poll_timeout); + } + gw->poll_timeout = b_timeout_add(5000, msn_gw_poll_timeout, gw); + +} + +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(); + } + + 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); + 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"); + gw->open = TRUE; +} + +static gboolean msn_gw_poll_timeout(gpointer data, gint source, b_input_condition cond) +{ + struct msn_gw *gw = data; + gw->poll_timeout = -1; + if (!gw->waiting) { + msn_gw_dorequest(gw, NULL); + } + return FALSE; +} diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index a3894242..2669a736 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -123,6 +123,25 @@ typedef enum { MSN_EMAIL_UNVERIFIED = 16, } msn_flags_t; +struct msn_gw { + char *last_host; + int port; + gboolean ssl; + + char *session_id; + + GByteArray *in; + GByteArray *out; + + int poll_timeout; + + b_event_handler callback; + gpointer data; + + gboolean open; + gboolean waiting; +}; + struct msn_data { int fd, inpa; int rxlen; @@ -151,6 +170,9 @@ struct msn_data { it to the MSNP server. */ GTree *domaintree; int adl_todo; + + gboolean is_http; + struct msn_gw *gw; }; struct msn_away_state { |