Skip to content

Commit a330837

Browse files
committed
Add a patch status to recover failed requests
Signed-off-by: Brandon Mitchell <[email protected]>
1 parent f72e501 commit a330837

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

conformance/02_push_test.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
var test02Push = func() {
1313
g.Context(titlePush, func() {
1414

15-
var lastResponse *reggie.Response
15+
var lastResponse, prevResponse *reggie.Response
1616

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

179180
req = client.NewRequest(reggie.PATCH, resp.GetRelativeLocation()).
180181
SetHeader("Content-Type", "application/octet-stream").
@@ -184,6 +185,30 @@ var test02Push = func() {
184185
resp, err = client.Do(req)
185186
Expect(err).To(BeNil())
186187
Expect(resp.StatusCode()).To(Equal(http.StatusAccepted))
188+
Expect(resp.Header().Get("Range")).To(Equal(testBlobBChunk1Range))
189+
lastResponse = resp
190+
})
191+
192+
g.Specify("Retry previous blob chunk should return 416", func() {
193+
SkipIfDisabled(push)
194+
req := client.NewRequest(reggie.PATCH, prevResponse.GetRelativeLocation()).
195+
SetHeader("Content-Type", "application/octet-stream").
196+
SetHeader("Content-Length", testBlobBChunk1Length).
197+
SetHeader("Content-Range", testBlobBChunk1Range).
198+
SetBody(testBlobBChunk1)
199+
resp, err := client.Do(req)
200+
Expect(err).To(BeNil())
201+
Expect(resp.StatusCode()).To(Equal(http.StatusRequestedRangeNotSatisfiable))
202+
})
203+
204+
g.Specify("Get on stale blob upload should return 204 with a range and location", func() {
205+
SkipIfDisabled(push)
206+
req := client.NewRequest(reggie.GET, prevResponse.GetRelativeLocation())
207+
resp, err := client.Do(req)
208+
Expect(err).To(BeNil())
209+
Expect(resp.StatusCode()).To(Equal(http.StatusNoContent))
210+
Expect(resp.Header().Get("Location")).ToNot(BeEmpty())
211+
Expect(resp.Header().Get("Range")).To(Equal(fmt.Sprintf("bytes=%s", testBlobBChunk1Range)))
187212
lastResponse = resp
188213
})
189214

spec.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,16 +348,20 @@ It MUST match the following regular expression:
348348

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

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

353353
```
354-
Location <location>
354+
Location: <location>
355+
Range: 0-<end-of-range>
355356
```
356357

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

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

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

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

392+
---
393+
394+
To get the current status after a 416 error, issue a `GET` request to a URL `<location>` <sup>[end-13](#endpoints)</sup>.
395+
396+
The `<location>` refers to the URL obtained from any preceding `POST` or `PATCH` request.
397+
398+
The response to an active upload `<location>` MUST be a `204 No Content` response code, and MUST have the following headers:
399+
400+
```
401+
Location: <location>
402+
Range: 0-<end-of-range>
403+
```
404+
405+
The following chunk upload SHOULD use the `<location>` provided in the response.
406+
407+
The `<end-of-range>` value is the position of the last uploaded byte.
388408

389409
##### Mounting a blob from another repository
390410

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

720741
#### Error Codes
721742

0 commit comments

Comments
 (0)