1
+ <?php
2
+
3
+ namespace OSS \Signer ;
4
+
5
+ use OSS \Core \OssUtil ;
6
+ use OSS \Http \RequestCore ;
7
+ use OSS \Credentials \Credentials ;
8
+
9
+ class SignerV1 implements SignerInterface
10
+ {
11
+ public function sign (RequestCore $ request , Credentials $ credentials , array &$ options )
12
+ {
13
+ // Date
14
+ if (!isset ($ request ->request_headers ['Date ' ])) {
15
+ $ request ->add_header ('Date ' , gmdate ('D, d M Y H:i:s \G\M\T ' ));
16
+ }
17
+ // Credentials information
18
+ if (strlen ($ credentials ->getSecurityToken ()) > 0 ) {
19
+ $ request ->add_header ("x-oss-security-token " , $ credentials ->getSecurityToken ());
20
+ }
21
+ $ headers = $ request ->request_headers ;
22
+ $ method = strtoupper ($ request ->method );
23
+ $ date = $ headers ['Date ' ];
24
+ $ resourcePath = $ this ->getResourcePath ($ options );
25
+ $ queryString = parse_url ($ request ->request_url , PHP_URL_QUERY );
26
+ $ query = array ();
27
+ parse_str ($ queryString , $ query );
28
+ $ stringToSign = $ this ->calcStringToSign ($ method , $ date , $ headers , $ resourcePath , $ query );
29
+ // printf("sign str:%s" . PHP_EOL, $stringToSign);
30
+ $ options ['string_to_sign ' ] = $ stringToSign ;
31
+ $ signature = base64_encode (hash_hmac ('sha1 ' , $ stringToSign , $ credentials ->getAccessKeySecret (), true ));
32
+ $ request ->add_header ('Authorization ' , 'OSS ' . $ credentials ->getAccessKeyId () . ': ' . $ signature );
33
+ }
34
+
35
+ public function presign (RequestCore $ request , Credentials $ credentials , array &$ options )
36
+ {
37
+ $ headers = $ request ->request_headers ;
38
+ // Date
39
+ $ expiration = $ options ['expiration ' ];
40
+ if (!isset ($ request ->request_headers ['Date ' ])) {
41
+ $ request ->add_header ('Date ' , gmdate ('D, d M Y H:i:s \G\M\T ' ));
42
+ }
43
+ $ parsed_url = parse_url ($ request ->request_url );
44
+ $ queryString = isset ($ parsed_url ['query ' ]) ? $ parsed_url ['query ' ] : '' ;
45
+ $ query = array ();
46
+ parse_str ($ queryString , $ query );
47
+ // Credentials information
48
+ if (strlen ($ credentials ->getSecurityToken ()) > 0 ) {
49
+ $ query ["security-token " ] = $ credentials ->getSecurityToken ();
50
+ }
51
+ $ method = strtoupper ($ request ->method );
52
+ $ date = $ expiration . "" ;
53
+ $ resourcePath = $ this ->getResourcePath ($ options );
54
+ $ stringToSign = $ this ->calcStringToSign ($ method , $ date , $ headers , $ resourcePath , $ query );
55
+ $ options ['string_to_sign ' ] = $ stringToSign ;
56
+ $ signature = base64_encode (hash_hmac ('sha1 ' , $ stringToSign , $ credentials ->getAccessKeySecret (), true ));
57
+ $ query ['OSSAccessKeyId ' ] = $ credentials ->getAccessKeyId ();
58
+ $ query ['Expires ' ] = $ date ;
59
+ $ query ['Signature ' ] = $ signature ;
60
+ $ queryString = OssUtil::toQueryString ($ query );
61
+ $ parsed_url ['query ' ] = $ queryString ;
62
+ $ request ->request_url = OssUtil::unparseUrl ($ parsed_url );
63
+ }
64
+
65
+ private function getResourcePath (array $ options )
66
+ {
67
+ $ resourcePath = '/ ' ;
68
+ if (strlen ($ options ['bucket ' ]) > 0 ) {
69
+ $ resourcePath .= $ options ['bucket ' ] . '/ ' ;
70
+ }
71
+ if (strlen ($ options ['key ' ]) > 0 ) {
72
+ $ resourcePath .= $ options ['key ' ];
73
+ }
74
+ return $ resourcePath ;
75
+ }
76
+
77
+ private function calcStringToSign ($ method , $ date , array $ headers , $ resourcePath , array $ query )
78
+ {
79
+ /*
80
+ SignToString =
81
+ VERB + "\n"
82
+ + Content-MD5 + "\n"
83
+ + Content-Type + "\n"
84
+ + Date + "\n"
85
+ + CanonicalizedOSSHeaders
86
+ + CanonicalizedResource
87
+ Signature = base64(hmac-sha1(AccessKeySecret, SignToString))
88
+ */
89
+ $ contentMd5 = '' ;
90
+ $ contentType = '' ;
91
+ // CanonicalizedOSSHeaders
92
+ $ signheaders = array ();
93
+ foreach ($ headers as $ key => $ value ) {
94
+ $ lowk = strtolower ($ key );
95
+ if (strncmp ($ lowk , "x-oss- " , 6 ) == 0 ) {
96
+ $ signheaders [$ lowk ] = $ value ;
97
+ } else if ($ lowk === 'content-md5 ' ) {
98
+ $ contentMd5 = $ value ;
99
+ } else if ($ lowk === 'content-type ' ) {
100
+ $ contentType = $ value ;
101
+ }
102
+ }
103
+ ksort ($ signheaders );
104
+ $ canonicalizedOSSHeaders = '' ;
105
+ foreach ($ signheaders as $ key => $ value ) {
106
+ $ canonicalizedOSSHeaders .= $ key . ': ' . $ value . "\n" ;
107
+ }
108
+ // CanonicalizedResource
109
+ $ signquery = array ();
110
+ foreach ($ query as $ key => $ value ) {
111
+ if (in_array ($ key , $ this ->signKeyList )) {
112
+ $ signquery [$ key ] = $ value ;
113
+ }
114
+ }
115
+ ksort ($ signquery );
116
+ $ sortedQueryList = array ();
117
+ foreach ($ signquery as $ key => $ value ) {
118
+ if (strlen ($ value ) > 0 ) {
119
+ $ sortedQueryList [] = $ key . '= ' . $ value ;
120
+ } else {
121
+ $ sortedQueryList [] = $ key ;
122
+ }
123
+ }
124
+ $ queryStringSorted = implode ('& ' , $ sortedQueryList );
125
+ $ canonicalizedResource = $ resourcePath ;
126
+ if (!empty ($ queryStringSorted )) {
127
+ $ canonicalizedResource .= '? ' . $ queryStringSorted ;
128
+ }
129
+ return $ method . "\n" . $ contentMd5 . "\n" . $ contentType . "\n" . $ date . "\n" . $ canonicalizedOSSHeaders . $ canonicalizedResource ;
130
+ }
131
+
132
+ private $ signKeyList = array (
133
+ "acl " , "uploads " , "location " , "cors " ,
134
+ "logging " , "website " , "referer " , "lifecycle " ,
135
+ "delete " , "append " , "tagging " , "objectMeta " ,
136
+ "uploadId " , "partNumber " , "security-token " , "x-oss-security-token " ,
137
+ "position " , "img " , "style " , "styleName " ,
138
+ "replication " , "replicationProgress " ,
139
+ "replicationLocation " , "cname " , "bucketInfo " ,
140
+ "comp " , "qos " , "live " , "status " , "vod " ,
141
+ "startTime " , "endTime " , "symlink " ,
142
+ "x-oss-process " , "response-content-type " , "x-oss-traffic-limit " ,
143
+ "response-content-language " , "response-expires " ,
144
+ "response-cache-control " , "response-content-disposition " ,
145
+ "response-content-encoding " , "udf " , "udfName " , "udfImage " ,
146
+ "udfId " , "udfImageDesc " , "udfApplication " ,
147
+ "udfApplicationLog " , "restore " , "callback " , "callback-var " , "qosInfo " ,
148
+ "policy " , "stat " , "encryption " , "versions " , "versioning " , "versionId " , "requestPayment " ,
149
+ "x-oss-request-payer " , "sequential " ,
150
+ "inventory " , "inventoryId " , "continuation-token " , "asyncFetch " ,
151
+ "worm " , "wormId " , "wormExtend " , "withHashContext " ,
152
+ "x-oss-enable-md5 " , "x-oss-enable-sha1 " , "x-oss-enable-sha256 " ,
153
+ "x-oss-hash-ctx " , "x-oss-md5-ctx " , "transferAcceleration " ,
154
+ "regionList " , "cloudboxes " , "x-oss-ac-source-ip " , "x-oss-ac-subnet-mask " , "x-oss-ac-vpc-id " , "x-oss-ac-forward-allow " ,
155
+ "metaQuery " , "resourceGroup " , "rtc " , "x-oss-async-process " , "responseHeader "
156
+ );
157
+ }
0 commit comments