Skip to content

feat: add per-request upload and download bandwidth limiting - #524

Open
ChrisJr404 wants to merge 1 commit into
imroc:masterfrom
ChrisJr404:feat/bandwidth-limit
Open

feat: add per-request upload and download bandwidth limiting#524
ChrisJr404 wants to merge 1 commit into
imroc:masterfrom
ChrisJr404:feat/bandwidth-limit

Conversation

@ChrisJr404

Copy link
Copy Markdown
Contributor

What

Adds Request.SetUploadLimit and Request.SetDownloadLimit, so you can cap the
upload or download speed of a request to a given number of bytes per second.
This is the feature requested in #256.

client := req.C()

// don't read the response body faster than 512 KiB/s
resp, _ := client.R().
    SetDownloadLimit(512 * 1024).
    Get("https://example.com/big-file")

// don't push the request body faster than 256 KiB/s
client.R().
    SetUploadLimit(256 * 1024).
    SetFile("file", "big-file").
    Post("https://example.com/upload")

Global wrappers req.SetUploadLimit / req.SetDownloadLimit are there too, to
match the other request options.

Behavior

Both limits wrap the underlying body in a small reader that paces itself: after
each read it sleeps for however long those bytes should have taken at the limit,
so the average throughput converges to the configured rate. A value of 0 or less
clears the limit.

  • The download limit is applied to the raw bytes coming off the wire, before
    content decoding, so it reflects real network usage. It reuses the same
    response body wrapping mechanism as SetDownloadCallback and composes with it
    when both are set.
  • The upload limit wraps the request body reader, and is reapplied through
    GetBody so a retried or redirected request stays limited.

Default behavior is unchanged when neither limit is set.

Tests

Added ratelimit_test.go covering the limiter itself (bytes come through intact
and the read is throttled), SetDownloadLimit and SetUploadLimit end to end
against a local test server, and that a zero/negative value clears the limit.
The timing assertions only check a lower bound so they don't get flaky on slow
machines. go test ./... and go vet ./... both pass.

Closes #256

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature bandwith limit download/upload

1 participant