Skip to content

Commit

Permalink
Add a patch status to recover failed requests
Browse files Browse the repository at this point in the history
Signed-off-by: Brandon Mitchell <git@bmitch.net>
  • Loading branch information
sudo-bmitch committed Nov 26, 2022
1 parent f72e501 commit a330837
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
27 changes: 26 additions & 1 deletion conformance/02_push_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
var test02Push = func() {
g.Context(titlePush, func() {

var lastResponse *reggie.Response
var lastResponse, prevResponse *reggie.Response

g.Context("Setup", func() {
// No setup required at this time for push tests
Expand Down Expand Up @@ -175,6 +175,7 @@ var test02Push = func() {
Expect(err).To(BeNil())
location := resp.Header().Get("Location")
Expect(location).ToNot(BeEmpty())
prevResponse = resp

req = client.NewRequest(reggie.PATCH, resp.GetRelativeLocation()).
SetHeader("Content-Type", "application/octet-stream").
Expand All @@ -184,6 +185,30 @@ var test02Push = func() {
resp, err = client.Do(req)
Expect(err).To(BeNil())
Expect(resp.StatusCode()).To(Equal(http.StatusAccepted))
Expect(resp.Header().Get("Range")).To(Equal(testBlobBChunk1Range))
lastResponse = resp
})

g.Specify("Retry previous blob chunk should return 416", func() {
SkipIfDisabled(push)
req := client.NewRequest(reggie.PATCH, prevResponse.GetRelativeLocation()).
SetHeader("Content-Type", "application/octet-stream").
SetHeader("Content-Length", testBlobBChunk1Length).
SetHeader("Content-Range", testBlobBChunk1Range).
SetBody(testBlobBChunk1)
resp, err := client.Do(req)
Expect(err).To(BeNil())
Expect(resp.StatusCode()).To(Equal(http.StatusRequestedRangeNotSatisfiable))
})

g.Specify("Get on stale blob upload should return 204 with a range and location", func() {
SkipIfDisabled(push)
req := client.NewRequest(reggie.GET, prevResponse.GetRelativeLocation())
resp, err := client.Do(req)
Expect(err).To(BeNil())
Expect(resp.StatusCode()).To(Equal(http.StatusNoContent))
Expect(resp.Header().Get("Location")).ToNot(BeEmpty())
Expect(resp.Header().Get("Range")).To(Equal(fmt.Sprintf("bytes=%s", testBlobBChunk1Range)))
lastResponse = resp
})

Expand Down
25 changes: 23 additions & 2 deletions spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -348,16 +348,20 @@ It MUST match the following regular expression:

The `<length>` is the content-length, in bytes, of the current chunk.

Each successful chunk upload MUST have a `202 Accepted` response code, and MUST have the following header:
Each successful chunk upload MUST have a `202 Accepted` response code, and MUST have the following headers:

```
Location <location>
Location: <location>
Range: 0-<end-of-range>
```

Each consecutive chunk upload SHOULD use the `<location>` provided in the response to the previous chunk upload.

The `<end-of-range>` value is the position of the last uploaded byte.

Chunks MUST be uploaded in order, with the first byte of a chunk being the last chunk's `<end-of-range>` plus one.
If a chunk is uploaded out of order, the registry MUST respond with a `416 Requested Range Not Satisfiable` code.
A GET request may be used to retrieve the current valid offset and upload location.

The final chunk MAY be uploaded using a `PATCH` request or it MAY be uploaded in the closing `PUT` request.
Regardless of how the final chunk is uploaded, the session MUST be closed with a `PUT` request.
Expand Down Expand Up @@ -385,6 +389,22 @@ Location: <blob-location>

Here, `<blob-location>` is a pullable blob URL.

---

To get the current status after a 416 error, issue a `GET` request to a URL `<location>` <sup>[end-13](#endpoints)</sup>.

The `<location>` refers to the URL obtained from any preceding `POST` or `PATCH` request.

The response to an active upload `<location>` MUST be a `204 No Content` response code, and MUST have the following headers:

```
Location: <location>
Range: 0-<end-of-range>
```

The following chunk upload SHOULD use the `<location>` provided in the response.

The `<end-of-range>` value is the position of the last uploaded byte.

##### Mounting a blob from another repository

Expand Down Expand Up @@ -716,6 +736,7 @@ This endpoint MAY be used for authentication/authorization purposes, but this is
| end-11 | `POST` | `/v2/<name>/blobs/uploads/?mount=<digest>&from=<other_name>` | `201` | `404` |
| end-12a | `GET` | `/v2/<name>/referrers/<digest>` | `200` | `404`/`400` |
| end-12b | `GET` | `/v2/<name>/referrers/<digest>?artifactType=<artifactType>` | `200` | `404`/`400` |
| end-13 | `GET` | `/v2/<name>/blobs/uploads/<reference>` | `204` | `404` |

#### Error Codes

Expand Down

0 comments on commit a330837

Please sign in to comment.