diff options
Diffstat (limited to 'proxy/proxy_http_connector.c')
-rw-r--r-- | proxy/proxy_http_connector.c | 203 |
1 files changed, 0 insertions, 203 deletions
diff --git a/proxy/proxy_http_connector.c b/proxy/proxy_http_connector.c deleted file mode 100644 index 6f03d9b..0000000 --- a/proxy/proxy_http_connector.c +++ /dev/null @@ -1,203 +0,0 @@ -/* Copyright (C) 2007-2008 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ -#include "proxy_http_int.h" -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include "qemu-common.h" - -/* A HttpConnector implements a non-HTTP proxied connection - * through the CONNECT method. Many firewalls are configured - * to reject these for port 80, so these connections should - * use a HttpRewriter instead. - */ - -typedef enum { - STATE_NONE = 0, - STATE_CONNECTING, /* connecting to the server */ - STATE_SEND_HEADER, /* connected, sending header to the server */ - STATE_RECEIVE_ANSWER_LINE1, - STATE_RECEIVE_ANSWER_LINE2 /* connected, reading server's answer */ -} ConnectorState; - -typedef struct Connection { - ProxyConnection root[1]; - ConnectorState state; -} Connection; - - -static void -connection_free( ProxyConnection* root ) -{ - proxy_connection_done(root); - qemu_free(root); -} - - - -#define HTTP_VERSION "1.1" - -static int -connection_init( Connection* conn ) -{ - HttpService* service = (HttpService*) conn->root->service; - ProxyConnection* root = conn->root; - stralloc_t* str = root->str; - - proxy_connection_rewind(root); - stralloc_add_format(str, "CONNECT %s HTTP/" HTTP_VERSION "\r\n", - sock_address_to_string(&root->address)); - - stralloc_add_bytes(str, service->footer, service->footer_len); - - if (!socket_connect( root->socket, &service->server_addr )) { - /* immediate connection ?? */ - conn->state = STATE_SEND_HEADER; - PROXY_LOG("%s: immediate connection", root->name); - } - else { - if (errno == EINPROGRESS || errno == EWOULDBLOCK) { - conn->state = STATE_CONNECTING; - PROXY_LOG("%s: connecting", root->name); - } - else { - PROXY_LOG("%s: cannot connect to proxy: %s", root->name, errno_str); - return -1; - } - } - return 0; -} - - -static void -connection_select( ProxyConnection* root, - ProxySelect* sel ) -{ - unsigned flags; - Connection* conn = (Connection*)root; - - switch (conn->state) { - case STATE_RECEIVE_ANSWER_LINE1: - case STATE_RECEIVE_ANSWER_LINE2: - flags = PROXY_SELECT_READ; - break; - - case STATE_CONNECTING: - case STATE_SEND_HEADER: - flags = PROXY_SELECT_WRITE; - break; - - default: - flags = 0; - }; - proxy_select_set(sel, root->socket, flags); -} - -static void -connection_poll( ProxyConnection* root, - ProxySelect* sel ) -{ - DataStatus ret = DATA_NEED_MORE; - Connection* conn = (Connection*)root; - int fd = root->socket; - - if (!proxy_select_poll(sel, fd)) - return; - - switch (conn->state) - { - case STATE_CONNECTING: - PROXY_LOG("%s: connected to http proxy, sending header", root->name); - conn->state = STATE_SEND_HEADER; - break; - - case STATE_SEND_HEADER: - ret = proxy_connection_send(root, fd); - if (ret == DATA_COMPLETED) { - conn->state = STATE_RECEIVE_ANSWER_LINE1; - PROXY_LOG("%s: header sent, receiving first answer line", root->name); - } - break; - - case STATE_RECEIVE_ANSWER_LINE1: - case STATE_RECEIVE_ANSWER_LINE2: - ret = proxy_connection_receive_line(root, root->socket); - if (ret == DATA_COMPLETED) { - if (conn->state == STATE_RECEIVE_ANSWER_LINE1) { - int http1, http2, codenum; - const char* line = root->str->s; - - if ( sscanf(line, "HTTP/%d.%d %d", &http1, &http2, &codenum) != 3 ) { - PROXY_LOG( "%s: invalid answer from proxy: '%s'", - root->name, line ); - ret = DATA_ERROR; - break; - } - - /* success is 2xx */ - if (codenum/2 != 100) { - PROXY_LOG( "%s: connection refused, error=%d", - root->name, codenum ); - proxy_connection_free( root, 0, PROXY_EVENT_CONNECTION_REFUSED ); - return; - } - PROXY_LOG("%s: receiving second answer line", root->name); - conn->state = STATE_RECEIVE_ANSWER_LINE2; - proxy_connection_rewind(root); - } else { - /* ok, we're connected */ - PROXY_LOG("%s: connection succeeded", root->name); - proxy_connection_free( root, 1, PROXY_EVENT_CONNECTED ); - } - } - break; - - default: - PROXY_LOG("%s: invalid state for read event: %d", root->name, conn->state); - } - - if (ret == DATA_ERROR) { - proxy_connection_free( root, 0, PROXY_EVENT_SERVER_ERROR ); - } -} - - - -ProxyConnection* -http_connector_connect( HttpService* service, - SockAddress* address ) -{ - Connection* conn; - int s; - - s = socket_create_inet( SOCKET_STREAM ); - if (s < 0) - return NULL; - - conn = qemu_mallocz(sizeof(*conn)); - if (conn == NULL) { - socket_close(s); - return NULL; - } - - proxy_connection_init( conn->root, s, address, service->root, - connection_free, - connection_select, - connection_poll ); - - if ( connection_init( conn ) < 0 ) { - connection_free( conn->root ); - return NULL; - } - - return conn->root; -} |