⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpconn.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			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 + -