func TestTempUrl(t *testing.T) { err := c.ObjectPutBytes(CONTAINER, OBJECT, []byte(CONTENTS), "") if err != nil { t.Fatal(err) } m := swift.Metadata{} m["temp-url-key"] = SECRET_KEY err = c.AccountUpdate(m.AccountHeaders()) if err != nil { t.Fatal(err) } expiresTime := time.Now().Add(20 * time.Minute) tempUrl := c.ObjectTempUrl(CONTAINER, OBJECT, SECRET_KEY, "GET", expiresTime) resp, err := http.Get(tempUrl) if err != nil { t.Fatal("Failed to retrieve file from temporary url") } if resp.StatusCode == 401 { t.Log("Server doesn't support tempurl") } else if resp.StatusCode != 200 { t.Fatal("HTTP Error retrieving file from temporary url", resp.StatusCode) } else { if content, err := ioutil.ReadAll(resp.Body); err != nil || string(content) != CONTENTS { t.Error("Bad content", err) } } resp.Body.Close() err = c.ObjectDelete(CONTAINER, OBJECT) if err != nil { t.Fatal(err) } }
// New constructs a new Driver with the given Openstack Swift credentials and container name func New(params Parameters) (*Driver, error) { transport := &http.Transport{ Proxy: http.ProxyFromEnvironment, MaxIdleConnsPerHost: 2048, TLSClientConfig: &tls.Config{InsecureSkipVerify: params.InsecureSkipVerify}, } ct := swift.Connection{ UserName: params.Username, ApiKey: params.Password, AuthUrl: params.AuthURL, Region: params.Region, UserAgent: "distribution/" + version.Version, Tenant: params.Tenant, TenantId: params.TenantID, Domain: params.Domain, DomainId: params.DomainID, TrustId: params.TrustID, Transport: transport, ConnectTimeout: 60 * time.Second, Timeout: 15 * 60 * time.Second, } err := ct.Authenticate() if err != nil { return nil, fmt.Errorf("Swift authentication failed: %s", err) } if _, _, err := ct.Container(params.Container); err == swift.ContainerNotFound { if err := ct.ContainerCreate(params.Container, nil); err != nil { return nil, fmt.Errorf("Failed to create container %s (%s)", params.Container, err) } } else if err != nil { return nil, fmt.Errorf("Failed to retrieve info about container %s (%s)", params.Container, err) } d := &driver{ Conn: ct, Container: params.Container, Prefix: params.Prefix, ChunkSize: params.ChunkSize, TempURLMethods: make([]string, 0), AccessKey: params.AccessKey, } info := swiftInfo{} if config, err := d.Conn.QueryInfo(); err == nil { _, d.BulkDeleteSupport = config["bulk_delete"] if err := mapstructure.Decode(config, &info); err == nil { d.TempURLContainerKey = info.Swift.Version >= "2.3.0" d.TempURLMethods = info.Tempurl.Methods } } else { d.TempURLContainerKey = params.TempURLContainerKey d.TempURLMethods = params.TempURLMethods } if len(d.TempURLMethods) > 0 { secretKey := params.SecretKey if secretKey == "" { secretKey, _ = generateSecret() } // Since Swift 2.2.2, we can now set secret keys on containers // in addition to the account secret keys. Use them in preference. if d.TempURLContainerKey { _, containerHeaders, err := d.Conn.Container(d.Container) if err != nil { return nil, fmt.Errorf("Failed to fetch container info %s (%s)", d.Container, err) } d.SecretKey = containerHeaders["X-Container-Meta-Temp-Url-Key"] if d.SecretKey == "" || (params.SecretKey != "" && d.SecretKey != params.SecretKey) { m := swift.Metadata{} m["temp-url-key"] = secretKey if d.Conn.ContainerUpdate(d.Container, m.ContainerHeaders()); err == nil { d.SecretKey = secretKey } } } else { // Use the account secret key _, accountHeaders, err := d.Conn.Account() if err != nil { return nil, fmt.Errorf("Failed to fetch account info (%s)", err) } d.SecretKey = accountHeaders["X-Account-Meta-Temp-Url-Key"] if d.SecretKey == "" || (params.SecretKey != "" && d.SecretKey != params.SecretKey) { m := swift.Metadata{} m["temp-url-key"] = secretKey if err := d.Conn.AccountUpdate(m.AccountHeaders()); err == nil { d.SecretKey = secretKey } } } } return &Driver{ baseEmbed: baseEmbed{ Base: base.Base{ StorageDriver: d, }, }, }, nil }