📄 httpconn.c
字号:
servconn->rx_buf = NULL; } servconn->processing = FALSE; if (servconn->wasted) msn_servconn_destroy(servconn); g_free(old_rx_buf);}static voidhttpconn_write_cb(gpointer data, gint source, PurpleInputCondition cond){ MsnHttpConn *httpconn; int ret, writelen; httpconn = data; writelen = purple_circ_buffer_get_max_read(httpconn->tx_buf); if (writelen == 0) { purple_input_remove(httpconn->tx_handler); httpconn->tx_handler = 0; return; } ret = write(httpconn->fd, httpconn->tx_buf->outptr, writelen); if (ret <= 0) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) /* No worries */ return; /* Error! */ msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); return; } purple_circ_buffer_mark_read(httpconn->tx_buf, ret); /* TODO: I don't think these 2 lines are needed. Remove them? */ if (ret == writelen) httpconn_write_cb(data, source, cond);}static gbooleanwrite_raw(MsnHttpConn *httpconn, const char *data, size_t data_len){ ssize_t res; /* result of the write operation */ if (httpconn->tx_handler == 0) res = write(httpconn->fd, data, data_len); else { res = -1; errno = EAGAIN; } if ((res <= 0) && ((errno != EAGAIN) && (errno != EWOULDBLOCK))) { msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); return FALSE; } if (res < 0 || res < data_len) { if (res < 0) res = 0; if (httpconn->tx_handler == 0 && httpconn->fd) httpconn->tx_handler = purple_input_add(httpconn->fd, PURPLE_INPUT_WRITE, httpconn_write_cb, httpconn); purple_circ_buffer_append(httpconn->tx_buf, data + res, data_len - res); } return TRUE;}static char *msn_httpconn_proxy_auth(MsnHttpConn *httpconn){ PurpleAccount *account; PurpleProxyInfo *gpi; const char *username, *password; char *auth = NULL; account = httpconn->session->account; gpi = purple_proxy_get_setup(account); if (gpi == NULL || !(purple_proxy_info_get_type(gpi) == PURPLE_PROXY_HTTP || purple_proxy_info_get_type(gpi) == PURPLE_PROXY_USE_ENVVAR)) return NULL; username = purple_proxy_info_get_username(gpi); password = purple_proxy_info_get_password(gpi); if (username != NULL) { char *tmp; auth = g_strdup_printf("%s:%s", username, password ? password : ""); tmp = purple_base64_encode((const guchar *)auth, strlen(auth)); g_free(auth); auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp); g_free(tmp); } return auth;}static gbooleanmsn_httpconn_poll(gpointer data){ MsnHttpConn *httpconn; char *header; char *auth; httpconn = data; g_return_val_if_fail(httpconn != NULL, FALSE); if ((httpconn->host == NULL) || (httpconn->full_session_id == NULL)) { /* There's no need to poll if the session is not fully established */ return TRUE; } if (httpconn->waiting_response) { /* There's no need to poll if we're already waiting for a response */ return TRUE; } auth = msn_httpconn_proxy_auth(httpconn); header = g_strdup_printf( "POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n" "Accept: */*\r\n" "Accept-Language: en-us\r\n" "User-Agent: MSMSGS\r\n" "Host: %s\r\n" "Proxy-Connection: Keep-Alive\r\n" "%s" /* Proxy auth */ "Connection: Keep-Alive\r\n" "Pragma: no-cache\r\n" "Content-Type: application/x-msn-messenger\r\n" "Content-Length: 0\r\n\r\n", httpconn->host, httpconn->full_session_id, httpconn->host, auth ? auth : ""); g_free(auth); if (write_raw(httpconn, header, strlen(header))) httpconn->waiting_response = TRUE; g_free(header); return TRUE;}ssize_tmsn_httpconn_write(MsnHttpConn *httpconn, const char *body, size_t body_len){ char *params; char *data; int header_len; char *auth; const char *server_types[] = { "NS", "SB" }; const char *server_type; char *host; MsnServConn *servconn; /* TODO: remove http data from servconn */ g_return_val_if_fail(httpconn != NULL, 0); g_return_val_if_fail(body != NULL, 0); g_return_val_if_fail(body_len > 0, 0); servconn = httpconn->servconn; if (httpconn->waiting_response) { MsnHttpQueueData *queue_data = g_new0(MsnHttpQueueData, 1); queue_data->httpconn = httpconn; queue_data->body = g_memdup(body, body_len); queue_data->body_len = body_len; httpconn->queue = g_list_append(httpconn->queue, queue_data); return body_len; } server_type = server_types[servconn->type]; if (httpconn->virgin) { host = "gateway.messenger.hotmail.com"; /* The first time servconn->host is the host we should connect to. */ params = g_strdup_printf("Action=open&Server=%s&IP=%s", server_type, servconn->host); httpconn->virgin = FALSE; } else { /* The rest of the times servconn->host is the gateway host. */ host = httpconn->host; if (host == NULL || httpconn->full_session_id == NULL) { purple_debug_warning("msn", "Attempted HTTP write before session is established\n"); return -1; } params = g_strdup_printf("SessionID=%s", httpconn->full_session_id); } auth = msn_httpconn_proxy_auth(httpconn); data = g_strdup_printf( "POST http://%s/gateway/gateway.dll?%s HTTP/1.1\r\n" "Accept: */*\r\n" "Accept-Language: en-us\r\n" "User-Agent: MSMSGS\r\n" "Host: %s\r\n" "Proxy-Connection: Keep-Alive\r\n" "%s" /* Proxy auth */ "Connection: Keep-Alive\r\n" "Pragma: no-cache\r\n" "Content-Type: application/x-msn-messenger\r\n" "Content-Length: %d\r\n\r\n", host, params, host, auth ? auth : "", (int) body_len); g_free(params); g_free(auth); header_len = strlen(data); data = g_realloc(data, header_len + body_len); memcpy(data + header_len, body, body_len); if (write_raw(httpconn, data, header_len + body_len)) httpconn->waiting_response = TRUE; g_free(data); return body_len;}MsnHttpConn *msn_httpconn_new(MsnServConn *servconn){ MsnHttpConn *httpconn; g_return_val_if_fail(servconn != NULL, NULL); httpconn = g_new0(MsnHttpConn, 1); purple_debug_info("msn", "new httpconn (%p)\n", httpconn); /* TODO: Remove this */ httpconn->session = servconn->session; httpconn->servconn = servconn; httpconn->tx_buf = purple_circ_buffer_new(MSN_BUF_LEN); httpconn->tx_handler = 0; return httpconn;}voidmsn_httpconn_destroy(MsnHttpConn *httpconn){ g_return_if_fail(httpconn != NULL); purple_debug_info("msn", "destroy httpconn (%p)\n", httpconn); if (httpconn->connected) msn_httpconn_disconnect(httpconn); g_free(httpconn->full_session_id); g_free(httpconn->session_id); g_free(httpconn->host); purple_circ_buffer_destroy(httpconn->tx_buf); if (httpconn->tx_handler > 0) purple_input_remove(httpconn->tx_handler); g_free(httpconn);}static voidconnect_cb(gpointer data, gint source, const gchar *error_message){ MsnHttpConn *httpconn; httpconn = data; httpconn->connect_data = NULL; httpconn->fd = source; if (source >= 0) { httpconn->inpa = purple_input_add(httpconn->fd, PURPLE_INPUT_READ, read_cb, data); httpconn->timer = purple_timeout_add(2000, msn_httpconn_poll, httpconn); msn_httpconn_process_queue(httpconn); } else { purple_debug_error("msn", "HTTP: Connection error\n"); msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT); }}gbooleanmsn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port){ g_return_val_if_fail(httpconn != NULL, FALSE); g_return_val_if_fail(host != NULL, FALSE); g_return_val_if_fail(port > 0, FALSE); if (httpconn->connected) msn_httpconn_disconnect(httpconn); httpconn->connect_data = purple_proxy_connect(NULL, httpconn->session->account, "gateway.messenger.hotmail.com", 80, connect_cb, httpconn); if (httpconn->connect_data != NULL) { httpconn->waiting_response = TRUE; httpconn->connected = TRUE; } return httpconn->connected;}voidmsn_httpconn_disconnect(MsnHttpConn *httpconn){ g_return_if_fail(httpconn != NULL); if (!httpconn->connected) return; if (httpconn->connect_data != NULL) { purple_proxy_connect_cancel(httpconn->connect_data); httpconn->connect_data = NULL; } if (httpconn->timer) { purple_timeout_remove(httpconn->timer); httpconn->timer = 0; } if (httpconn->inpa > 0) { purple_input_remove(httpconn->inpa); httpconn->inpa = 0; } close(httpconn->fd); httpconn->fd = -1; g_free(httpconn->rx_buf); httpconn->rx_buf = NULL; httpconn->rx_len = 0; httpconn->connected = FALSE; /* msn_servconn_disconnect(httpconn->servconn); */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -