aboutsummaryrefslogtreecommitdiffstats
path: root/proxy/proxy_http.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:04:49 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:04:49 -0800
commitdf7881f07f53b041dc0568be8528e9dbb74994cc (patch)
tree1b3e036f7df4241bf0c2d527b73198c50e1d7891 /proxy/proxy_http.c
parent55f4e4a5ec657a017e3bf75299ad71fd1c968dd3 (diff)
downloadexternal_qemu-df7881f07f53b041dc0568be8528e9dbb74994cc.zip
external_qemu-df7881f07f53b041dc0568be8528e9dbb74994cc.tar.gz
external_qemu-df7881f07f53b041dc0568be8528e9dbb74994cc.tar.bz2
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'proxy/proxy_http.c')
-rw-r--r--proxy/proxy_http.c235
1 files changed, 31 insertions, 204 deletions
diff --git a/proxy/proxy_http.c b/proxy/proxy_http.c
index 83982a7..c3d663c 100644
--- a/proxy/proxy_http.c
+++ b/proxy/proxy_http.c
@@ -10,200 +10,18 @@
** GNU General Public License for more details.
*/
#include "proxy_int.h"
-#include "proxy_http.h"
+#include "proxy_http_int.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "vl.h"
-typedef enum {
- HTTP_NONE = 0,
- HTTP_CONNECTING, /* connecting to the server */
- HTTP_SEND_HEADER, /* connected, sending header to the server */
- HTTP_RECEIVE_ANSWER_LINE1,
- HTTP_RECEIVE_ANSWER_LINE2 /* connected, reading server's answer */
-} HttpConnectionState;
-
-
-typedef struct {
- ProxyConnection root[1];
- HttpConnectionState state;
-} HttpConnection;
-
-
-typedef struct {
- ProxyService root[1];
- struct sockaddr_in server_addr; /* server address and port */
- char* footer; /* the footer contains the static parts of the */
- int footer_len; /* connection header, we generate it only once */
- char footer0[512];
-} HttpService;
-
-
-static void
-http_connection_free( HttpConnection* conn )
-{
- proxy_connection_done(conn->root);
- qemu_free(conn);
-}
-
-
#define HTTP_VERSION "1.1"
-static int
-http_connection_init( HttpConnection* conn )
-{
- HttpService* service = (HttpService*) conn->root->service;
- ProxyConnection* root = conn->root;
- char* p = root->buffer0;
- char* end = p + sizeof(root->buffer0);
- int wlen, ret;
- uint32_t address = ntohl(conn->root->address.sin_addr.s_addr);
- int port = ntohs(conn->root->address.sin_port);
-
- root->buffer_pos = 0;
- root->buffer = p;
-
- p += snprintf(p, end-p, "CONNECT %d.%d.%d.%d:%d HTTP/" HTTP_VERSION "\r\n",
- (address >> 24) & 0xff, (address >> 16) & 0xff,
- (address >> 8) & 0xff, address & 0xff, port);
- if (p >= end) goto Overflow;
-
- p += snprintf(p, end-p, "%.*s", service->footer_len, service->footer);
-
- if (p >= end) {
- Overflow:
- PROXY_LOG("%s: buffer overflow in proxy connection header\n", root->name);
- return -1;
- }
-
- root->buffer_len = (p - root->buffer);
-
- ret = connect( root->socket,
- (struct sockaddr*) &service->server_addr,
- sizeof(service->server_addr) );
- if (ret == 0) {
- /* immediate connection ?? */
- conn->state = HTTP_SEND_HEADER;
- PROXY_LOG("%s: immediate connection\n", root->name);
- }
- else {
- if (socket_errno == EINPROGRESS || socket_errno == EWOULDBLOCK) {
- conn->state = HTTP_CONNECTING;
- PROXY_LOG("%s: connecting\n", conn->root->name);
- }
- else {
- PROXY_LOG("%s: cannot connect to proxy: %s\n", root->name, strerror(errno));
- return -1;
- }
- }
- return 0;
-}
-
-
-static unsigned
-http_connection_select( HttpConnection* conn )
-{
- unsigned flags;
-
- switch (conn->state) {
- case HTTP_RECEIVE_ANSWER_LINE1:
- case HTTP_RECEIVE_ANSWER_LINE2:
- flags = PROXY_SELECT_READ;
- break;
-
- case HTTP_CONNECTING:
- case HTTP_SEND_HEADER:
- flags = PROXY_SELECT_WRITE;
- break;
-
- default:
- flags = 0;
- };
- return flags;
-}
-
-static void
-http_connection_poll( HttpConnection* conn,
- unsigned flags )
-{
- int ret;
- ProxyConnection* root = conn->root;
-
- switch (conn->state)
- {
- case HTTP_CONNECTING:
- PROXY_LOG("%s: connected to http proxy, sending header\n", root->name);
- conn->state = HTTP_SEND_HEADER;
- break;
-
- case HTTP_SEND_HEADER:
- {
- int ret = proxy_connection_send(root);
-
- if (ret < 0) {
- proxy_connection_free( root, PROXY_EVENT_SERVER_ERROR );
- return;
- }
- if (ret == 0)
- return;
-
- root->buffer_len = sizeof(root->buffer0);
- root->buffer_pos = 0;
- conn->state = HTTP_RECEIVE_ANSWER_LINE1;
- PROXY_LOG("%s: header sent, receiving first answer line\n", root->name);
- }
- break;
-
- case HTTP_RECEIVE_ANSWER_LINE1:
- case HTTP_RECEIVE_ANSWER_LINE2:
- {
- int ret = proxy_connection_receive_line(root);
-
- if (ret < 0) {
- proxy_connection_free( root, PROXY_EVENT_SERVER_ERROR );
- return;
- }
- if (ret == 0)
- return;
-
- if (conn->state == HTTP_RECEIVE_ANSWER_LINE1) {
- int http1, http2, codenum;
-
- if ( sscanf(root->buffer, "HTTP/%d.%d %d", &http1, &http2, &codenum) != 3 ) {
- PROXY_LOG( "%s: invalid answer from proxy: '%s'\n",
- root->name, root->buffer );
- proxy_connection_free( root, PROXY_EVENT_SERVER_ERROR );
- return;
- }
-
- /* success is 2xx */
- if (codenum/2 != 100) {
- PROXY_LOG( "%s: connection refused, error=%d\n",
- root->name, codenum );
- proxy_connection_free( root, PROXY_EVENT_CONNECTION_REFUSED );
- return;
- }
- PROXY_LOG("%s: receiving second answer line\n", root->name);
- conn->state = HTTP_RECEIVE_ANSWER_LINE2;
- root->buffer_pos = 0;
- } else {
- /* ok, we're connected */
- PROXY_LOG("%s: connection succeeded\n", root->name);
- proxy_connection_free( root, PROXY_EVENT_CONNECTED );
- }
- }
- break;
-
- default:
- PROXY_LOG("%s: invalid state for read event: %d\n", root->name, conn->state);
- }
-}
-
static void
http_service_free( HttpService* service )
{
- PROXY_LOG("%s\n", __FUNCTION__);
+ PROXY_LOG("%s", __FUNCTION__);
if (service->footer != service->footer0)
qemu_free(service->footer);
qemu_free(service);
@@ -212,11 +30,11 @@ http_service_free( HttpService* service )
static ProxyConnection*
http_service_connect( HttpService* service,
- int socket,
+ int sock_type,
struct sockaddr_in* address )
{
- HttpConnection* conn = qemu_mallocz(sizeof(*conn));
- int sock_type = socket_get_type(socket);
+ uint32_t addr;
+ int port;
/* the HTTP proxy can only handle TCP connections */
if (sock_type != SOCK_STREAM)
@@ -227,14 +45,25 @@ http_service_connect( HttpService* service,
address->sin_port == service->server_addr.sin_port)
return NULL;
- proxy_connection_init( conn->root, socket, address, service->root );
-
- if ( http_connection_init( conn ) < 0 ) {
- http_connection_free( conn );
- return NULL;
+ addr = ntohl(address->sin_addr.s_addr);
+ port = ntohs(address->sin_port);
+
+ PROXY_LOG("%s: trying to connect to %d.%d.%d.%d on port %d",
+ __FUNCTION__,
+ (addr >> 24) & 255,
+ (addr >> 16) & 255,
+ (addr >> 8) & 255,
+ addr & 255,
+ port );
+
+ if (port == 80) {
+ /* use the rewriter for HTTP */
+ PROXY_LOG("%s: using HTTP rewriter", __FUNCTION__);
+ return http_rewriter_connect(service, address);
+ } else {
+ PROXY_LOG("%s: using HTTP rewriter", __FUNCTION__);
+ return http_connector_connect(service, address);
}
-
- return conn->root;
}
@@ -256,7 +85,7 @@ proxy_http_setup( const char* servername,
if (servernamelen < 0)
servernamelen = strlen(servername);
- PROXY_LOG( "%s: creating http proxy service connecting to: %.*s:%d\n",
+ PROXY_LOG( "%s: creating http proxy service connecting to: %.*s:%d",
__FUNCTION__, servernamelen, servername, serverport );
/* resolve server address */
@@ -269,7 +98,7 @@ proxy_http_setup( const char* servername,
/* create service object */
service = qemu_mallocz(sizeof(*service));
if (service == NULL) {
- PROXY_LOG("%s: not enough memory to allocate new proxy service\n", __FUNCTION__);
+ PROXY_LOG("%s: not enough memory to allocate new proxy service", __FUNCTION__);
return -1;
}
@@ -322,7 +151,7 @@ proxy_http_setup( const char* servername,
wlen = proxy_base64_encode(user_pass, uplen, encoded, (int)sizeof(encoded));
if (wlen < 0) {
- PROXY_LOG( "could not base64 encode '%.*s'\n", uplen, user_pass);
+ PROXY_LOG( "could not base64 encode '%.*s'", uplen, user_pass);
goto FooterOverflow;
}
@@ -341,7 +170,7 @@ proxy_http_setup( const char* servername,
if (p >= end) {
FooterOverflow:
- PROXY_LOG( "%s: buffer overflow when creating connection footer\n",
+ PROXY_LOG( "%s: buffer overflow when creating connection footer",
__FUNCTION__);
http_service_free(service);
return -1;
@@ -351,18 +180,16 @@ proxy_http_setup( const char* servername,
service->footer_len = (p - service->footer);
}
- PROXY_LOG( "%s: creating HTTP Proxy Service Footer is (len=%d):\n'%.*s'\n",
+ PROXY_LOG( "%s: creating HTTP Proxy Service Footer is (len=%d):\n'%.*s'",
__FUNCTION__, service->footer_len,
service->footer_len, service->footer );
service->root->opaque = service;
- service->root->serv_free = (ProxyServiceFreeFunc) http_service_free;
- service->root->serv_connect = (ProxyServiceConnectFunc) http_service_connect;
- service->root->conn_free = (ProxyConnectionFreeFunc) http_connection_free;
- service->root->conn_select = (ProxyConnectionSelectFunc) http_connection_select;
- service->root->conn_poll = (ProxyConnectionPollFunc) http_connection_poll;
+ service->root->serv_free = (ProxyServiceFreeFunc) http_service_free;
+ service->root->serv_connect = (ProxyServiceConnectFunc) http_service_connect;
if (proxy_manager_add_service( service->root ) < 0) {
+ PROXY_LOG("%s: could not register service ?", __FUNCTION__);
http_service_free(service);
return -1;
}