From 9659f379672d7be6f9a2bdae9e58c7da0b3919e2 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Thu, 27 Jan 2011 22:01:43 +0000 Subject: [PATCH] introduce-http_proxy-support-no-auth.patch Signed-off-by: Andy Green --- README-test-server | 13 ++++++++ lib/client-handshake.c | 72 ++++++++++++++++++++++++++++++++++++++------- lib/libwebsockets.c | 25 ++++++++++++++++ lib/private-libwebsockets.h | 2 ++ 4 files changed, 102 insertions(+), 10 deletions(-) diff --git a/README-test-server b/README-test-server index cb9e6b5..1cb8e84 100644 --- a/README-test-server +++ b/README-test-server @@ -159,6 +159,19 @@ another server, you can specify the protcol to handshake with by --protocol=protocolname +proxy support +------------- + +The http_proxy environment variable is respected by the client +connection code for both ws:// and wss://. It doesn't support +authentication yet. + +You use it like this + +export http_proxy=myproxy.com:3128 +libwebsockets-test-client someserver.com + + Websocket version supported --------------------------- diff --git a/lib/client-handshake.c b/lib/client-handshake.c index e93ce99..5f487e5 100644 --- a/lib/client-handshake.c +++ b/lib/client-handshake.c @@ -115,6 +115,7 @@ libwebsocket_client_connect(struct libwebsocket_context *this, int okay = 0; struct libwebsocket *wsi; int n; + int plen = 0; #ifdef LWS_OPENSSL_SUPPORT char ssl_err_buf[512]; #else @@ -126,7 +127,7 @@ libwebsocket_client_connect(struct libwebsocket_context *this, wsi = malloc(sizeof(struct libwebsocket)); if (wsi == NULL) { - fprintf(stderr, "Out of memort allocing new connection\n"); + fprintf(stderr, "Out of memory allocing new connection\n"); return NULL; } @@ -144,7 +145,23 @@ libwebsocket_client_connect(struct libwebsocket_context *this, } /* - * prepare the actual connection + * proxy? + */ + + if (this->http_proxy_port) { + plen = sprintf(pkt, "CONNECT %s:%u HTTP/1.0\x0d\x0a" + "User-agent: libwebsockets\x0d\x0a" +/*Proxy-authorization: basic aGVsbG86d29ybGQ= */ + "\x0d\x0a", address, port); + + /* OK from now on we talk via the proxy */ + + address = this->http_proxy_address; + port = this->http_proxy_port; + } + + /* + * prepare the actual connection (to the proxy, if any) */ server_hostent = gethostbyname(address); @@ -172,6 +189,35 @@ libwebsocket_client_connect(struct libwebsocket_context *this, goto bail1; } + /* we are connected to server, or proxy */ + + /* non-SSL connection */ + + if (this->http_proxy_port) { + + n = send(wsi->sock, pkt, plen, 0); + if (n < 0) { + fprintf(stderr, "ERROR writing to " + "proxy socket\n"); + goto bail2; + } + + n = recv(wsi->sock, pkt, sizeof pkt, 0); + if (n < 0) { + fprintf(stderr, "ERROR reading from " + "proxy socket\n"); + goto bail2; + } + + pkt[13] = '\0'; + if (strcmp(pkt, "HTTP/1.0 200 ") != 0) { + fprintf(stderr, "ERROR from proxy: %s\n", pkt); + goto bail2; + } + + /* we can just start sending to proxy */ + } + #ifdef LWS_OPENSSL_SUPPORT if (ssl_connection) { @@ -182,22 +228,28 @@ libwebsocket_client_connect(struct libwebsocket_context *this, if (SSL_connect(wsi->ssl) <= 0) { fprintf(stderr, "SSL connect error %s\n", ERR_error_string(ERR_get_error(), ssl_err_buf)); - goto bail2; + goto bail1; } n = SSL_get_verify_result(wsi->ssl); if (n != X509_V_OK) { - if (n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && - ssl_connection == 2) - goto cert_okay; + if (n != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || + ssl_connection != 2) { - fprintf(stderr, "server's cert didn't look good %d\n", n); - goto bail2; + fprintf(stderr, "server's cert didn't " + "look good %d\n", n); + goto bail2; + } } - } else + } else { wsi->ssl = NULL; -cert_okay: #endif + + +#ifdef LWS_OPENSSL_SUPPORT + } +#endif + /* * create the random key */ diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index e6db157..2674aee 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -623,6 +623,7 @@ libwebsocket_create_context(int port, int opt = 1; struct libwebsocket_context *this = NULL; unsigned int slen; + char *p; #ifdef LWS_OPENSSL_SUPPORT SSL_METHOD *method; @@ -636,6 +637,30 @@ libwebsocket_create_context(int port, } this->protocols = protocols; this->listen_port = port; + this->http_proxy_port = 0; + this->http_proxy_address[0] = '\0'; + + /* split the proxy ads:port if given */ + + p = getenv("http_proxy"); + if (p) { + strncpy(this->http_proxy_address, p, + sizeof this->http_proxy_address - 1); + this->http_proxy_address[ + sizeof this->http_proxy_address - 1] = '\0'; + + p = strchr(this->http_proxy_address, ':'); + if (p == NULL) { + fprintf(stderr, "http_proxy needs to be ads:port\n"); + return NULL; + } + *p = '\0'; + this->http_proxy_port = atoi(p + 1); + + fprintf(stderr, "Using proxy %s:%u\n", + this->http_proxy_address, + this->http_proxy_port); + } if (port) { diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index c3bce43..2cb3f2b 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -168,6 +168,8 @@ struct libwebsocket_context { struct pollfd fds[MAX_CLIENTS + 1]; int fds_count; int listen_port; + char http_proxy_address[256]; + unsigned int http_proxy_port; #ifdef LWS_OPENSSL_SUPPORT int use_ssl; SSL_CTX *ssl_ctx; -- 2.7.4