diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2005-12-17 19:55:46 +0100 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2005-12-17 19:55:46 +0100 |
commit | 52b3a9978681da7c3f2cd21cd6987eb158a54a03 (patch) | |
tree | 48fa512664d4b4b74e9979bc60ae807827e8bad2 | |
parent | 8a9afe4eaa42052006fb64c6755ac0321b97ab55 (diff) | |
parent | b5a22e33a1aa2500093e783e79de2f44bf53c150 (diff) |
Successfully tested http_client, added support for redirections.
-rwxr-xr-x | configure | 16 | ||||
-rw-r--r-- | protocols/http_client.c | 146 | ||||
-rw-r--r-- | protocols/jabber/Makefile | 8 | ||||
-rw-r--r-- | protocols/msn/Makefile | 8 | ||||
-rw-r--r-- | protocols/oscar/Makefile | 8 | ||||
-rw-r--r-- | protocols/yahoo/Makefile | 8 | ||||
-rw-r--r-- | url.c | 48 | ||||
-rw-r--r-- | url.h | 3 |
8 files changed, 178 insertions, 67 deletions
@@ -251,10 +251,10 @@ if [ "$msn" = 1 -o "$jabber" = 1 ]; then if [ "$ret" = "0" ]; then echo - echo 'WARNING: Could not find a suitable SSL library (GnuTLS, libnss or OpenSSL).' - echo ' This is necessary for MSN and full Jabber support. To continue,' - echo ' install a suitable SSL library or disable MSN support (--msn=0).' - echo ' If you want Jabber without SSL support you can try --ssl=bogus.' + echo 'ERROR: Could not find a suitable SSL library (GnuTLS, libnss or OpenSSL).' + echo ' This is necessary for MSN and full Jabber support. To continue,' + echo ' install a suitable SSL library or disable MSN support (--msn=0).' + echo ' If you want Jabber without SSL support you can try --ssl=bogus.' exit 1; fi; @@ -307,7 +307,7 @@ if [ "$msn" = 0 ]; then else echo '#define WITH_MSN' >> config.h protocols=$protocols'msn ' - protoobjs=$protoobjs'msnn.o ' + protoobjs=$protoobjs'msn_mod.o ' fi if [ "$jabber" = 0 ]; then @@ -315,7 +315,7 @@ if [ "$jabber" = 0 ]; then else echo '#define WITH_JABBER' >> config.h protocols=$protocols'jabber ' - protoobjs=$protoobjs'jabberr.o ' + protoobjs=$protoobjs'jabber_mod.o ' fi if [ "$oscar" = 0 ]; then @@ -323,7 +323,7 @@ if [ "$oscar" = 0 ]; then else echo '#define WITH_OSCAR' >> config.h protocols=$protocols'oscar ' - protoobjs=$protoobjs'oscarr.o ' + protoobjs=$protoobjs'oscar_mod.o ' fi if [ "$yahoo" = 0 ]; then @@ -331,7 +331,7 @@ if [ "$yahoo" = 0 ]; then else echo '#define WITH_YAHOO' >> config.h protocols=$protocols'yahoo ' - protoobjs=$protoobjs'yahooo.o ' + protoobjs=$protoobjs'yahoo_mod.o ' fi if [ "$protocols" = "PROTOCOLS = " ]; then diff --git a/protocols/http_client.c b/protocols/http_client.c index f631981f..fa735426 100644 --- a/protocols/http_client.c +++ b/protocols/http_client.c @@ -4,7 +4,7 @@ * Copyright 2002-2005 Wilmer van der Gaast and others * \********************************************************************/ -/* HTTP(S) module (actually, it only does HTTPS right now) */ +/* HTTP(S) module */ /* This program is free software; you can redistribute it and/or modify @@ -24,9 +24,11 @@ */ #include <string.h> +#include <stdio.h> #include "sock.h" #include "http_client.h" +#include "url.h" static void http_connected( gpointer data, int source, GaimInputCondition cond ); @@ -60,6 +62,8 @@ void *http_dorequest( char *host, int port, http_input_function func, int ssl, c return( NULL ); } + req->func = func; + req->data = data; req->request = g_strdup( request ); req->request_length = strlen( request ); @@ -102,7 +106,7 @@ static void http_connected( gpointer data, int source, GaimInputCondition cond ) { if( !sockerr_again() ) { - close( req->fd ); + closesocket( req->fd ); goto error; } } @@ -187,6 +191,7 @@ static void http_incoming_data( gpointer data, int source, GaimInputCondition co { req->reply_headers = g_realloc( req->reply_headers, req->bytes_read + st + 1 ); memcpy( req->reply_headers + req->bytes_read, buffer, st ); + req->bytes_read += st; } /* There will be more! */ @@ -207,18 +212,149 @@ got_reply: if( end2 && end2 < end1 ) { - end1 = end2; + end1 = end2 + 1; evil_server = 1; } + else + { + end1 += 2; + } if( end1 ) { *end1 = 0; if( evil_server ) + req->reply_body = end1 + 1; + else req->reply_body = end1 + 2; + } + + if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL ) + { + if( sscanf( end1 + 1, "%d", &req->status_code ) != 1 ) + req->status_code = -1; + } + else + { + req->status_code = -1; + } + + if( req->status_code == 301 || req->status_code == 302 ) + { + char *loc, *new_request, *new_host; + int error = 0, new_port, new_proto; + + loc = strstr( req->reply_headers, "\nLocation: " ); + if( loc == NULL ) /* We can't handle this redirect... */ + goto cleanup; + + loc += 11; + while( *loc == ' ' ) + loc ++; + + /* TODO/FIXME: Possibly have to handle relative redirections, + and rewrite Host: headers. Not necessary for now, it's + enough for passport authentication like this. */ + + if( *loc == '/' ) + { + /* Just a different pathname... */ + + /* Since we don't cache the servername, and since we + don't need this yet anyway, I won't implement it. */ + + goto cleanup; + } else - req->reply_body = end1 + 4; + { + /* A whole URL */ + url_t *url; + char *s; + + s = strstr( loc, "\r\n" ); + if( s == NULL ) + goto cleanup; + + url = g_new0( url_t, 1 ); + *s = 0; + + if( !url_set( url, loc ) ) + { + g_free( url ); + goto cleanup; + } + + /* Okay, this isn't fun! We have to rebuild the request... :-( */ + new_request = g_malloc( req->request_length + strlen( url->file ) ); + + /* So, now I just allocated enough memory, so I'm + going to use strcat(), whether you like it or not. :-) */ + + /* First, find the GET/POST/whatever from the original request. */ + s = strchr( req->request, ' ' ); + if( s == NULL ) + { + g_free( new_request ); + g_free( url ); + goto cleanup; + } + + *s = 0; + sprintf( new_request, "%s %s HTTP/1.0\r\n", req->request, url->file ); + *s = ' '; + + s = strstr( req->request, "\r\n" ); + if( s == NULL ) + { + g_free( new_request ); + g_free( url ); + goto cleanup; + } + + strcat( new_request, s + 2 ); + new_host = g_strdup( url->host ); + new_port = url->port; + new_proto = url->proto; + + g_free( url ); + } + + if( req->ssl ) + ssl_disconnect( req->ssl ); + else + closesocket( req->fd ); + + req->fd = -1; + req->ssl = 0; + + if( new_proto == PROTO_HTTPS ) + { + req->ssl = ssl_connect( new_host, new_port, http_ssl_connected, req ); + if( req->ssl == NULL ) + error = 1; + } + else + { + req->fd = proxy_connect( new_host, new_port, http_connected, req ); + if( req->fd < 0 ) + error = 1; + } + + if( error ) + { + g_free( new_request ); + goto cleanup; + } + + g_free( req->request ); + g_free( req->reply_headers ); + req->request = new_request; + req->request_length = strlen( new_request ); + req->bytes_read = req->bytes_written = req->inpa = 0; + req->reply_headers = req->reply_body = NULL; + + return; } /* Assume that a closed connection means we're finished, this indeed @@ -229,7 +365,7 @@ cleanup: if( req->ssl ) ssl_disconnect( req->ssl ); else - close( req->fd ); + closesocket( req->fd ); req->func( req ); diff --git a/protocols/jabber/Makefile b/protocols/jabber/Makefile index df326fe6..9b414dc8 100644 --- a/protocols/jabber/Makefile +++ b/protocols/jabber/Makefile @@ -15,7 +15,7 @@ CFLAGS += -Wall LFLAGS += -r # [SH] Phony targets -all: jabberr.o +all: jabber_mod.o .PHONY: all clean distclean @@ -32,6 +32,6 @@ $(objects): %.o: %.c @echo '*' Compiling $< @$(CC) -c $(CFLAGS) $< -o $@ -jabberr.o: $(objects) - @echo '*' Linking jabberr.o - @$(LD) $(LFLAGS) $(objects) -o jabberr.o +jabber_mod.o: $(objects) + @echo '*' Linking jabber_mod.o + @$(LD) $(LFLAGS) $(objects) -o jabber_mod.o diff --git a/protocols/msn/Makefile b/protocols/msn/Makefile index e6620323..873c831c 100644 --- a/protocols/msn/Makefile +++ b/protocols/msn/Makefile @@ -15,7 +15,7 @@ CFLAGS += -Wall LFLAGS += -r # [SH] Phony targets -all: msnn.o +all: msn_mod.o .PHONY: all clean distclean @@ -32,8 +32,8 @@ $(objects): %.o: %.c @echo '*' Compiling $< @$(CC) -c $(CFLAGS) $< -o $@ -msnn.o: $(objects) - @echo '*' Linking msnn.o - @$(LD) $(LFLAGS) $(objects) -o msnn.o +msn_mod.o: $(objects) + @echo '*' Linking msn_mod.o + @$(LD) $(LFLAGS) $(objects) -o msn_mod.o diff --git a/protocols/oscar/Makefile b/protocols/oscar/Makefile index 5ef996a1..97a27299 100644 --- a/protocols/oscar/Makefile +++ b/protocols/oscar/Makefile @@ -15,7 +15,7 @@ CFLAGS += -Wall LFLAGS += -r # [SH] Phony targets -all: oscarr.o +all: oscar_mod.o .PHONY: all clean distclean @@ -32,6 +32,6 @@ $(objects): %.o: %.c @echo '*' Compiling $< @$(CC) -c $(CFLAGS) $< -o $@ -oscarr.o: $(objects) - @echo '*' Linking oscarr.o - @$(LD) $(LFLAGS) $(objects) -o oscarr.o +oscar_mod.o: $(objects) + @echo '*' Linking oscar_mod.o + @$(LD) $(LFLAGS) $(objects) -o oscar_mod.o diff --git a/protocols/yahoo/Makefile b/protocols/yahoo/Makefile index 39a655a3..e594cc1f 100644 --- a/protocols/yahoo/Makefile +++ b/protocols/yahoo/Makefile @@ -15,7 +15,7 @@ CFLAGS += -Wall -DSTDC_HEADERS -DHAVE_STRING_H -DHAVE_STRCHR -DHAVE_MEMCPY -DHAV LFLAGS += -r # [SH] Phony targets -all: yahooo.o +all: yahoo_mod.o .PHONY: all clean distclean @@ -32,6 +32,6 @@ $(objects): %.o: %.c @echo '*' Compiling $< @$(CC) -c $(CFLAGS) $< -o $@ -yahooo.o: $(objects) - @echo '*' Linking yahooo.o - @$(LD) $(LFLAGS) $(objects) -o yahooo.o +yahoo_mod.o: $(objects) + @echo '*' Linking yahoo_mod.o + @$(LD) $(LFLAGS) $(objects) -o yahoo_mod.o @@ -1,7 +1,7 @@ /********************************************************************\ * BitlBee -- An IRC to other IM-networks gateway * * * - * Copyright 2001-2004 Wilmer van der Gaast and others * + * Copyright 2001-2005 Wilmer van der Gaast and others * \********************************************************************/ /* URL/mirror stuff - Stolen from Axel */ @@ -29,7 +29,7 @@ int url_set( url_t *url, char *set_url ) { char s[MAX_STRING]; - char *i, *j; + char *i; /* protocol:// */ if( ( i = strstr( set_url, "://" ) ) == NULL ) @@ -39,7 +39,9 @@ int url_set( url_t *url, char *set_url ) } else { - if( g_strncasecmp( set_url, "http", i - set_url ) == 0 ) + if( g_strncasecmp( set_url, "https", i - set_url ) == 0 ) + url->proto = PROTO_HTTPS; + else if( g_strncasecmp( set_url, "http", i - set_url ) == 0 ) url->proto = PROTO_HTTP; else if( g_strncasecmp( set_url, "socks4", i - set_url ) == 0 ) url->proto = PROTO_SOCKS4; @@ -55,33 +57,14 @@ int url_set( url_t *url, char *set_url ) /* Split */ if( ( i = strchr( s, '/' ) ) == NULL ) { - strcpy( url->dir, "/" ); + strcpy( url->file, "/" ); } else { + strncpy( url->file, i, MAX_STRING ); *i = 0; - g_snprintf( url->dir, MAX_STRING, "/%s", i + 1 ); - if( url->proto == PROTO_HTTP ) - http_encode( url->dir ); } strncpy( url->host, s, MAX_STRING ); - j = strchr( url->dir, '?' ); - if( j != NULL ) - *j = 0; - i = strrchr( url->dir, '/' ); - *i = 0; - if( j != NULL ) - *j = '?'; - if( i == NULL ) - { - strcpy( url->file, url->dir ); - strcpy( url->dir, "/" ); - } - else - { - strcpy( url->file, i + 1 ); - strcat( url->dir, "/" ); - } /* Check for username in host field */ if( strrchr( url->host, '@' ) != NULL ) @@ -95,15 +78,7 @@ int url_set( url_t *url, char *set_url ) /* If not: Fill in defaults */ else { - if( url->proto == PROTO_FTP ) - { - strcpy( url->user, "anonymous" ); - strcpy( url->pass, "-p.artmaps@lintux.cx" ); - } - else - { - *url->user = *url->pass = 0; - } + *url->user = *url->pass = 0; } /* Password? */ @@ -116,13 +91,14 @@ int url_set( url_t *url, char *set_url ) if( ( i = strchr( url->host, ':' ) ) != NULL ) { *i = 0; - sscanf( i + 1, "%i", &url->port ); + sscanf( i + 1, "%d", &url->port ); } - /* Take default port numbers from /etc/services */ else { if( url->proto == PROTO_HTTP ) - url->port = 8080; + url->port = 80; + else if( url->proto == PROTO_HTTPS ) + url->port = 443; else if( url->proto == PROTO_SOCKS4 || url->proto == PROTO_SOCKS4 ) url->port = 1080; } @@ -25,8 +25,8 @@ #include "bitlbee.h" -#define PROTO_FTP 1 #define PROTO_HTTP 2 +#define PROTO_HTTPS 5 #define PROTO_SOCKS4 3 #define PROTO_SOCKS5 4 #define PROTO_DEFAULT PROTO_HTTP @@ -36,7 +36,6 @@ typedef struct url int proto; int port; char host[MAX_STRING]; - char dir[MAX_STRING]; char file[MAX_STRING]; char user[MAX_STRING]; char pass[MAX_STRING]; |