- Timestamp:
- 2011-12-17T13:50:01Z (13 years ago)
- 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. - Location:
- lib
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/http_client.c
r87dddee r6e9ae72 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-20 05Wilmer van der Gaast and others *4 * Copyright 2002-2011 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 69 69 req->request_length = strlen( request ); 70 70 req->redir_ttl = 3; 71 72 if( getenv( "BITLBEE_DEBUG" ) ) 73 printf( "About to send HTTP request:\n%s\n", req->request ); 71 74 72 75 return( req ); … … 240 243 http_incoming_data, req ); 241 244 242 return FALSE; 245 if( ssl_pending( req->ssl ) ) 246 return http_incoming_data( data, source, cond ); 247 else 248 return FALSE; 243 249 244 250 got_reply: … … 275 281 276 282 *end1 = 0; 283 284 if( getenv( "BITLBEE_DEBUG" ) ) 285 printf( "HTTP response headers:\n%s\n", req->reply_headers ); 277 286 278 287 if( evil_server ) … … 314 323 } 315 324 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 ) 317 327 { 318 328 char *loc, *new_request, *new_host; … … 354 364 url_t *url; 355 365 char *s; 366 const char *new_method; 356 367 357 368 s = strstr( loc, "\r\n" ); … … 369 380 } 370 381 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" ) ) ) ) 381 388 { 382 389 req->status_string = g_strdup( "Error while rebuilding request string" ); 383 g_free( new_request );384 390 g_free( url ); 385 391 goto cleanup; 386 392 } 387 393 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 389 416 new_host = g_strdup( url->host ); 390 417 new_port = url->port; 391 418 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'; 392 424 393 425 g_free( url ); … … 402 434 req->ssl = NULL; 403 435 436 if( getenv( "BITLBEE_DEBUG" ) ) 437 printf( "New headers for redirected HTTP request:\n%s\n", new_request ); 438 404 439 if( new_proto == PROTO_HTTPS ) 405 440 { … … 443 478 closesocket( req->fd ); 444 479 480 if( getenv( "BITLBEE_DEBUG" ) && req ) 481 printf( "Finishing HTTP request with status: %s\n", 482 req->status_string ? req->status_string : "NULL" ); 483 445 484 req->func( req ); 446 485 http_free( req ); -
lib/ssl_client.h
r87dddee r6e9ae72 63 63 G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len ); 64 64 65 /* See ssl_openssl.c for an explanation. */ 65 /* Now needed by most SSL libs. See for more info: 66 http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209 67 http://www.openssl.org/docs/ssl/SSL_pending.html 68 69 Required because OpenSSL empties the TCP buffer completely but doesn't 70 necessarily give us all the unencrypted data. Or maybe you didn't ask 71 for all of it because your buffer is too small. 72 73 Returns 0 if there's nothing left, 1 if there's more data. */ 66 74 G_MODULE_EXPORT int ssl_pending( void *conn ); 67 75 -
lib/ssl_gnutls.c
r87dddee r6e9ae72 45 45 #endif 46 46 47 #define SSLDEBUG 0 48 47 49 struct scd 48 50 { … … 135 137 gnutls_certificate_allocate_credentials( &conn->xcred ); 136 138 gnutls_init( &conn->session, GNUTLS_CLIENT ); 137 gnutls_transport_set_lowat( conn->session, 1 ); 139 #if GNUTLS_VERSION_NUMBER < 0x020c00 140 gnutls_transport_set_lowat( conn->session, 0 ); 141 #endif 138 142 gnutls_set_default_priority( conn->session ); 139 143 gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred ); … … 187 191 { 188 192 ssl_errno = SSL_NOHANDSHAKE; 189 return ( -1 );193 return -1; 190 194 } 191 195 … … 196 200 ssl_errno = SSL_AGAIN; 197 201 198 if( 0 && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 1, buf, st );202 if( SSLDEBUG && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 2, buf, st ); 199 203 200 204 return st; … … 208 212 { 209 213 ssl_errno = SSL_NOHANDSHAKE; 210 return ( -1 );214 return -1; 211 215 } 212 216 … … 217 221 ssl_errno = SSL_AGAIN; 218 222 219 if( 0 && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 1, buf, st );223 if( SSLDEBUG && getenv( "BITLBEE_DEBUG" ) && st > 0 ) len = write( 2, buf, st ); 220 224 221 225 return st; 222 226 } 223 227 224 /* See ssl_openssl.c for an explanation. */225 228 int ssl_pending( void *conn ) 226 229 { 227 return 0; 230 if( conn == NULL ) 231 return 0; 232 233 if( !((struct scd*)conn)->established ) 234 { 235 ssl_errno = SSL_NOHANDSHAKE; 236 return 0; 237 } 238 239 return gnutls_record_check_pending( ((struct scd*)conn)->session ) != 0; 228 240 } 229 241 -
lib/ssl_nss.c
r87dddee r6e9ae72 207 207 } 208 208 209 /* See ssl_openssl.c for an explanation. */210 209 int ssl_pending( void *conn ) 211 210 { -
lib/ssl_openssl.c
r87dddee r6e9ae72 241 241 } 242 242 243 /* Only OpenSSL *really* needs this (and well, maybe NSS). See for more info:244 http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209245 http://www.openssl.org/docs/ssl/SSL_pending.html246 247 Required because OpenSSL empties the TCP buffer completely but doesn't248 necessarily give us all the unencrypted data.249 250 Returns 0 if there's nothing left or if we don't have to care (GnuTLS),251 1 if there's more data. */252 243 int ssl_pending( void *conn ) 253 244 { -
lib/xmltree.c
r87dddee r6e9ae72 323 323 } 324 324 325 #ifdef DEBUG326 325 void xt_print( struct xt_node *node ) 327 326 { … … 331 330 /* Indentation */ 332 331 for( c = node; c->parent; c = c->parent ) 333 printf(" " );332 fprintf( stderr, " " ); 334 333 335 334 /* Start the tag */ 336 printf("<%s", node->name );335 fprintf( stderr, "<%s", node->name ); 337 336 338 337 /* Print the attributes */ … … 340 339 { 341 340 char *v = g_markup_escape_text( node->attr[i].value, -1 ); 342 printf(" %s=\"%s\"", node->attr[i].key, v );341 fprintf( stderr, " %s=\"%s\"", node->attr[i].key, v ); 343 342 g_free( v ); 344 343 } … … 349 348 if( node->text == NULL && node->children == NULL ) 350 349 { 351 printf("/>\n" );350 fprintf( stderr, "/>\n" ); 352 351 return; 353 352 /* Then we're finished! */ … … 355 354 356 355 /* Otherwise... */ 357 printf(">" );356 fprintf( stderr, ">" ); 358 357 359 358 /* Only print the text if it contains more than whitespace (TEST). */ … … 364 363 { 365 364 char *v = g_markup_escape_text( node->text, -1 ); 366 printf("%s", v );365 fprintf( stderr, "%s", v ); 367 366 g_free( v ); 368 367 } … … 370 369 371 370 if( node->children ) 372 printf("\n" );371 fprintf( stderr, "\n" ); 373 372 374 373 for( c = node->children; c; c = c->next ) … … 377 376 if( node->children ) 378 377 for( c = node; c->parent; c = c->parent ) 379 printf(" " );378 fprintf( stderr, " " ); 380 379 381 380 /* Non-empty tag is now finished. */ 382 printf( "</%s>\n", node->name ); 383 } 384 #endif 381 fprintf( stderr, "</%s>\n", node->name ); 382 } 385 383 386 384 struct xt_node *xt_dup( struct xt_node *node ) … … 557 555 } 558 556 557 /* Strip a few non-printable characters that aren't allowed in XML streams 558 (and upset some XMPP servers for example). */ 559 void xt_strip_text( char *in ) 560 { 561 char *out = in; 562 static const char nonprint[32] = { 563 0, 0, 0, 0, 0, 0, 0, 0, /* 0..7 */ 564 0, 1, 1, 0, 0, 1, 0, 0, /* 9 (tab), 10 (\n), 13 (\r) */ 565 }; 566 567 if( !in ) 568 return; 569 570 while( *in ) 571 { 572 if( (unsigned int) *in >= ' ' || nonprint[(unsigned int) *in] ) 573 *out ++ = *in; 574 in ++; 575 } 576 *out = *in; 577 } 578 559 579 struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children ) 560 580 { … … 568 588 if( text ) 569 589 { 570 node->text_len = strlen( text ); 571 node->text = g_memdup( text, node->text_len + 1 ); 590 node->text = g_strdup( text ); 591 xt_strip_text( node->text ); 592 node->text_len = strlen( node->text ); 572 593 } 573 594
Note: See TracChangeset
for help on using the changeset viewer.