3
3
abstract class PhutilAWSFuture extends FutureProxy {
4
4
5
5
private $ future ;
6
- private $ awsAccessKey ;
7
- private $ awsPrivateKey ;
8
- private $ awsRegion ;
9
- private $ builtRequest ;
10
- private $ params ;
6
+ private $ accessKey ;
7
+ private $ secretKey ;
8
+ private $ region ;
9
+ private $ httpMethod = 'GET ' ;
10
+ private $ path = '/ ' ;
11
+ private $ params = array ();
12
+ private $ endpoint ;
11
13
12
14
abstract public function getServiceName ();
13
15
14
16
public function __construct () {
15
17
parent ::__construct (null );
16
18
}
17
19
18
- public function setAWSKeys ($ access , $ private ) {
19
- $ this ->awsAccessKey = $ access ;
20
- $ this ->awsPrivateKey = $ private ;
20
+ public function setAccessKey ($ access_key ) {
21
+ $ this ->accessKey = $ access_key ;
21
22
return $ this ;
22
23
}
23
24
24
- public function getAWSAccessKey () {
25
- return $ this ->awsAccessKey ;
25
+ public function getAccessKey () {
26
+ return $ this ->accessKey ;
26
27
}
27
28
28
- public function getAWSPrivateKey () {
29
- return $ this ->awsPrivateKey ;
29
+ public function setSecretKey (PhutilOpaqueEnvelope $ secret_key ) {
30
+ $ this ->secretKey = $ secret_key ;
31
+ return $ this ;
32
+ }
33
+
34
+ public function getSecretKey () {
35
+ return $ this ->secretKey ;
30
36
}
31
37
32
- public function getAWSRegion () {
33
- return $ this ->awsRegion ;
38
+ public function getRegion () {
39
+ return $ this ->region ;
34
40
}
35
41
36
- public function setAWSRegion ($ region ) {
37
- $ this ->awsRegion = $ region ;
42
+ public function setRegion ($ region ) {
43
+ $ this ->region = $ region ;
38
44
return $ this ;
39
45
}
40
46
41
- public function getHost ( ) {
42
- $ host = $ this -> getServiceName (). ' . ' . $ this -> awsRegion . ' .amazonaws.com ' ;
43
- return $ host ;
47
+ public function setEndpoint ( $ endpoint ) {
48
+ $ this -> endpoint = $ endpoint ;
49
+ return $ this ;
44
50
}
45
51
46
- public function setRawAWSQuery ($ action , array $ params = array ()) {
47
- $ this ->params = $ params ;
48
- $ this ->params ['Action ' ] = $ action ;
52
+ public function getEndpoint () {
53
+ return $ this ->endpoint ;
54
+ }
55
+
56
+ public function setHTTPMethod ($ method ) {
57
+ $ this ->httpMethod = $ method ;
49
58
return $ this ;
50
59
}
51
60
52
- protected function getProxiedFuture () {
53
- if (! $ this ->future ) {
54
- $ params = $ this -> params ;
61
+ public function getHTTPMethod () {
62
+ return $ this ->httpMethod ;
63
+ }
55
64
56
- if (!$ this ->params ) {
57
- throw new Exception (
58
- pht (
59
- 'You must %s! ' ,
60
- 'setRawAWSQuery() ' ));
61
- }
65
+ public function setPath ($ path ) {
66
+ $ this ->path = $ path ;
67
+ return $ this ;
68
+ }
62
69
63
- if (!$ this ->getAWSAccessKey ()) {
64
- throw new Exception (
65
- pht (
66
- 'You must %s! ' ,
67
- 'setAWSKeys() ' ));
68
- }
70
+ public function getPath () {
71
+ return $ this ->path ;
72
+ }
69
73
70
- $ params ['AWSAccessKeyId ' ] = $ this ->getAWSAccessKey ();
71
- $ params ['Version ' ] = '2013-10-15 ' ;
72
- $ params ['Timestamp ' ] = date ('c ' );
74
+ protected function getParameters () {
75
+ $ params = $ this ->params ;
76
+ return $ params ;
77
+ }
73
78
74
- $ params = $ this ->sign ($ params );
79
+ protected function getProxiedFuture () {
80
+ if (!$ this ->future ) {
81
+ $ params = $ this ->getParameters ();
82
+ $ method = $ this ->getHTTPMethod ();
83
+ $ host = $ this ->getEndpoint ();
84
+ $ path = $ this ->getPath ();
75
85
76
- $ uri = new PhutilURI ('http:// ' .$ this ->getHost ().'/ ' );
77
- $ uri ->setQueryParams ($ params );
86
+ $ uri = id (new PhutilURI ("https:// {$ host }/ " ))
87
+ ->setPath ($ path )
88
+ ->setQueryParams ($ params );
78
89
79
- $ this ->future = new HTTPFuture ($ uri );
90
+ $ future = id (new HTTPSFuture ($ uri ))
91
+ ->setMethod ($ method );
92
+
93
+ $ this ->signRequest ($ future );
94
+
95
+ $ this ->future = $ future ;
80
96
}
81
97
82
98
return $ this ->future ;
83
99
}
84
100
101
+ protected function signRequest (HTTPSFuture $ future ) {
102
+ $ access_key = $ this ->getAccessKey ();
103
+ $ secret_key = $ this ->getSecretKey ();
104
+
105
+ $ region = $ this ->getRegion ();
106
+
107
+ id (new PhutilAWSv4Signature ())
108
+ ->setRegion ($ region )
109
+ ->setService ($ this ->getServiceName ())
110
+ ->setAccessKey ($ access_key )
111
+ ->setSecretKey ($ secret_key )
112
+ ->signRequest ($ future );
113
+ }
114
+
85
115
protected function didReceiveResult ($ result ) {
86
116
list ($ status , $ body , $ headers ) = $ result ;
87
117
@@ -101,7 +131,8 @@ protected function didReceiveResult($result) {
101
131
);
102
132
if ($ xml ) {
103
133
$ params ['RequestID ' ] = $ xml ->RequestID [0 ];
104
- foreach ($ xml ->Errors [0 ] as $ error ) {
134
+ $ errors = array ($ xml ->Error );
135
+ foreach ($ errors as $ error ) {
105
136
$ params ['Errors ' ][] = array ($ error ->Code , $ error ->Message );
106
137
}
107
138
}
@@ -112,36 +143,4 @@ protected function didReceiveResult($result) {
112
143
return $ xml ;
113
144
}
114
145
115
- /**
116
- * http://bit.ly/wU0JFh
117
- */
118
- private function sign (array $ params ) {
119
-
120
- $ params ['SignatureMethod ' ] = 'HmacSHA256 ' ;
121
- $ params ['SignatureVersion ' ] = '2 ' ;
122
-
123
- ksort ($ params );
124
-
125
- $ pstr = array ();
126
- foreach ($ params as $ key => $ value ) {
127
- $ pstr [] = rawurlencode ($ key ).'= ' .rawurlencode ($ value );
128
- }
129
- $ pstr = implode ('& ' , $ pstr );
130
-
131
- $ sign = "GET " ."\n" .
132
- strtolower ($ this ->getHost ())."\n" .
133
- "/ " ."\n" .
134
- $ pstr ;
135
-
136
- $ hash = hash_hmac (
137
- 'sha256 ' ,
138
- $ sign ,
139
- $ this ->getAWSPrivateKey (),
140
- $ raw_ouput = true );
141
-
142
- $ params ['Signature ' ] = base64_encode ($ hash );
143
-
144
- return $ params ;
145
- }
146
-
147
146
}
0 commit comments