func()

in experimental/s3_storage.go [112:193]


func (f *s3Storage) List(path string, fn walkFunc) error {
	path = f.fullPath(path)
	if path != "/" && path[len(path)-1] != '/' {
		path = path + "/"
	}

	atomic.AddInt64(&f.apiCalls, 1)
	resp, err := f.S3.ListObjects(&s3.ListObjectsInput{
		Bucket:    aws.String(f.Bucket),
		Prefix:    aws.String(path),
		Delimiter: aws.String("/"),
		MaxKeys:   aws.Int64(listMax),
	})
	if err != nil {
		return err
	}

	for {
		for _, key := range resp.Contents {
			keyPath := *key.Key
			if strings.HasPrefix(keyPath, path) {
				keyPath = keyPath[len(path):]
			}

			if keyPath == "" {
				continue
			}

			fi := fileInfo{
				fullPath:     *key.Key,
				size:         *key.Size,
				etag:         *key.ETag,
				lastModified: *key.LastModified,
				directory:    strings.HasSuffix(*key.Key, "/"),
			}

			err = fn(keyPath, fi, err)
			if err != nil {
				return err
			}
		}

		for _, commonPrefix := range resp.CommonPrefixes {
			prefixPath := *commonPrefix.Prefix
			if strings.HasPrefix(prefixPath, path) {
				prefixPath = prefixPath[len(path):]
			}

			if prefixPath == "" {
				continue
			}

			fi := fileInfo{
				fullPath:  *commonPrefix.Prefix,
				directory: true,
			}

			err = fn(prefixPath, fi, err)
			if err != nil {
				return err
			}
		}

		if *resp.IsTruncated {
			atomic.AddInt64(&f.apiCalls, 1)
			resp, err = f.S3.ListObjects(&s3.ListObjectsInput{
				Bucket:    aws.String(f.Bucket),
				Prefix:    aws.String(path),
				MaxKeys:   aws.Int64(listMax),
				Delimiter: aws.String("/"),
				Marker:    resp.NextMarker,
			})
			if err != nil {
				return err
			}
		} else {
			break
		}
	}

	return nil
}