Changes in lib/http_client.c [a72dc2b:c1d9c95]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/http_client.c
ra72dc2b rc1d9c95 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-201 1Wilmer van der Gaast and others *4 * Copyright 2002-2012 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 73 73 printf( "About to send HTTP request:\n%s\n", req->request ); 74 74 75 return ( req );75 return req; 76 76 } 77 77 … … 173 173 static gboolean http_ssl_connected( gpointer data, int returncode, void *source, b_input_condition cond ) 174 174 { 175 //The returncode is not used at the moment.176 175 struct http_request *req = data; 177 176 … … 194 193 } 195 194 195 static gboolean http_handle_headers( struct http_request *req ); 196 196 197 static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond ) 197 198 { 198 199 struct http_request *req = data; 199 int evil_server = 0;200 char buffer[2048];201 char *end1, *end2;200 char buffer[4096]; 201 char *s; 202 size_t content_length; 202 203 int st; 203 204 … … 218 219 packets that abort connections! \o/ */ 219 220 220 goto got_reply;221 goto eof; 221 222 } 222 223 } 223 224 else if( st == 0 ) 224 225 { 225 goto got_reply;226 goto eof; 226 227 } 227 228 } … … 239 240 else if( st == 0 ) 240 241 { 241 goto got_reply;242 } 243 } 244 245 if( st > 0 )242 goto eof; 243 } 244 } 245 246 if( st > 0 && !req->sbuf ) 246 247 { 247 248 req->reply_headers = g_realloc( req->reply_headers, req->bytes_read + st + 1 ); 248 249 memcpy( req->reply_headers + req->bytes_read, buffer, st ); 249 250 req->bytes_read += st; 250 } 251 252 st = 0; 253 } 254 255 if( st >= 0 && ( req->flags & HTTPC_STREAMING ) ) 256 { 257 if( !req->reply_body && 258 ( strstr( req->reply_headers, "\r\n\r\n" ) || 259 strstr( req->reply_headers, "\n\n" ) ) ) 260 { 261 size_t hlen; 262 263 /* We've now received all headers, so process them once 264 before we start feeding back data. */ 265 if( !http_handle_headers( req ) ) 266 return FALSE; 267 268 hlen = req->reply_body - req->reply_headers; 269 270 req->sblen = req->bytes_read - hlen; 271 req->sbuf = g_memdup( req->reply_body, req->sblen + 1 ); 272 req->reply_headers = g_realloc( req->reply_headers, hlen + 1 ); 273 274 req->reply_body = req->sbuf; 275 } 276 277 if( st > 0 ) 278 { 279 int pos = req->reply_body - req->sbuf; 280 req->sbuf = g_realloc( req->sbuf, req->sblen + st + 1 ); 281 memcpy( req->sbuf + req->sblen, buffer, st ); 282 req->bytes_read += st; 283 req->sblen += st; 284 req->sbuf[req->sblen] = '\0'; 285 req->reply_body = req->sbuf + pos; 286 req->body_size = req->sblen - pos; 287 } 288 289 if( req->reply_body ) 290 req->func( req ); 291 } 292 293 if( ssl_pending( req->ssl ) ) 294 return http_incoming_data( data, source, cond ); 251 295 252 296 /* There will be more! */ … … 255 299 http_incoming_data, req ); 256 300 257 if( ssl_pending( req->ssl ) ) 258 return http_incoming_data( data, source, cond ); 259 else 260 return FALSE; 261 262 got_reply: 301 return FALSE; 302 303 eof: 304 req->flags |= HTTPC_EOF; 305 263 306 /* Maybe if the webserver is overloaded, or when there's bad SSL 264 307 support... */ … … 269 312 } 270 313 314 if( !( req->flags & HTTPC_STREAMING ) ) 315 { 316 /* Returns FALSE if we were redirected, in which case we should abort 317 and not run any callback yet. */ 318 if( !http_handle_headers( req ) ) 319 return FALSE; 320 } 321 322 cleanup: 323 if( req->ssl ) 324 ssl_disconnect( req->ssl ); 325 else 326 closesocket( req->fd ); 327 328 if( ( s = get_rfc822_header( req->reply_headers, "Content-Length", 0 ) ) && 329 sscanf( s, "%zd", &content_length ) == 1 ) 330 { 331 if( content_length < req->body_size ) 332 { 333 req->status_code = -1; 334 g_free( req->status_string ); 335 req->status_string = g_strdup( "Response truncated" ); 336 } 337 } 338 g_free( s ); 339 340 if( getenv( "BITLBEE_DEBUG" ) && req ) 341 printf( "Finishing HTTP request with status: %s\n", 342 req->status_string ? req->status_string : "NULL" ); 343 344 req->func( req ); 345 http_free( req ); 346 return FALSE; 347 } 348 349 /* Splits headers and body. Checks result code, in case of 300s it'll handle 350 redirects. If this returns FALSE, don't call any callbacks! */ 351 static gboolean http_handle_headers( struct http_request *req ) 352 { 353 char *end1, *end2; 354 int evil_server = 0; 355 271 356 /* Zero termination is very convenient. */ 272 req->reply_headers[req->bytes_read] = 0;357 req->reply_headers[req->bytes_read] = '\0'; 273 358 274 359 /* Find the separation between headers and body, and keep stupid … … 289 374 { 290 375 req->status_string = g_strdup( "Malformed HTTP reply" ); 291 goto cleanup;376 return TRUE; 292 377 } 293 378 … … 306 391 if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL ) 307 392 { 308 if( sscanf( end1 + 1, "% d", &req->status_code ) != 1 )393 if( sscanf( end1 + 1, "%hd", &req->status_code ) != 1 ) 309 394 { 310 395 req->status_string = g_strdup( "Can't parse status code" ); … … 349 434 { 350 435 req->status_string = g_strdup( "Can't locate Location: header" ); 351 goto cleanup;436 return TRUE; 352 437 } 353 438 … … 369 454 req->status_string = g_strdup( "Can't handle recursive redirects" ); 370 455 371 goto cleanup;456 return TRUE; 372 457 } 373 458 else … … 380 465 s = strstr( loc, "\r\n" ); 381 466 if( s == NULL ) 382 goto cleanup;467 return TRUE; 383 468 384 469 url = g_new0( url_t, 1 ); … … 389 474 req->status_string = g_strdup( "Malformed redirect URL" ); 390 475 g_free( url ); 391 goto cleanup;476 return TRUE; 392 477 } 393 478 … … 401 486 req->status_string = g_strdup( "Error while rebuilding request string" ); 402 487 g_free( url ); 403 goto cleanup;488 return TRUE; 404 489 } 405 490 … … 467 552 req->status_string = g_strdup( "Connection problem during redirect" ); 468 553 g_free( new_request ); 469 goto cleanup;554 return TRUE; 470 555 } 471 556 … … 480 565 } 481 566 482 /* Assume that a closed connection means we're finished, this indeed 483 breaks with keep-alive connections and faulty connections. */ 484 req->finished = 1; 485 486 cleanup: 567 return TRUE; 568 } 569 570 void http_flush_bytes( struct http_request *req, size_t len ) 571 { 572 if( len <= 0 || len > req->body_size || !( req->flags & HTTPC_STREAMING ) ) 573 return; 574 575 req->reply_body += len; 576 req->body_size -= len; 577 578 if( req->reply_body - req->sbuf >= 512 ) 579 { 580 char *new = g_memdup( req->reply_body, req->body_size + 1 ); 581 g_free( req->sbuf ); 582 req->reply_body = req->sbuf = new; 583 req->sblen = req->body_size; 584 } 585 } 586 587 void http_close( struct http_request *req ) 588 { 589 if( !req ) 590 return; 591 592 if( req->inpa > 0 ) 593 b_event_remove( req->inpa ); 594 487 595 if( req->ssl ) 488 596 ssl_disconnect( req->ssl ); … … 490 598 closesocket( req->fd ); 491 599 492 if( getenv( "BITLBEE_DEBUG" ) && req )493 printf( "Finishing HTTP request with status: %s\n",494 req->status_string ? req->status_string : "NULL" );495 496 req->func( req );497 600 http_free( req ); 498 return FALSE;499 601 } 500 602 … … 504 606 g_free( req->reply_headers ); 505 607 g_free( req->status_string ); 608 g_free( req->sbuf ); 506 609 g_free( req ); 507 610 } 508
Note: See TracChangeset
for help on using the changeset viewer.