storj.io/uplink@v1.13.0/edge/share.go (about)

     1  // Copyright (C) 2021 Storj Labs, Inc.
     2  // See LICENSE for copying information.
     3  
     4  package edge
     5  
     6  import (
     7  	"net/url"
     8  	"strings"
     9  )
    10  
    11  // ShareURLOptions contains options how to present the data data exposed through Linksharing.
    12  type ShareURLOptions struct {
    13  	// If set it creates a link directly to the data instead of an to intermediate landing page.
    14  	// This URL can then be passed to a download command or embedded on a webpage.
    15  	Raw bool
    16  }
    17  
    18  // JoinShareURL creates a linksharing URL from parts. The existence or accessibility of the target
    19  // is not checked, it might not exist or be inaccessible.
    20  //
    21  // Example result is https://link.storjshare.io/s/l5pucy3dmvzxgs3fpfewix27l5pq/mybucket/myprefix/myobject
    22  //
    23  // The baseURL is the url of the linksharing service, e.g. https://link.storjshare.io. The accessKeyID
    24  // can be obtained by calling RegisterAccess. It must be associated with public visibility.
    25  // The bucket is optional, leave it blank to share the entire project. The object key is also optional,
    26  // if empty shares the entire bucket. It can also be a prefix, in which case it must end with a "/".
    27  func JoinShareURL(baseURL string, accessKeyID string, bucket string, key string, options *ShareURLOptions) (string, error) {
    28  	if accessKeyID == "" {
    29  		return "", uplinkError.New("accessKeyID is required")
    30  	}
    31  
    32  	if bucket == "" && key != "" {
    33  		return "", uplinkError.New("bucket is required if key is specified")
    34  	}
    35  
    36  	if options == nil {
    37  		options = &ShareURLOptions{}
    38  	}
    39  
    40  	if options.Raw {
    41  		if key == "" {
    42  			return "", uplinkError.New("key is required for a raw download link")
    43  		}
    44  		if key[len(key)-1:] == "/" {
    45  			// This is error can be removed if it is too limiting.
    46  			// Because the result could be used as a base for a known folder structure.
    47  			return "", uplinkError.New("a raw download link can not be a prefix")
    48  		}
    49  	}
    50  
    51  	result, err := url.ParseRequestURI(baseURL)
    52  	if err != nil {
    53  		return "", uplinkError.New("invalid base url: %q", baseURL)
    54  	}
    55  
    56  	result.Path = strings.Trim(result.Path, "/")
    57  	if options.Raw {
    58  		result.Path += "/raw/"
    59  	} else {
    60  		result.Path += "/s/"
    61  	}
    62  
    63  	result.Path += accessKeyID
    64  
    65  	if bucket != "" {
    66  		result.Path += "/" + bucket
    67  	}
    68  
    69  	if key != "" {
    70  		result.Path += "/" + key
    71  	}
    72  
    73  	return result.String(), nil
    74  }