diff --git a/app/handler/file.go b/app/handler/file.go index 0ecb302..778b18c 100644 --- a/app/handler/file.go +++ b/app/handler/file.go @@ -7,6 +7,8 @@ import ( "mstore/app/router" ) +const zeroContentLength = "0" + func (hand *Handler) FileExists(rctx *router.Context) { hand.logg.Debugf("Handle FileExists") @@ -25,7 +27,7 @@ func (hand *Handler) FileExists(rctx *router.Context) { rctx.SetHeader("X-Content-Type", res.ContentType) rctx.SetHeader("X-Content-Length", res.ContentLength) rctx.SetHeader("X-Content-Digest", res.ContentDigest) - rctx.SetHeader("Content-Length", "0") + rctx.SetHeader("Content-Length", zeroContentLength) rctx.SetStatus(code) } diff --git a/pkg/client/client.go b/pkg/client/client.go index 4779065..715ff96 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -81,16 +81,17 @@ func (cli *Client) FileExists(ctx context.Context, ref string) (bool, error) { return res, err } -func (cli *Client) GetFile(ctx context.Context, ref, filename string) error { +func (cli *Client) GetFile(ctx context.Context, ref, filename string) (int64, error) { var err error + var size int64 ref, err = convertFileLink(ref) if err != nil { - return err + return size, err } req, err := http.NewRequestWithContext(ctx, http.MethodGet, ref, nil) if err != nil { - return err + return size, err } transport := &http.Transport{ TLSClientConfig: &tls.Config{ @@ -102,29 +103,42 @@ func (cli *Client) GetFile(ctx context.Context, ref, filename string) error { } resp, err := client.Do(req) if err != nil { - return err + return size, err } defer resp.Body.Close() + contentLength := resp.Header.Get("Content-Length") + if contentLength == "" { + err = fmt.Errorf("Empty Content-Length received") + return size, err + } if resp.StatusCode != http.StatusOK { err := fmt.Errorf("Received wrong status code: %s", resp.Status) - return err + return size, err + } + declSize, err := strconv.ParseInt(contentLength, 10, 64) + if err != nil { + err = fmt.Errorf("Wrong Content-Length value: %v", err) + return size, err } - dirname := filepath.Dir(filename) err = os.MkdirAll(dirname, 0750) if err != nil { - return err + return size, err } file, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0640) if err != nil { - return err + return size, err } - _, err = io.Copy(file, resp.Body) + size, err = io.Copy(file, resp.Body) if err != nil { - return err + return size, err } - return err + if size != declSize { + err := fmt.Errorf("Mismatch Content-Length and recorded filesize") + return size, err + } + return size, err } func (cli *Client) PutFile(ctx context.Context, filename, ref string) error { diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index d3cc787..b808702 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -57,6 +57,7 @@ func TestService(t *testing.T) { time.Sleep(1 * time.Second) } { + // ServiceHello fmt.Printf("=== ServiceHello ===\n") cli := NewClient() ctx := context.Background() @@ -67,6 +68,7 @@ func TestService(t *testing.T) { require.True(t, helloRes) } { + // PutFile tmpdir := t.TempDir() tmpfile := filepath.Join(tmpdir, "foo.bin") @@ -86,4 +88,19 @@ func TestService(t *testing.T) { require.NoError(t, err) } + { + // GetFile + fmt.Printf("=== GetFil ===\n") + cli := NewClient() + ctx := context.Background() + ctx, _ = context.WithTimeout(ctx, 1*time.Second) + + tmpdir := t.TempDir() + tmpfile := filepath.Join(tmpdir, "foo.bin") + + _, err = cli.GetFile(ctx, srvaddr+"/foo.bin", tmpfile) + require.NoError(t, err) + + } + }