package main import ( "context" "flag" "io" "net/http" "net/url" "os" "reflect" "strconv" "time" "unsafe" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" "github.com/pkg/errors" _ "unsafe" ) type obsS3Options struct { Endpoint string Region string Secure bool // S3 secure } const maxURLExpiry = time.Duration(int64(^uint64(0) / 2)) var defaultObsS3Opts = obsS3Options{} func (opts *obsS3Options) Bind(fs *flag.FlagSet) (err error) { fs.StringVar(&opts.Endpoint, "obs-endpoint", os.Getenv("OBS_ENDPOINT"), "OBS S3 Host") fs.StringVar(&opts.Region, "obs-region", os.Getenv("OBS_REGION"), "OBS S3 Region") var vObsSecure = opts.Secure if sObsSecure := os.Getenv("OBS_SECURE"); sObsSecure != "" { var obsSecure bool if obsSecure, err = strconv.ParseBool(sObsSecure); err != nil { err = errors.Wrap(err, "obs secure") return } vObsSecure = obsSecure } fs.BoolVar(&opts.Secure, "obs-secure", vObsSecure, "OBS S3 secure transport") return } func newObsS3Client(opts obsS3Options) (*minio.Client, error) { client, err := minio.New(opts.Endpoint, &minio.Options{ Creds: credentials.NewEnvAWS(), BucketLookup: minio.BucketLookupAuto, // vhost / path Region: opts.Region, Secure: opts.Secure, }) if err != nil { return nil, err } setOverrideSignerType(client, credentials.SignatureV2) return client, nil } var ( offsetCredsProvider uintptr offsetOverrideSignerType uintptr ) func init() { vt := reflect.TypeOf(minio.Client{}) if field, ok := vt.FieldByName("credsProvider"); ok { offsetCredsProvider = field.Offset } else { panic("cannot find credsProvider field") } if field, ok := vt.FieldByName("overrideSignerType"); ok { offsetOverrideSignerType = field.Offset } else { panic("cannot find overrideSignerType field") } } func getCredsProvider(client *minio.Client) *credentials.Credentials { return *(**credentials.Credentials)(unsafe.Add(unsafe.Pointer(client), offsetCredsProvider)) } func setOverrideSignerType(client *minio.Client, signerType credentials.SignatureType) { ptr := (*credentials.SignatureType)(unsafe.Add(unsafe.Pointer(client), offsetOverrideSignerType)) *ptr = signerType } //go:linkname isVirtualHostStyleRequest github.com/minio/minio-go/v7.(*Client).isVirtualHostStyleRequest func isVirtualHostStyleRequest(client *minio.Client, url url.URL, bucketName string) bool //go:linkname makeTargetURL github.com/minio/minio-go/v7.(*Client).makeTargetURL func makeTargetURL(client *minio.Client, bucketName, objectName, bucketLocation string, isVirtualHostStyle bool, queryValues url.Values) (*url.URL, error) // requestMetadata - is container for all the values to make a request. type requestMetadata struct { // If set newRequest presigns the URL. presignURL bool // User supplied. bucketName string objectName string queryValues url.Values customHeader http.Header extraPresignHeader http.Header expires int64 // Generated by our internal code. bucketLocation string contentBody io.Reader contentLength int64 contentMD5Base64 string // carries base64 encoded md5sum contentSHA256Hex string // carries hex encoded sha256sum streamSha256 bool addCrc bool trailer http.Header // (http.Request).Trailer. Requires v4 signature. } //go:linkname newRequest github.com/minio/minio-go/v7.(*Client).newRequest func newRequest(client *minio.Client, ctx context.Context, method string, metadata requestMetadata) (req *http.Request, err error)