{"id":15437110,"url":"https://github.com/awwright/http-progress","last_synced_at":"2025-04-19T18:59:04.949Z","repository":{"id":47501807,"uuid":"189172011","full_name":"awwright/http-progress","owner":"awwright","description":"Resumable Requests and Long-Running Operations in HTTP","archived":false,"fork":false,"pushed_at":"2023-11-07T10:19:44.000Z","size":187,"stargazers_count":19,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-07T16:59:53.207Z","etag":null,"topics":["http"],"latest_commit_sha":null,"homepage":"https://awwright.github.io/http-progress/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/awwright.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-05-29T07:20:34.000Z","updated_at":"2024-02-08T22:05:39.000Z","dependencies_parsed_at":"2024-11-10T17:15:15.000Z","dependency_job_id":null,"html_url":"https://github.com/awwright/http-progress","commit_stats":{"total_commits":96,"total_committers":1,"mean_commits":96.0,"dds":0.0,"last_synced_commit":"e035269367d11daadd861fa1d7f137a398584624"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awwright%2Fhttp-progress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awwright%2Fhttp-progress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awwright%2Fhttp-progress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awwright%2Fhttp-progress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awwright","download_url":"https://codeload.github.com/awwright/http-progress/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249239295,"owners_count":21235835,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["http"],"created_at":"2024-10-01T18:55:08.515Z","updated_at":"2025-04-16T12:30:55.922Z","avatar_url":"https://github.com/awwright.png","language":"JavaScript","readme":"# Resumable and Partial Operations in HTTP\n\nThis repository hosts a suite of documents for use in making large or long-running requests that manipulate the server state:\n\n* [Byte range PATCH](draft-wright-http-patch-byterange.md) - defines a media type for writing to a portion of a target resource\n* [Partial upload](draft-wright-http-partial-upload.md) - defines semantics for sparse and incompletely uploaded resources\n* [Resumable requests](draft-wright-http-resume-request.md) - defines two headers that specify where a partially finished request is stored and may be resumed at.\n* [Progress of long-running operations](draft-wright-http-progress.md) - defines several features that provides real-time updates of an operation being run by the server\n\n## Use cases\n\nIt supports the following use cases:\n\n\n### Patching a specific byte range\n\nUse PATCH with an existing resource using the `message/byterange` or `multipart/byteranges` media types.\n\n\n### Segmented new file creation\n\nCreate a new document using PATCH with a `message/byterange` media type, and the server will report the new file is only partially uploaded with a 2__ (Incomplete Content) status code.\n\n\n### Resume interrupted request\n\nWhen a request begins, the server may provide a `Request-Content-Location` representing the URI where the upload is being stored (either in memory or on disk). The request may be completed with a PATCH request to this resource.\n\n\n### Reporting realtime progress of a long-running request\n\nAllows a server to report the current status of an ongoing request using the `102 Processing` status code with a `Progress` header.\n\n\n### Resume interrupted response\nIf a request has been fully written, but the connection is interrupted before the final response is ready, the `Response-Message-Location` header specifies a request where the final status will be available at.\n\nIf the final headers have been written but the payload transfer was interrupted, the client may additionally use the `Content-Location` header as already defined.\n\n## Node.js Proof-of-Concept\n\nThis includes a proof-of-concept written for Node.js. As of Node.js v12.4.0, a patch is required to expose headers in 1xx interim status requests.\n\n* demo/client-lib.js - Simple library similar to Node.js http.request\n* demo/httpd.js - Server implementing resumable requests, the message/byterange PATCH type, and progress of long-running responses, and a test suite with various endpoints that respond in different ways\n* demo/test-run-suite.sh - start a server and run all the clients\n* demo/test-runner-client.sh - connect to and run the server's testing endpoints\n\n\n## Example\n\nThese documents may be deployed and used individually, or all together.\n\nHere is an example of a POST request that ends up using all of the functionality described here: An initial request that is interrupted and resumed, processed by the server, with regular updates on its progress, and reading the final response:\n\n### Request/response 1: Initial unsafe request\n\n~~~http\nPOST /collection HTTP/1.1\nContent-Type: application/json\nContent-Length: 100\nExpect: 100-continue\nPrefer: resume, processing, respond-async, wait=20\n\n~~~\n\nThe client now waits for a 100-continue response:\n\n~~~http\nHTTP/1.1 100 Continue\nRequest-Content-Location: http://example.com/job/1.request\nResponse-Message-Location: http://example.com/job/1.response\n~~~\n\nWith `100 Continue` in hand, the client begins uploading. However, somewhere along the way, the connection was lost, resulting in the server only receiving the first three bytes (a curly brace, and ␍␊ line-terminating sequence):\n\n~~~\n{\n~~~\n\n### Request/response 2: Re-synchronize upload\n\nAt this point, the client doesn't know exactly how many bytes the server actually received, so it makes a HEAD request to the request-content-location:\n\n~~~http\nHEAD http://example.com/job/1.request HTTP/1.1\n\n~~~\n\nThe server responds:\n\n~~~http\nHTTP/1.1 2__ Incomplete Content\nContent-Type: application/json\nContent-Length: 3\n\n~~~\n\nNow the client knows only the first three bytes were received by the server. The `2__ Incomplete Content` status code tells the client the query for the resource was successful, but the server is waiting for more data to be appended to the document.\n\n### Request/response 3: Resume upload\n\nThe client writes out a segment of the original upload using a PATCH request to the request-content-location:\n\n~~~http\nPATCH http://example.com/job/1.request HTTP/1.1\nContent-Type: message/byterange\nContent-Length: {length}\n\nContent-Type: application/json\nContent-Range: bytes 3-19/100\n\n\"key\": \"value\",\n~~~\n\nThe server responds with the `2__ (Incomplete Content)` status code, indicating the upload looks good so far, but no action can be taken until the resource is fully written to.\n\n### Request/response 3: Finish upload\n\nThe server writes out the remainder of the request using a PATCH request to the request-content-location:\n\n~~~http\nPATCH http://example.com/job/1.request HTTP/1.1\nContent-Type: message/byterange\n\nContent-Type: application/json\nContent-Range: bytes 20-99/100\n\n\"name\", \"...\" }\n~~~\n\nWhere `...` is content that has been omitted for brevity.\n\nThe server now begins processing this file, beginning by emitting a `102 Processing` interim response acknowledging that processing has begun. After 20 seconds of processing, the server realizes it has been running for longer than the client says it is prepared to wait, and so responds with `202 Accepted`.\n\n~~~http\nHTTP/1.1 102 Processing \nProgress: 0/3 \"Herding cats\"\nLocation: \u003c/1.status\u003e\n\nHTTP/1.1 102 Processing\nProgress: 1/3 \"Knitting sweaters\"\n\nHTTP/1.1 202 Accepted\nLocation: \u003c/1.status\u003e\nContent-Location: \u003c/1.status\u003e\nContent-Type: text/plain\n\nThe photographer is on step 2: Knitting sweaters\n~~~\n\n### Request/response 4: Reading the final status\n\nNow that the client has an address to a status document, it can request that document:\n\n\n~~~http\nGET http://example.com/1.status HTTP/1.1\nPrefer: processing, respond-async\n\n~~~\n\n~~~http\nHTTP/1.1 102 Processing\nProgress: 1/3 \"Knitting sweaters\"\n\nHTTP/1.1 102 Processing\nProgress: 2/3 \"Slaying dragons\"\n\nHTTP/1.1 200 OK\nProgress: 3/3 \"Available\"\nStatus-URI: 201 \u003c/capture\u003e\nStatus-Location: \u003c/photos/42\u003e\nContent-Type: text/plain\n\nThe photographer uploaded your image to:\n  \u003chttp://example.com/photos/42\u003e\n~~~\n\n\n### Request/response 5: Reading the final result\n\nIf written out in the initial request, the response-message-location is the address of document that contains the response (or what would have been the response) to the initial request:\n\n~~~http\nGET http://example.com/1.response HTTP/1.1\n\n~~~\n\n~~~http\nHTTP/1.1 201 Created\nLocation: http://example.com/items/1\nContent-Type: text/plain\nContent-Length: 19\n\nResource created.\n~~~\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawwright%2Fhttp-progress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawwright%2Fhttp-progress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawwright%2Fhttp-progress/lists"}