Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

curl_easy_setopt CURLOPT_MAX_RECV_SPEED_LARGE not work during curl_multi_perform #6162

Closed
Kael1117 opened this issue Nov 3, 2020 · 2 comments
Closed
Labels

Comments

@Kael1117
Copy link

@Kael1117 Kael1117 commented Nov 3, 2020

Version: curl-7_73_0
Action: curl_easy_setopt CURLOPT_MAX_RECV_SPEED_LARGE after curl_multi_perform for a while.
Expect: Download speed is limited.
Actually: CURLOPT_MAX_RECV_SPEED_LARGE not work.

Issue:
void Curl_pgrsStartNow(struct Curl_easy *data)
data->progress.dl_limit_start and data->progress.ul_limit_start is zero, not Curl_now();

@Kael1117
Copy link
Author

@Kael1117 Kael1117 commented Nov 3, 2020

#include <stdio.h>
#include <string.h>
#include <curl/curl.h>

bool change_speed = false;

static int progress_callback(void *clientp,   double dltotal,   double dlnow,   double ultotal,   double ulnow)
{
    static time_t time_last = 0;
    static time_t time_start = 0;
    static double dlnow_last = 0;

    time_t now = time(NULL);
    if (time_last == 0) {
        time_last = now;
        time_start = now;
        dlnow_last = dlnow;
    }

    if (now > time_last + 1) {
        printf("Speed: %.2f KB/S\n", (dlnow - dlnow_last) / (now - time_last) / 1024);
        time_last = now;
        dlnow_last = dlnow;
    }

    if (dlnow / dltotal > 0.5 || now > time_start + 10) {
        change_speed = true;
    }

    return 0;
}

static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    return size * nmemb;
}

int main()
{
    CURL *easy_handle = curl_easy_init();
    if (!easy_handle) {
        return -1;
    }

    const char *url = "https://speed.hetzner.de/100MB.bin";
    curl_easy_setopt(easy_handle, CURLOPT_URL, url);
    curl_easy_setopt(easy_handle, CURLOPT_PROGRESSFUNCTION, progress_callback);
    curl_easy_setopt(easy_handle, CURLOPT_NOPROGRESS, 0L);
    curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(easy_handle, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(easy_handle, CURLOPT_SSL_VERIFYPEER, 0L);

    CURLM *multi_handle = curl_multi_init();
    if (!multi_handle) {
        return -1;
    }

    bool done = false;
    CURLcode result = CURLE_OK;

    CURLMcode mcode = curl_multi_add_handle(multi_handle, easy_handle);

    while (!mcode) {
        int still_running = 0;
        int numfds = 0;

        mcode = curl_multi_perform(multi_handle, &still_running);

        if (!still_running && !mcode) {
            int rc;
            CURLMsg *msg = curl_multi_info_read(multi_handle, &rc);
            if (msg) {
                result = msg->data.result;
                printf("Curl result: %d\n", result);
                break;
            }
        }else {
            long timeout;
            curl_multi_timeout(multi_handle, &timeout);
            if (timeout < 0) {
                timeout = 100;
            }

            curl_multi_wait(multi_handle, NULL, 0, timeout, &numfds);
        }

        static bool speed_changed = false;
        if (change_speed && !speed_changed) {
            curl_easy_setopt(easy_handle, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t)31415);

            speed_changed = true;
            printf("CURLOPT_MAX_RECV_SPEED_LARGE\n");
        }
    }

    curl_multi_remove_handle(multi_handle, easy_handle);
    curl_easy_cleanup(easy_handle);
    curl_multi_cleanup(multi_handle);

    return 0;
}
@bagder bagder added the libcurl API label Nov 3, 2020
@bagder
Copy link
Member

@bagder bagder commented Nov 3, 2020

We actually don't promise that setting and changing this option at run-time works. I would of course still be cool if it does, but I think there's not enough caution in the code being made for that situation.

bagder added a commit that referenced this issue Nov 7, 2020
By setting the speed limit time stamps unconditionally at transfer
start, we can start off a transfer without speed limits and yet allow
them to get set during transfer and have an effect.

Reported-by: Kael1117 on github
Fixes #6162
Closes #
@Kael1117 Kael1117 closed this Nov 9, 2020
bagder added a commit that referenced this issue Nov 9, 2020
By setting the speed limit time stamps unconditionally at transfer
start, we can start off a transfer without speed limits and yet allow
them to get set during transfer and have an effect.

Reported-by: Kael1117 on github
Fixes #6162
Closes #6184
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

2 participants
You can’t perform that action at this time.