Ignore:
Timestamp:
2005-12-17T18:55:46Z (18 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
2db811a
Parents:
8a9afe4 (diff), b5a22e3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Successfully tested http_client, added support for redirections.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/http_client.c

    r8a9afe4 r52b3a99  
    55  \********************************************************************/
    66
    7 /* HTTP(S) module (actually, it only does HTTPS right now)              */
     7/* HTTP(S) module                                                       */
    88
    99/*
     
    2525
    2626#include <string.h>
     27#include <stdio.h>
    2728
    2829#include "sock.h"
    2930#include "http_client.h"
     31#include "url.h"
    3032
    3133
     
    6163        }
    6264       
     65        req->func = func;
     66        req->data = data;
    6367        req->request = g_strdup( request );
    6468        req->request_length = strlen( request );
     
    103107                        if( !sockerr_again() )
    104108                        {
    105                                 close( req->fd );
     109                                closesocket( req->fd );
    106110                                goto error;
    107111                        }
     
    188192                req->reply_headers = g_realloc( req->reply_headers, req->bytes_read + st + 1 );
    189193                memcpy( req->reply_headers + req->bytes_read, buffer, st );
     194                req->bytes_read += st;
    190195        }
    191196       
     
    208213        if( end2 && end2 < end1 )
    209214        {
    210                 end1 = end2;
     215                end1 = end2 + 1;
    211216                evil_server = 1;
    212217        }
     218        else
     219        {
     220                end1 += 2;
     221        }
    213222       
    214223        if( end1 )
     
    217226               
    218227                if( evil_server )
     228                        req->reply_body = end1 + 1;
     229                else
    219230                        req->reply_body = end1 + 2;
     231        }
     232       
     233        if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL )
     234        {
     235                if( sscanf( end1 + 1, "%d", &req->status_code ) != 1 )
     236                        req->status_code = -1;
     237        }
     238        else
     239        {
     240                req->status_code = -1;
     241        }
     242       
     243        if( req->status_code == 301 || req->status_code == 302 )
     244        {
     245                char *loc, *new_request, *new_host;
     246                int error = 0, new_port, new_proto;
     247               
     248                loc = strstr( req->reply_headers, "\nLocation: " );
     249                if( loc == NULL ) /* We can't handle this redirect... */
     250                        goto cleanup;
     251               
     252                loc += 11;
     253                while( *loc == ' ' )
     254                        loc ++;
     255               
     256                /* TODO/FIXME: Possibly have to handle relative redirections,
     257                   and rewrite Host: headers. Not necessary for now, it's
     258                   enough for passport authentication like this. */
     259               
     260                if( *loc == '/' )
     261                {
     262                        /* Just a different pathname... */
     263                       
     264                        /* Since we don't cache the servername, and since we
     265                           don't need this yet anyway, I won't implement it. */
     266                       
     267                        goto cleanup;
     268                }
    220269                else
    221                         req->reply_body = end1 + 4;
     270                {
     271                        /* A whole URL */
     272                        url_t *url;
     273                        char *s;
     274                       
     275                        s = strstr( loc, "\r\n" );
     276                        if( s == NULL )
     277                                goto cleanup;
     278                       
     279                        url = g_new0( url_t, 1 );
     280                        *s = 0;
     281                       
     282                        if( !url_set( url, loc ) )
     283                        {
     284                                g_free( url );
     285                                goto cleanup;
     286                        }
     287                       
     288                        /* Okay, this isn't fun! We have to rebuild the request... :-( */
     289                        new_request = g_malloc( req->request_length + strlen( url->file ) );
     290                       
     291                        /* So, now I just allocated enough memory, so I'm
     292                           going to use strcat(), whether you like it or not. :-) */
     293                       
     294                        /* First, find the GET/POST/whatever from the original request. */
     295                        s = strchr( req->request, ' ' );
     296                        if( s == NULL )
     297                        {
     298                                g_free( new_request );
     299                                g_free( url );
     300                                goto cleanup;
     301                        }
     302                       
     303                        *s = 0;
     304                        sprintf( new_request, "%s %s HTTP/1.0\r\n", req->request, url->file );
     305                        *s = ' ';
     306                       
     307                        s = strstr( req->request, "\r\n" );
     308                        if( s == NULL )
     309                        {
     310                                g_free( new_request );
     311                                g_free( url );
     312                                goto cleanup;
     313                        }
     314                       
     315                        strcat( new_request, s + 2 );
     316                        new_host = g_strdup( url->host );
     317                        new_port = url->port;
     318                        new_proto = url->proto;
     319                       
     320                        g_free( url );
     321                }
     322               
     323                if( req->ssl )
     324                        ssl_disconnect( req->ssl );
     325                else
     326                        closesocket( req->fd );
     327               
     328                req->fd = -1;
     329                req->ssl = 0;
     330               
     331                if( new_proto == PROTO_HTTPS )
     332                {
     333                        req->ssl = ssl_connect( new_host, new_port, http_ssl_connected, req );
     334                        if( req->ssl == NULL )
     335                                error = 1;
     336                }
     337                else
     338                {
     339                        req->fd = proxy_connect( new_host, new_port, http_connected, req );
     340                        if( req->fd < 0 )
     341                                error = 1;
     342                }
     343               
     344                if( error )
     345                {
     346                        g_free( new_request );
     347                        goto cleanup;
     348                }
     349               
     350                g_free( req->request );
     351                g_free( req->reply_headers );
     352                req->request = new_request;
     353                req->request_length = strlen( new_request );
     354                req->bytes_read = req->bytes_written = req->inpa = 0;
     355                req->reply_headers = req->reply_body = NULL;
     356               
     357                return;
    222358        }
    223359       
     
    230366                ssl_disconnect( req->ssl );
    231367        else
    232                 close( req->fd );
     368                closesocket( req->fd );
    233369       
    234370        req->func( req );
Note: See TracChangeset for help on using the changeset viewer.