Mercurial > audlegacy-plugins
comparison src/curl/curl.c @ 764:5810f14fc8e6 trunk
[svn] - revert r1624 due to the fact that it breaks
author | nenolod |
---|---|
date | Thu, 01 Mar 2007 04:33:43 -0800 |
parents | 58dcfb61cf76 |
children | b02927277ccb |
comparison
equal
deleted
inserted
replaced
763:58dcfb61cf76 | 764:5810f14fc8e6 |
---|---|
30 | 30 |
31 #define BUFFER_SIZE 256 * 1024 | 31 #define BUFFER_SIZE 256 * 1024 |
32 #define REVERSE_SEEK_SIZE 2048 | 32 #define REVERSE_SEEK_SIZE 2048 |
33 | 33 |
34 #define DEBUG_CONNECTION 0 | 34 #define DEBUG_CONNECTION 0 |
35 #define DEBUG_OPEN_CLOSE 0 | 35 #define DEBUG_OPEN_CLOSE 1 |
36 #define DEBUG_SEEK 0 | 36 #define DEBUG_SEEK 0 |
37 #define DEBUG_READ 0 | 37 #define DEBUG_READ 0 |
38 #define DEBUG_HEADERS 0 | 38 #define DEBUG_HEADERS 0 |
39 #define DEBUG_ICY 0 | 39 #define DEBUG_ICY 0 |
40 #define DEBUG_ICY_WRAP 0 | 40 #define DEBUG_ICY_WRAP 0 |
59 gchar *buffer; | 59 gchar *buffer; |
60 | 60 |
61 gsize rd_index; | 61 gsize rd_index; |
62 gsize wr_index; | 62 gsize wr_index; |
63 | 63 |
64 gsize hdrs_start; | |
65 gsize hdr_index; | 64 gsize hdr_index; |
66 | 65 |
67 GSList *stream_stack; // stack for stream functions (getc, ungetc) | 66 GSList *stream_stack; // stack for stream functions (getc, ungetc) |
68 | 67 |
69 gboolean header; // true if we haven't finished the header yet | 68 gboolean header; // true if we haven't finished the header yet |
398 { | 397 { |
399 size_t leftover; | 398 size_t leftover; |
400 // Empty header means the end of the headers | 399 // Empty header means the end of the headers |
401 handle->header = 0; | 400 handle->header = 0; |
402 handle->hdr_index = (i + 2) % handle->buffer_length; | 401 handle->hdr_index = (i + 2) % handle->buffer_length; |
403 // There's some after the header; we have to put | 402 // We read from the start of the data in the request |
404 // it in the buffer where we started the headers | 403 handle->rd_index = handle->hdr_index; |
405 // and account for it in wr_abs. | 404 // We've already written the amount that's after |
406 leftover = (handle->wr_index - handle->hdr_index + | 405 // the header. |
407 handle->buffer_length) % | 406 leftover = (handle->wr_index - handle->hdr_index + handle->buffer_length) % handle->buffer_length; |
408 handle->buffer_length; | |
409 handle->wr_abs += leftover; | 407 handle->wr_abs += leftover; |
410 if (handle->download) | 408 if (handle->download) |
411 { | 409 { |
412 // the data which has to go into the | 410 // the data which has to go into the |
413 // beginning of the file must be at the end | 411 // beginning of the file must be at the end |
414 // of the input that we've dealt with. | 412 // of the input that we've dealt with. |
415 vfs_fwrite(ptr + ret - leftover, leftover, 1, | 413 vfs_fwrite(ptr + ret - leftover, leftover, 1, |
416 handle->download); | 414 handle->download); |
417 } | 415 } |
418 handle->wr_index = handle->hdrs_start; | |
419 if (handle->wr_index + leftover > handle->buffer_length) | |
420 { | |
421 g_print("Wrapped rewrite\n"); | |
422 memcpy(handle->buffer + handle->wr_index, ptr + ret, | |
423 handle->buffer_length - handle->wr_index); | |
424 memcpy(handle->buffer, ptr + ret + | |
425 handle->buffer_length - handle->wr_index, | |
426 leftover - handle->buffer_length + | |
427 handle->wr_index); | |
428 } | |
429 else | |
430 { | |
431 memcpy(handle->buffer + handle->wr_index, ptr + ret, | |
432 leftover); | |
433 } | |
434 handle->wr_index = (handle->wr_index + leftover) % | |
435 handle->buffer_length; | |
436 handle->icy_left = handle->icy_interval; | 416 handle->icy_left = handle->icy_interval; |
437 if (handle->icy_interval) | 417 if (handle->icy_interval) |
438 { | 418 { |
439 handle->icy_left -= | 419 handle->icy_left -= |
440 (handle->wr_index - handle->hdr_index + handle->buffer_length) % handle->buffer_length; | 420 (handle->wr_index - handle->hdr_index + handle->buffer_length) % handle->buffer_length; |
456 static gpointer | 436 static gpointer |
457 curl_manage_request(gpointer arg) | 437 curl_manage_request(gpointer arg) |
458 { | 438 { |
459 CurlHandle *handle = arg; | 439 CurlHandle *handle = arg; |
460 CURLcode result; | 440 CURLcode result; |
461 do | 441 if (DEBUG_CONNECTION) |
442 g_print("Connect %p\n", handle); | |
443 | |
444 if (handle->no_data) | |
445 curl_easy_setopt(handle->curl, CURLOPT_NOBODY, 1); | |
446 else | |
462 { | 447 { |
463 if (DEBUG_CONNECTION) | 448 if (DEBUG_CONNECTION) |
464 g_print("Connect %p\n", handle); | 449 g_print("Start from %d\n", handle->wr_abs); |
465 | 450 curl_easy_setopt(handle->curl, CURLOPT_RESUME_FROM, handle->wr_abs); |
466 if (handle->no_data) | 451 |
467 curl_easy_setopt(handle->curl, CURLOPT_NOBODY, 1); | 452 curl_easy_setopt(handle->curl, CURLOPT_NOBODY, 0); |
468 else | 453 curl_easy_setopt(handle->curl, CURLOPT_HTTPGET, 1); |
469 { | 454 } |
470 if (DEBUG_CONNECTION) | 455 |
471 g_print("Start from %d\n", handle->wr_abs); | 456 handle->header = 1; |
472 curl_easy_setopt(handle->curl, CURLOPT_RESUME_FROM, handle->wr_abs); | 457 handle->hdr_index = 0; |
473 | 458 handle->icy_interval = 0; |
474 curl_easy_setopt(handle->curl, CURLOPT_NOBODY, 0); | 459 |
475 curl_easy_setopt(handle->curl, CURLOPT_HTTPGET, 1); | 460 result = curl_easy_perform(handle->curl); |
476 } | 461 if (result == CURLE_OK) |
477 | 462 update_length(handle); |
478 handle->header = 1; | 463 // We expect to get CURLE_WRITE_ERROR if we cancel. |
479 handle->hdr_index = handle->wr_index; | 464 // We get CURLE_GOT_NOTHING if we send a HEAD request to a shoutcast server. |
480 handle->hdrs_start = handle->wr_index; | 465 // We get CURLE_HTTP_RANGE_ERROR if we try to use range with shoutcast. |
481 handle->icy_interval = 0; | 466 if (result != CURLE_OK && result != CURLE_WRITE_ERROR && |
482 | 467 result != CURLE_GOT_NOTHING && result != CURLE_HTTP_RANGE_ERROR && |
483 if (DEBUG_CONNECTION) | 468 result != CURLE_PARTIAL_FILE) |
484 g_print("About to perform %p\n", handle); | 469 { |
485 result = curl_easy_perform(handle->curl); | 470 g_print("Got curl error %d\n", result); |
486 if (result == CURLE_OK) | 471 handle->failed = 1; |
487 { | 472 } |
488 update_length(handle); | 473 if (DEBUG_CONNECTION) |
489 //g_print("Length: %d\n", handle->length); | 474 g_print("Done %p%s", handle, handle->cancel ? " (aborted)\n" : "\n"); |
490 } | |
491 // We expect to get CURLE_WRITE_ERROR if we cancel. | |
492 // We get CURLE_GOT_NOTHING if we send a HEAD request to a shoutcast server. | |
493 // We get CURLE_HTTP_RANGE_ERROR if we try to use range with shoutcast. | |
494 // Why do we get CURLE_PARTIAL_FILE? | |
495 if (result != CURLE_OK && result != CURLE_WRITE_ERROR && | |
496 result != CURLE_GOT_NOTHING && result != CURLE_HTTP_RANGE_ERROR && | |
497 result != CURLE_PARTIAL_FILE) | |
498 { | |
499 g_print("Got curl error %d\n", result); | |
500 handle->failed = 1; | |
501 } | |
502 if (DEBUG_CONNECTION) | |
503 g_print("Got curl error %d\n", result); | |
504 if (result == CURLE_PARTIAL_FILE) | |
505 { | |
506 if (DEBUG_CONNECTION) | |
507 g_print("Lost connection %p; restarting\n", handle); | |
508 continue; | |
509 } | |
510 if (DEBUG_CONNECTION) | |
511 g_print("Done %p%s", handle, handle->cancel ? " (aborted)\n" : "\n"); | |
512 break; | |
513 } | |
514 while (1); | |
515 handle->cancel = 1; | 475 handle->cancel = 1; |
516 return NULL; | 476 return NULL; |
517 } | 477 } |
518 | 478 |
519 static void curl_req_xfer(CurlHandle *handle) | 479 static void curl_req_xfer(CurlHandle *handle) |
524 return; | 484 return; |
525 } | 485 } |
526 if (!handle->thread) | 486 if (!handle->thread) |
527 { | 487 { |
528 handle->cancel = 0; | 488 handle->cancel = 0; |
529 handle->rd_index = 0; //BUFFER_SIZE - 100; | 489 handle->wr_index = 0; |
530 handle->wr_index = handle->rd_index; | 490 handle->rd_index = 0; |
531 handle->wr_abs = handle->rd_abs; | 491 handle->wr_abs = handle->rd_abs; |
532 if (DEBUG_CONNECTION) | 492 if (DEBUG_CONNECTION) |
533 g_print("Starting connection %p at %d\n", handle, handle->wr_abs); | 493 g_print("Starting connection %p at %d\n", handle, handle->wr_abs); |
534 handle->thread = g_thread_create(curl_manage_request, handle, | 494 handle->thread = g_thread_create(curl_manage_request, handle, |
535 TRUE, NULL); | 495 TRUE, NULL); |
865 posn = handle->rd_abs; | 825 posn = handle->rd_abs; |
866 | 826 |
867 if (whence == SEEK_SET) | 827 if (whence == SEEK_SET) |
868 handle->rd_abs = offset; | 828 handle->rd_abs = offset; |
869 else if (whence == SEEK_END) | 829 else if (whence == SEEK_END) |
870 { | 830 handle->rd_abs = handle->length + offset; |
871 if (-offset > handle->length) | |
872 handle->rd_abs = 0; | |
873 else | |
874 handle->rd_abs = handle->length + offset; | |
875 } | |
876 else | 831 else |
877 { | 832 handle->rd_abs = handle->rd_abs + offset; |
878 if (-offset > handle->rd_abs) | |
879 handle->rd_abs = 0; | |
880 else | |
881 handle->rd_abs = handle->rd_abs + offset; | |
882 } | |
883 | |
884 if (handle->rd_abs > handle->length) | |
885 { | |
886 g_print("Seek before start of file: %d %d = %d\n", posn, offset, | |
887 handle->rd_abs); | |
888 } | |
889 | 833 |
890 // XXXX | 834 // XXXX |
891 // There's a race here between finding available space and | 835 // There's a race here between finding available space and |
892 // allocating it and the check below. | 836 // allocating it and the check below. |
893 | 837 |