Changeset 6e9ae72 for lib/http_client.c


Ignore:
Timestamp:
2011-12-17T13:50:01Z (13 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
18c6d36
Parents:
87dddee (diff), 17f057d (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:

Mainline merge.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/http_client.c

    r87dddee r6e9ae72  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2005 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2011 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    6969        req->request_length = strlen( request );
    7070        req->redir_ttl = 3;
     71       
     72        if( getenv( "BITLBEE_DEBUG" ) )
     73                printf( "About to send HTTP request:\n%s\n", req->request );
    7174       
    7275        return( req );
     
    240243                                 http_incoming_data, req );
    241244       
    242         return FALSE;
     245        if( ssl_pending( req->ssl ) )
     246                return http_incoming_data( data, source, cond );
     247        else
     248                return FALSE;
    243249
    244250got_reply:
     
    275281       
    276282        *end1 = 0;
     283       
     284        if( getenv( "BITLBEE_DEBUG" ) )
     285                printf( "HTTP response headers:\n%s\n", req->reply_headers );
    277286       
    278287        if( evil_server )
     
    314323        }
    315324       
    316         if( ( req->status_code == 301 || req->status_code == 302 ) && req->redir_ttl-- > 0 )
     325        if( ( ( req->status_code >= 301 && req->status_code <= 303 ) ||
     326              req->status_code == 307 ) && req->redir_ttl-- > 0 )
    317327        {
    318328                char *loc, *new_request, *new_host;
     
    354364                        url_t *url;
    355365                        char *s;
     366                        const char *new_method;
    356367                       
    357368                        s = strstr( loc, "\r\n" );
     
    369380                        }
    370381                       
    371                         /* Okay, this isn't fun! We have to rebuild the request... :-( */
    372                         new_request = g_malloc( req->request_length + strlen( url->file ) );
    373                        
    374                         /* So, now I just allocated enough memory, so I'm
    375                            going to use strcat(), whether you like it or not. :-) */
    376                        
    377                         sprintf( new_request, "GET %s HTTP/1.0", url->file );
    378                        
    379                         s = strstr( req->request, "\r\n" );
    380                         if( s == NULL )
     382                        /* Find all headers and, if necessary, the POST request contents.
     383                           Skip the old Host: header though. This crappy code here means
     384                           anything using this http_client MUST put the Host: header at
     385                           the top. */
     386                        if( !( ( s = strstr( req->request, "\r\nHost: " ) ) &&
     387                               ( s = strstr( s + strlen( "\r\nHost: " ), "\r\n" ) ) ) )
    381388                        {
    382389                                req->status_string = g_strdup( "Error while rebuilding request string" );
    383                                 g_free( new_request );
    384390                                g_free( url );
    385391                                goto cleanup;
    386392                        }
    387393                       
    388                         strcat( new_request, s );
     394                        /* More or less HTTP/1.0 compliant, from my reading of RFC 2616.
     395                           Always perform a GET request unless we received a 301. 303 was
     396                           meant for this but it's HTTP/1.1-only and we're specifically
     397                           speaking HTTP/1.0. ...
     398                           
     399                           Well except someone at identi.ca's didn't bother reading any
     400                           RFCs and just return HTTP/1.1-specific status codes to HTTP/1.0
     401                           requests. Fuckers. So here we are, handle 301..303,307. */
     402                        if( strncmp( req->request, "GET", 3 ) == 0 )
     403                                /* GETs never become POSTs. */
     404                                new_method = "GET";
     405                        else if( req->status_code == 302 || req->status_code == 303 )
     406                                /* 302 de-facto becomes GET, 303 as specified by RFC 2616#10.3.3 */
     407                                new_method = "GET";
     408                        else
     409                                /* 301 de-facto should stay POST, 307 specifally RFC 2616#10.3.8 */
     410                                new_method = "POST";
     411                       
     412                        /* Okay, this isn't fun! We have to rebuild the request... :-( */
     413                        new_request = g_strdup_printf( "%s %s HTTP/1.0\r\nHost: %s%s",
     414                                                       new_method, url->file, url->host, s );
     415                       
    389416                        new_host = g_strdup( url->host );
    390417                        new_port = url->port;
    391418                        new_proto = url->proto;
     419                       
     420                        /* If we went from POST to GET, truncate the request content. */
     421                        if( new_request[0] != req->request[0] && new_request[0] == 'G' &&
     422                            ( s = strstr( new_request, "\r\n\r\n" ) ) )
     423                                s[4] = '\0';
    392424                       
    393425                        g_free( url );
     
    402434                req->ssl = NULL;
    403435               
     436                if( getenv( "BITLBEE_DEBUG" ) )
     437                        printf( "New headers for redirected HTTP request:\n%s\n", new_request );
     438       
    404439                if( new_proto == PROTO_HTTPS )
    405440                {
     
    443478                closesocket( req->fd );
    444479       
     480        if( getenv( "BITLBEE_DEBUG" ) && req )
     481                printf( "Finishing HTTP request with status: %s\n",
     482                        req->status_string ? req->status_string : "NULL" );
     483       
    445484        req->func( req );
    446485        http_free( req );
Note: See TracChangeset for help on using the changeset viewer.