diff --git a/bucket_domain.go b/bucket_domain.go new file mode 100644 index 0000000..87f78b6 --- /dev/null +++ b/bucket_domain.go @@ -0,0 +1,39 @@ +package cos + +import ( + "context" + "encoding/xml" + "net/http" +) + +type BucketPutDomainOptions struct { + XMLName xml.Name `xml:"DomainConfiguration"` + Status string `xml:"DomainRule>Status,omitempty"` + Name string `xml:"DomainRule>Name,omitempty"` + Type string `xml:"DomainRule>Type,omitempty"` + ForcedReplacement string `xml:"DomainRule>ForcedReplacement,omitempty"` +} +type BucketGetDomainResult BucketPutDomainOptions + +func (s *BucketService) PutDomain(ctx context.Context, opt *BucketPutDomainOptions) (*Response, error) { + sendOpt := &sendOptions{ + baseURL: s.client.BaseURL.BucketURL, + uri: "/?domain", + method: http.MethodPut, + body: opt, + } + resp, err := s.client.send(ctx, sendOpt) + return resp, err +} + +func (s *BucketService) GetDomain(ctx context.Context) (*BucketGetDomainResult, *Response, error) { + var res BucketGetDomainResult + sendOpt := &sendOptions{ + baseURL: s.client.BaseURL.BucketURL, + uri: "/?domain", + method: http.MethodGet, + result: &res, + } + resp, err := s.client.send(ctx, sendOpt) + return &res, resp, err +} diff --git a/bucket_domain_test.go b/bucket_domain_test.go new file mode 100644 index 0000000..896e68f --- /dev/null +++ b/bucket_domain_test.go @@ -0,0 +1,113 @@ +package cos + +import ( + "context" + "encoding/xml" + "fmt" + "net/http" + "reflect" + "testing" +) + +func TestBucketService_GetDomain(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + vs := values{ + "domain": "", + } + testFormValues(t, r, vs) + fmt.Fprint(w, ` + + ENABLED + www.abc.com + REST + CNAME + +`) + }) + + res, _, err := client.Bucket.GetDomain(context.Background()) + if err != nil { + t.Fatalf("Bucket.GetDomain returned error %v", err) + } + + want := &BucketGetDomainResult{ + XMLName: xml.Name{Local: "DomainConfiguration"}, + Status: "ENABLED", + Name: "www.abc.com", + Type: "REST", + ForcedReplacement: "CNAME", + } + + if !reflect.DeepEqual(res, want) { + t.Errorf("Bucket.GetDomain returned %+v, want %+v", res, want) + } +} + +func TestBucketService_PutDomain(t *testing.T) { + setup() + defer teardown() + + opt := &BucketPutDomainOptions{ + XMLName: xml.Name{Local: "DomainConfiguration"}, + Status: "ENABLED", + Name: "www.abc.com", + Type: "REST", + ForcedReplacement: "CNAME", + } + + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + vs := values{ + "domain": "", + } + testFormValues(t, r, vs) + + body := new(BucketPutDomainOptions) + xml.NewDecoder(r.Body).Decode(body) + want := opt + want.XMLName = xml.Name{Local: "DomainConfiguration"} + if !reflect.DeepEqual(body, want) { + t.Errorf("Bucket.PutDomain request\n body: %+v\n, want %+v\n", body, want) + } + }) + + _, err := client.Bucket.PutDomain(context.Background(), opt) + if err != nil { + t.Fatalf("Bucket.PutDomain returned error: %v", err) + } +} + +func TestBucketService_DeleteDomain(t *testing.T) { + setup() + defer teardown() + + opt := &BucketPutDomainOptions{} + + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodPut) + vs := values{ + "domain": "", + } + testFormValues(t, r, vs) + + body := new(BucketPutDomainOptions) + xml.NewDecoder(r.Body).Decode(body) + want := opt + want.XMLName = xml.Name{Local: "DomainConfiguration"} + if !reflect.DeepEqual(body, want) { + t.Errorf("Bucket.PutDomain request\n body: %+v\n, want %+v\n", body, want) + } + + w.WriteHeader(http.StatusNoContent) + }) + + _, err := client.Bucket.PutDomain(context.Background(), opt) + if err != nil { + t.Fatalf("Bucket.PutDomain returned error: %v", err) + } + +} diff --git a/bucket_website.go b/bucket_website.go new file mode 100644 index 0000000..3052bf1 --- /dev/null +++ b/bucket_website.go @@ -0,0 +1,59 @@ +package cos + +import ( + "context" + "encoding/xml" + "net/http" +) + +type WebsiteRoutingRule struct { + ConditionErrorCode string `xml:"Condition>HttpErrorCodeReturnedEquals,omitempty"` + ConditionPrefix string `xml:"Condition>KeyPrefixEquals,omitempty"` + + RedirectProtocol string `xml:"Redirect>Protocol,omitempty"` + RedirectReplaceKey string `xml:"Redirect>ReplaceKeyWith,omitempty"` + RedirectReplaceKeyPrefix string `xml:"Redirect>ReplaceKeyPrefixWith,omitempty"` +} + +type BucketPutWebsiteOptions struct { + XMLName xml.Name `xml:"WebsiteConfiguration"` + Index string `xml:"IndexDocument>Suffix"` + RedirectProtocol string `xml:"RedirectAllRequestsTo>Protocol,omitempty"` + Error string `xml:"ErrorDocument>Key,omitempty"` + Rules []WebsiteRoutingRule `xml:"RoutingRules>RoutingRule,omitempty"` +} + +type BucketGetWebsiteResult BucketPutWebsiteOptions + +func (s *BucketService) PutWebsite(ctx context.Context, opt *BucketPutWebsiteOptions) (*Response, error) { + sendOpt := &sendOptions{ + baseURL: s.client.BaseURL.BucketURL, + uri: "/?website", + method: http.MethodPut, + body: opt, + } + resp, err := s.client.send(ctx, sendOpt) + return resp, err +} + +func (s *BucketService) GetWebsite(ctx context.Context) (*BucketGetWebsiteResult, *Response, error) { + var res BucketGetWebsiteResult + sendOpt := &sendOptions{ + baseURL: s.client.BaseURL.BucketURL, + uri: "/?website", + method: http.MethodGet, + result: &res, + } + resp, err := s.client.send(ctx, sendOpt) + return &res, resp, err +} + +func (s *BucketService) DeleteWebsite(ctx context.Context) (*Response, error) { + sendOpt := &sendOptions{ + baseURL: s.client.BaseURL.BucketURL, + uri: "/?website", + method: http.MethodDelete, + } + resp, err := s.client.send(ctx, sendOpt) + return resp, err +} diff --git a/bucket_website_test.go b/bucket_website_test.go new file mode 100644 index 0000000..c59bcc8 --- /dev/null +++ b/bucket_website_test.go @@ -0,0 +1,166 @@ +package cos + +import ( + "context" + "encoding/xml" + "fmt" + "net/http" + "reflect" + "testing" +) + +func TestBucketService_GetWebsite(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + vs := values{ + "website": "", + } + testFormValues(t, r, vs) + fmt.Fprint(w, ` + + index.html + + + https + + + Error.html + + + + + 404 + + + https + 404.html + + + + + docs/ + + + https + documents/ + + + + + img/ + + + https + demo.jpg + + + +`) + }) + + res, _, err := client.Bucket.GetWebsite(context.Background()) + if err != nil { + t.Fatalf("Bucket.GetWebsite returned error %v", err) + } + + want := &BucketGetWebsiteResult{ + XMLName: xml.Name{Local: "WebsiteConfiguration"}, + Index: "index.html", + RedirectProtocol: "https", + Error: "Error.html", + Rules: []WebsiteRoutingRule{ + { + ConditionErrorCode: "404", + RedirectProtocol: "https", + RedirectReplaceKey: "404.html", + }, + { + ConditionPrefix: "docs/", + RedirectProtocol: "https", + RedirectReplaceKeyPrefix: "documents/", + }, + { + ConditionPrefix: "img/", + RedirectProtocol: "https", + RedirectReplaceKey: "demo.jpg", + }, + }, + } + + if !reflect.DeepEqual(res, want) { + t.Errorf("Bucket.GetWebsite returned %+v, want %+v", res, want) + } +} + +func TestBucketService_PutWebsite(t *testing.T) { + setup() + defer teardown() + + opt := &BucketPutWebsiteOptions{ + Index: "index.html", + RedirectProtocol: "https", + Error: "Error.html", + Rules: []WebsiteRoutingRule{ + { + ConditionErrorCode: "404", + RedirectProtocol: "https", + RedirectReplaceKey: "404.html", + }, + { + ConditionPrefix: "docs/", + RedirectProtocol: "https", + RedirectReplaceKeyPrefix: "documents/", + }, + { + ConditionPrefix: "img/", + RedirectProtocol: "https", + RedirectReplaceKey: "demo.jpg", + }, + }, + } + + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + vs := values{ + "website": "", + } + testFormValues(t, r, vs) + + body := new(BucketPutWebsiteOptions) + xml.NewDecoder(r.Body).Decode(body) + want := opt + want.XMLName = xml.Name{Local: "WebsiteConfiguration"} + if !reflect.DeepEqual(body, want) { + t.Errorf("Bucket.PutWebsite request\n body: %+v\n, want %+v\n", body, want) + } + }) + + _, err := client.Bucket.PutWebsite(context.Background(), opt) + if err != nil { + t.Fatalf("Bucket.PutWebsite returned error: %v", err) + } +} + +func TestBucketService_DeleteWebsite(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodDelete) + vs := values{ + "website": "", + } + testFormValues(t, r, vs) + + w.WriteHeader(http.StatusNoContent) + }) + + _, err := client.Bucket.DeleteWebsite(context.Background()) + if err != nil { + t.Fatalf("Bucket.DeleteWebsite returned error: %v", err) + } + +} diff --git a/costesting/ci_test.go b/costesting/ci_test.go index ea2dc59..8e485ee 100644 --- a/costesting/ci_test.go +++ b/costesting/ci_test.go @@ -4,9 +4,6 @@ package cos import ( "context" "fmt" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" - "github.com/tencentyun/cos-go-sdk-v5" "io/ioutil" "math/rand" "net/http" @@ -15,6 +12,10 @@ import ( "strings" "testing" "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "github.com/tencentyun/cos-go-sdk-v5" ) // Define the suite, and absorb the built-in basic suite @@ -304,6 +305,39 @@ func (s *CosTestSuite) TestPutGetDeleteLifeCycle() { assert.Nil(s.T(), err, "DeleteBucketLifecycle Failed") } +func (s *CosTestSuite) TestPutGetDeleteWebsite() { + opt := &cos.BucketPutWebsiteOptions{ + Index: "index.html", + Error: "index_backup.html", + RedirectProtocol: "https", + Rules: []cos.WebsiteRoutingRule{ + { + ConditionErrorCode: "404", + RedirectProtocol: "https", + RedirectReplaceKey: "404.html", + }, + { + ConditionPrefix: "docs/", + RedirectProtocol: "https", + RedirectReplaceKeyPrefix: "documents/", + }, + }, + } + + _, err := s.Client.Bucket.PutWebsite(context.Background(), opt) + assert.Nil(s.T(), err, "PutBucketWebsite Failed") + + res, rsp, err := s.Client.Bucket.GetWebsite(context.Background()) + if err != nil && 404 != rsp.StatusCode { + assert.Nil(s.T(), err, "GetBucketWebsite Failed") + } + assert.Equal(s.T(), opt.Index, res.Index, "GetBucketWebsite Failed") + assert.Equal(s.T(), opt.Error, res.Error, "GetBucketWebsite Failed") + assert.Equal(s.T(), opt.RedirectProtocol, res.RedirectProtocol, "GetBucketWebsite Failed") + _, err = s.Client.Bucket.DeleteWebsite(context.Background()) + assert.Nil(s.T(), err, "DeleteBucketWebsite Failed") +} + func (s *CosTestSuite) TestListMultipartUploads() { // Create new upload name := "test_multipart" + time.Now().Format(time.RFC3339) diff --git a/example/bucket/delWebsite.go b/example/bucket/delWebsite.go new file mode 100644 index 0000000..4741490 --- /dev/null +++ b/example/bucket/delWebsite.go @@ -0,0 +1,35 @@ +package main + +import ( + "context" + "net/http" + "net/url" + "os" + + "github.com/tencentyun/cos-go-sdk-v5" + "github.com/tencentyun/cos-go-sdk-v5/debug" +) + +func main() { + u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") + b := &cos.BaseURL{ + BucketURL: u, + } + c := cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: os.Getenv("COS_SECRETID"), + SecretKey: os.Getenv("COS_SECRETKEY"), + Transport: &debug.DebugRequestTransport{ + RequestHeader: true, + RequestBody: true, + ResponseHeader: true, + ResponseBody: true, + }, + }, + }) + + _, err := c.Bucket.DeleteWebsite(context.Background()) + if err != nil { + panic(err) + } +} diff --git a/example/bucket/getDomain.go b/example/bucket/getDomain.go new file mode 100644 index 0000000..0de5e0d --- /dev/null +++ b/example/bucket/getDomain.go @@ -0,0 +1,35 @@ +package main + +import ( + "context" + "net/http" + "net/url" + "os" + + "github.com/tencentyun/cos-go-sdk-v5" + "github.com/tencentyun/cos-go-sdk-v5/debug" +) + +func main() { + u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") + b := &cos.BaseURL{ + BucketURL: u, + } + c := cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: os.Getenv("COS_SECRETID"), + SecretKey: os.Getenv("COS_SECRETKEY"), + Transport: &debug.DebugRequestTransport{ + RequestHeader: true, + RequestBody: true, + ResponseHeader: true, + ResponseBody: true, + }, + }, + }) + + _, _, err := c.Bucket.GetDomain(context.Background()) + if err != nil { + panic(err) + } +} diff --git a/example/bucket/getWebsite.go b/example/bucket/getWebsite.go new file mode 100644 index 0000000..78b82c4 --- /dev/null +++ b/example/bucket/getWebsite.go @@ -0,0 +1,35 @@ +package main + +import ( + "context" + "net/http" + "net/url" + "os" + + "github.com/tencentyun/cos-go-sdk-v5" + "github.com/tencentyun/cos-go-sdk-v5/debug" +) + +func main() { + u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") + b := &cos.BaseURL{ + BucketURL: u, + } + c := cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: os.Getenv("COS_SECRETID"), + SecretKey: os.Getenv("COS_SECRETKEY"), + Transport: &debug.DebugRequestTransport{ + RequestHeader: true, + RequestBody: true, + ResponseHeader: true, + ResponseBody: true, + }, + }, + }) + + _, _, err := c.Bucket.GetWebsite(context.Background()) + if err != nil { + panic(err) + } +} diff --git a/example/bucket/putDomain.go b/example/bucket/putDomain.go new file mode 100644 index 0000000..e14968b --- /dev/null +++ b/example/bucket/putDomain.go @@ -0,0 +1,42 @@ +package main + +import ( + "context" + "net/http" + "net/url" + "os" + + "github.com/tencentyun/cos-go-sdk-v5" + "github.com/tencentyun/cos-go-sdk-v5/debug" +) + +func main() { + u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") + b := &cos.BaseURL{ + BucketURL: u, + } + c := cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: os.Getenv("COS_SECRETID"), + SecretKey: os.Getenv("COS_SECRETKEY"), + Transport: &debug.DebugRequestTransport{ + RequestHeader: true, + RequestBody: true, + ResponseHeader: true, + ResponseBody: true, + }, + }, + }) + + opt := &cos.BucketPutDomainOptions{ + Status: "ENABLED", + Name: "www.abc.com", + Type: "REST", + ForcedReplacement: "CNAME", + } + + _, err := c.Bucket.PutDomain(context.Background(), opt) + if err != nil { + panic(err) + } +} diff --git a/example/bucket/putWebsite.go b/example/bucket/putWebsite.go new file mode 100644 index 0000000..c87fb23 --- /dev/null +++ b/example/bucket/putWebsite.go @@ -0,0 +1,53 @@ +package main + +import ( + "context" + "net/http" + "net/url" + "os" + + "github.com/tencentyun/cos-go-sdk-v5" + "github.com/tencentyun/cos-go-sdk-v5/debug" +) + +func main() { + u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") + b := &cos.BaseURL{ + BucketURL: u, + } + c := cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: os.Getenv("COS_SECRETID"), + SecretKey: os.Getenv("COS_SECRETKEY"), + Transport: &debug.DebugRequestTransport{ + RequestHeader: true, + RequestBody: true, + ResponseHeader: true, + ResponseBody: true, + }, + }, + }) + + opt := &cos.BucketPutWebsiteOptions{ + Index: "index.html", + Error: "index_backup.html", + RedirectProtocol: "https", + Rules: []cos.WebsiteRoutingRule{ + { + ConditionErrorCode: "404", + RedirectProtocol: "https", + RedirectReplaceKey: "404.html", + }, + { + ConditionPrefix: "docs/", + RedirectProtocol: "https", + RedirectReplaceKeyPrefix: "documents/", + }, + }, + } + + _, err := c.Bucket.PutWebsite(context.Background(), opt) + if err != nil { + panic(err) + } +}