1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
//
// goamz - Go packages to interact with the Amazon Web Services.
//
// https://wiki.ubuntu.com/goamz
//
// Copyright (c) 2011 Memeo Inc.
//
// Written by Prudhvi Krishna Surapaneni <me@prudhvi.net>
// This package is in an experimental state, and does not currently
// follow conventions and style of the rest of goamz or common
// Go conventions. It must be polished before it's considered a
// first-class package in goamz.
package sns
// BUG(niemeyer): Package needs documentation.
import (
"encoding/xml"
"net/http"
"net/url"
"time"
"github.com/goamz/goamz/aws"
)
// The SNS type encapsulates operation with an SNS region.
type SNS struct {
aws.Auth
aws.Region
private byte // Reserve the right of using private data.
}
type AttributeEntry struct {
Key string `xml:"key"`
Value string `xml:"value"`
}
type ResponseMetadata struct {
RequestId string `xml:"ResponseMetadata>RequestId"`
BoxUsage float64 `xml:"ResponseMetadata>BoxUsage"`
}
func New(auth aws.Auth, region aws.Region) *SNS {
return &SNS{auth, region, 0}
}
func makeParams(action string) map[string]string {
params := make(map[string]string)
params["Action"] = action
return params
}
type Error struct {
StatusCode int
Code string
Message string
RequestId string
}
func (err *Error) Error() string {
return err.Message
}
type xmlErrors struct {
RequestId string
Errors []Error `xml:"Errors>Error"`
}
func (sns *SNS) query(params map[string]string, resp interface{}) error {
params["Timestamp"] = time.Now().UTC().Format(time.RFC3339)
u, err := url.Parse(sns.Region.SNSEndpoint)
if err != nil {
return err
}
sign(sns.Auth, "GET", "/", params, u.Host)
u.RawQuery = multimap(params).Encode()
r, err := http.Get(u.String())
if err != nil {
return err
}
defer r.Body.Close()
if r.StatusCode != 200 {
return buildError(r)
}
err = xml.NewDecoder(r.Body).Decode(resp)
return err
}
func buildError(r *http.Response) error {
errors := xmlErrors{}
xml.NewDecoder(r.Body).Decode(&errors)
var err Error
if len(errors.Errors) > 0 {
err = errors.Errors[0]
}
err.RequestId = errors.RequestId
err.StatusCode = r.StatusCode
if err.Message == "" {
err.Message = r.Status
}
return &err
}
func multimap(p map[string]string) url.Values {
q := make(url.Values, len(p))
for k, v := range p {
q[k] = []string{v}
}
return q
}
|