Description:"Initiate a blob upload. This endpoint can be used to create resumable uploads or monolithic uploads.",
Methods:[]MethodDescriptor{
{
Method:"POST",
Description:"Initiate a resumable blob upload. If successful, an upload location will be provided to complete the upload. Optionally, if the `digest` parameter is present, the request body will be used to complete the upload in a single request.",
Requests:[]RequestDescriptor{
{
Name:"Initiate Monolithic Blob Upload",
Description:"Upload a blob identified by the `digest` parameter in single request. This upload will not be resumable unless a recoverable error is returned.",
Headers:[]ParameterDescriptor{
authHeader,
{
Name:"Content-Length",
Type:"integer",
Format:"<length of blob>",
},
},
PathParameters:[]ParameterDescriptor{
nameParameterDescriptor,
},
QueryParameters:[]ParameterDescriptor{
ParameterDescriptor{
Name:"digest",
Type:"query",
Format:"<tarsum>",
Regexp:digest.DigestRegexp,
Description:`Digest of uploaded blob. If present, the upload will be completed, in a single request, with contents of the request body as the resulting blob.`,
},
},
Body:BodyDescriptor{
ContentType:"application/octect-stream",
Format:"<binary data>",
},
Successes:[]ResponseDescriptor{
{
StatusCode:http.StatusCreated,
Headers:[]ParameterDescriptor{
{
Name:"Location",
Type:"url",
Format:"<blob location>",
},
contentLengthZeroHeader,
},
},
},
Failures:[]ResponseDescriptor{
{
Name:"Invalid Name or Digest",
StatusCode:http.StatusBadRequest,
ErrorCodes:[]ErrorCode{
ErrorCodeDigestInvalid,
ErrorCodeNameInvalid,
},
},
{
Name:"Unauthorized",
StatusCode:http.StatusUnauthorized,
Headers:[]ParameterDescriptor{
authChallengeHeader,
},
ErrorCodes:[]ErrorCode{
ErrorCodeDigestInvalid,
ErrorCodeNameInvalid,
},
},
},
},
{
Name:"Initiate Resumable Blob Upload",
Description:"Initiate a resumable blob upload with an empty request body.",
Headers:[]ParameterDescriptor{
authHeader,
contentLengthZeroHeader,
},
PathParameters:[]ParameterDescriptor{
nameParameterDescriptor,
},
Successes:[]ResponseDescriptor{
{
Description:"The upload has been created. The `Location` header must be used to complete the upload. The response should identical to a `GET` request on the contents of the returned `Location` header.",
StatusCode:http.StatusAccepted,
Headers:[]ParameterDescriptor{
contentLengthZeroHeader,
{
Name:"Location",
Type:"url",
Format:"/v2/<name>/blobs/uploads/<uuid>",
Description:"The location of the created upload. Clients should use the contents verbatim to complete the upload, adding parameters where required.",
},
{
Name:"Range",
Format:"0-0",
Description:"Range header indicating the progress of the upload. When starting an upload, it will return an empty range, since no content has been received.",
Description:"Interact with blob uploads. Clients should never assemble URLs for this endpoint and should only take it through the `Location` header on related API requests.",
Methods:[]MethodDescriptor{
{
Method:"GET",
Description:"Retrieve status of upload identified by `uuid`. The primary purpose of this endpoint is to resolve the current status of a resumable upload.",
Requests:[]RequestDescriptor{
{
Description:"Retrieve the progress of the current upload, as reported by the `Range` header.",
PathParameters:[]ParameterDescriptor{
nameParameterDescriptor,
uuidParameterDescriptor,
},
Successes:[]ResponseDescriptor{
{
StatusCode:http.StatusNoContent,
Headers:[]ParameterDescriptor{
{
Name:"Range",
Type:"header",
Format:"0-<offset>",
Description:"Range indicating the current progress of the upload.",
},
},
},
},
},
},
},
{
Method:"HEAD",
Description:"Retrieve status of upload identified by `uuid`. This is identical to the GET request.",
Requests:[]RequestDescriptor{
{
Description:"Retrieve the progress of the current upload, as reported by the `Range` header.",
PathParameters:[]ParameterDescriptor{
nameParameterDescriptor,
uuidParameterDescriptor,
},
Successes:[]ResponseDescriptor{
{
StatusCode:http.StatusNoContent,
Headers:[]ParameterDescriptor{
{
Name:"Range",
Type:"header",
Format:"0-<offset>",
Description:"Range indicating the current progress of the upload.",
},
},
},
},
},
},
},
{
Method:"PATCH",
Description:"Upload a chunk of data for the specified upload.",
Requests:[]RequestDescriptor{
{
Description:"Upload a chunk of data to specified upload without completing the upload.",
PathParameters:[]ParameterDescriptor{
nameParameterDescriptor,
uuidParameterDescriptor,
},
Headers:[]ParameterDescriptor{
{
Name:"Content-Range",
Type:"header",
Format:"<start of range>-<end of range, inclusive>",
Required:true,
Description:"Range of bytes identifying the desired block of content represented by the body. Start must the end offset retrieved via status check plus one. Note that this is a non-standard use of the `Content-Range` header.",
},
{
Name:"Content-Length",
Type:"integer",
Format:"<length of chunk>",
Description:"Length of the chunk being uploaded, corresponding the length of the request body.",
},
},
Body:BodyDescriptor{
ContentType:"application/octet-stream",
Format:"<binary chunk>",
},
Successes:[]ResponseDescriptor{
{
StatusCode:http.StatusNoContent,
Headers:[]ParameterDescriptor{
{
Name:"Range",
Type:"header",
Format:"0-<offset>",
Description:"Range indicating the current progress of the upload.",
},
contentLengthZeroHeader,
},
},
},
},
},
},
{
Method:"PUT",
Description:"Complete the upload specified by `uuid`, optionally appending the body as the final chunk.",
Requests:[]RequestDescriptor{
{
// TODO(stevvooe): Break this down into three separate requests:
// 1. Complete an upload where all data has already been sent.
// 2. Complete an upload where the entire body is in the PUT.
// 3. Complete an upload where the final, partial chunk is the body.
Description:"Upload the _final_ chunk of data.",
PathParameters:[]ParameterDescriptor{
nameParameterDescriptor,
uuidParameterDescriptor,
},
QueryParameters:[]ParameterDescriptor{
ParameterDescriptor{
Name:"digest",
Type:"string",
Format:"<tarsum>",
Regexp:digest.DigestRegexp,
Required:true,
Description:`Digest of uploaded blob.`,
},
},
Successes:[]ResponseDescriptor{
{
StatusCode:http.StatusNoContent,
Headers:[]ParameterDescriptor{
{
Name:"Content-Range",
Type:"header",
Format:"<start of range>-<end of range, inclusive>",
Description:"Range of bytes identifying the desired block of content represented by the body. Start must match the end of offset retrieved via status check. Note that this is a non-standard use of the `Content-Range` header.",
},
{
Name:"Content-Length",
Type:"integer",
Format:"<length of chunk>",
Description:"Length of the chunk being uploaded, corresponding the length of the request body.",
},
},
Body:BodyDescriptor{
ContentType:"application/octet-stream",
Format:"<binary chunk>",
},
},
},
},
},
},
{
Method:"DELETE",
Description:"Cancel outstanding upload processes, releasing associated resources. If this is not called, the unfinished uploads will eventually timeout.",
Requests:[]RequestDescriptor{
{
Description:"Cancel the upload specified by `uuid`.",