示例#1
0
// downloadMeta downloads top-level metadata from remote storage and verifies
// it using the given file metadata.
func (c *Client) downloadMeta(name string, m data.FileMeta) ([]byte, error) {
	r, size, err := c.download(name, c.remote.GetMeta, m.Hashes)
	if err != nil {
		if IsNotFound(err) {
			return nil, ErrMissingRemoteMetadata{name}
		}
		return nil, err
	}
	defer r.Close()

	// return ErrWrongSize if the reported size is known and incorrect
	if size >= 0 && size != m.Length {
		return nil, ErrWrongSize{name, size, m.Length}
	}

	// wrap the data in a LimitReader so we download at most m.Length bytes
	stream := io.LimitReader(r, m.Length)

	// read the data, simultaneously writing it to buf and generating metadata
	var buf bytes.Buffer
	meta, err := util.GenerateFileMeta(io.TeeReader(stream, &buf), m.HashAlgorithms()...)
	if err != nil {
		return nil, err
	}
	if err := util.FileMetaEqual(meta, m); err != nil {
		return nil, ErrDownloadFailed{name, err}
	}
	return buf.Bytes(), nil
}
示例#2
0
// hasMeta checks whether local metadata has the given file meta
func (c *Client) hasMeta(name string, m data.FileMeta) bool {
	b, ok := c.localMeta[name]
	if !ok {
		return false
	}
	meta, err := util.GenerateFileMeta(bytes.NewReader(b), m.HashAlgorithms()...)
	if err != nil {
		return false
	}
	err = util.FileMetaEqual(meta, m)
	return err == nil
}