Skip to content

Commit

Permalink
Fix issues with missing headers (#15)
Browse files Browse the repository at this point in the history
* disable compression, redo SetBody

Signed-off-by: Josh Dolitsky <393494+jdolitsky@users.noreply.github.com>

* add additional testing

Signed-off-by: Josh Dolitsky <393494+jdolitsky@users.noreply.github.com>

* test passing in verifying request body

Signed-off-by: Josh Dolitsky <393494+jdolitsky@users.noreply.github.com>

* update readme example

Signed-off-by: Josh Dolitsky <393494+jdolitsky@users.noreply.github.com>
  • Loading branch information
jdolitsky authored and pmengelbert committed Jan 13, 2020
1 parent 29eefd9 commit b6c5215
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 28 deletions.
35 changes: 14 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ import (
func main() {
// construct client pointing to your registry
client, err := reggie.NewClient("http://localhost:5000",
reggie.WithDefaultName("my/repo"),
reggie.WithDefaultName("myorg/myrepo"),
reggie.WithDebug(true))
if err != nil {
panic(err)
Expand All @@ -152,8 +152,8 @@ func main() {
blobDigest := godigest.FromBytes(blob).String()

// upload the first chunk
req = client.NewRequest(reggie.PATCH, resp.GetRelativeLocation())
req.SetHeader("Content-Type", "application/octet-stream").
req = client.NewRequest(reggie.PATCH, resp.GetRelativeLocation()).
SetHeader("Content-Type", "application/octet-stream").
SetHeader("Content-Length", fmt.Sprintf("%d", len(blobChunk1))).
SetHeader("Content-Range", blobChunk1Range).
SetBody(blobChunk1)
Expand All @@ -163,8 +163,8 @@ func main() {
}

// upload the final chunk and close the session
req = client.NewRequest(reggie.PUT, resp.GetRelativeLocation())
req.SetHeader("Content-Length", fmt.Sprintf("%d", len(blobChunk2))).
req = client.NewRequest(reggie.PUT, resp.GetRelativeLocation()).
SetHeader("Content-Length", fmt.Sprintf("%d", len(blobChunk2))).
SetHeader("Content-Range", blobChunk2Range).
SetHeader("Content-Type", "application/octet-stream").
SetQueryParam("digest", blobDigest).
Expand All @@ -184,21 +184,15 @@ func main() {
fmt.Printf("Blob content:\n%s\n", resp.String())

// upload the manifest (referencing the uploaded blob)
ref := "test"
ref := "mytag"
manifest := []byte(fmt.Sprintf(
`{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"digest": "%s",
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": %d
},
"layers": [],
"schemaVersion": 2
}`, blobDigest, len(blob)))
"{ \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\", \"config\": { \"digest\": \"%s\", "+
"\"mediaType\": \"application/vnd.oci.image.config.v1+json\","+" \"size\": %d }, \"layers\": [], "+
"\"schemaVersion\": 2 }",
blobDigest, len(blob)))
req = client.NewRequest(reggie.PUT, "/v2/<name>/manifests/<reference>",
reggie.WithReference(ref))
req.SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
reggie.WithReference(ref)).
SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
SetBody(manifest)
resp, err = client.Do(req)
if err != nil {
Expand All @@ -207,13 +201,12 @@ func main() {

// validate the uploaded manifest content
req = client.NewRequest(reggie.GET, "/v2/<name>/manifests/<reference>",
reggie.WithReference(ref))
req.SetHeader("Accept", "application/vnd.oci.image.manifest.v1+json")
reggie.WithReference(ref)).
SetHeader("Accept", "application/vnd.oci.image.manifest.v1+json")
resp, err = client.Do(req)
if err != nil {
panic(err)
}
fmt.Printf("Manifest content:\n%s\n", resp.String())
}

```
1 change: 1 addition & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,6 @@ func createTransport() *http.Transport {
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1,
DisableCompression: true,
}
}
47 changes: 47 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package reggie

import (
"bytes"
"encoding/base64"
"fmt"
"net/http"
Expand All @@ -9,6 +10,11 @@ import (
"testing"
)

var (
lastCapturedRequest *http.Request
lastCapturedRequestBodyStr string
)

func TestClient(t *testing.T) {
authTestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
expectedAuthHeader := "Basic " + base64.StdEncoding.EncodeToString([]byte("testuser:testpass"))
Expand All @@ -23,6 +29,11 @@ func TestClient(t *testing.T) {
defer authTestServer.Close()

registryTestServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
lastCapturedRequest = r
buf := new(bytes.Buffer)
buf.ReadFrom(lastCapturedRequest.Body)
lastCapturedRequestBodyStr = buf.String()

h := r.Header.Get("Authorization")
if h == "Bearer abc123" {
w.Header().Set("Location", "http://abc123location.io/v2/blobs/uploads/e361aeb8-3181-11ea-850d-2e728ce88125")
Expand Down Expand Up @@ -185,4 +196,40 @@ func TestClient(t *testing.T) {
t.Fatalf("Expected error with bad address")
}

// Make sure headers and body match after going through auth
req = client.NewRequest(PUT, "/a/b/c").
SetHeader("Content-Length", "3").
SetHeader("Content-Range", "0-2").
SetHeader("Content-Type", "application/octet-stream").
SetQueryParam("digest", "xyz").
SetBody([]byte("abc"))
_, err = client.Do(req)
if err != nil {
t.Fatalf("Errors executing request: %s", err)
}

// 5 headers expected: the ones we set plus "Authorization" and "User-Agent"
numHeaders := len(lastCapturedRequest.Header)
if numHeaders != 5 {
fmt.Println(lastCapturedRequest.Header)
t.Fatalf("Expected 5 headers total, instead got %d", numHeaders)
}

// Just to be safe, lets check each of the 5 headers are ones we expect
for _, h := range []string{
"Content-Length",
"Content-Range",
"Content-Type",
"Authorization",
"User-Agent",
} {
if lastCapturedRequest.Header.Get(h) == "" {
t.Fatalf("Missing header: %s", h)
}
}

// Check that the body did not get lost somewhere in the multi-layer transport
if lastCapturedRequestBodyStr != "abc" {
t.Fatalf("Expected body to be \"abc\" but instead got %s", lastCapturedRequestBodyStr)
}
}
15 changes: 8 additions & 7 deletions request.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package reggie

import (
"bytes"
"fmt"
"io/ioutil"
"regexp"

"gopkg.in/resty.v1"
Expand Down Expand Up @@ -53,11 +51,19 @@ func WithSessionID(id string) requestOption {
}
}

// SetBody wraps the resty SetBody and returns the request, allowing method chaining
func (req *Request) SetBody(body []byte) *Request {
req.Request.SetBody(body)
return req
}

// SetHeader wraps the resty SetHeader and returns the request, allowing method chaining
func (req *Request) SetHeader(header, content string) *Request {
req.Request.SetHeader(header, content)
return req
}

// SetQueryParam wraps the resty SetQueryParam and returns the request, allowing method chaining
func (req *Request) SetQueryParam(param, content string) *Request {
req.Request.SetQueryParam(param, content)
return req
Expand All @@ -79,11 +85,6 @@ func (req *Request) Execute(method, url string) (*Response, error) {
return resp, err
}

func (req *Request) SetBody(body []byte) *Request {
req.Request.SetBody(ioutil.NopCloser(bytes.NewReader(body)))
return req
}

func validateRequest(req *Request) error {
re := regexp.MustCompile("<name>|<reference>|<digest>|<session_id>|//{2,}")
matches := re.FindAllString(req.URL, -1)
Expand Down

0 comments on commit b6c5215

Please sign in to comment.