/[drupal]/contributions/modules/fileapi/drivers/s3.driver
ViewVC logotype

Contents of /contributions/modules/fileapi/drivers/s3.driver

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3.4.1 - (show annotations) (download)
Thu Jan 4 09:24:40 2007 UTC (2 years, 10 months ago) by dopry
Branch: DRUPAL-5
Changes since 1.3: +62 -13 lines
fixed a couple bugs in s3_request, merged bucket into resource since it is technically a part of the
resource and moved all the bucket stuff out of s3_request... not the fileapi_driver callbacks need to
concatenate bucket with path.
1 <?php
2
3 /**
4 * @file
5 * Amazon S3 storage driver for filesystem.
6 *
7 * We are treating S3 like a normal hierarchal filesystem. The bucket
8 * is predetermined by the mountpoint settings. Except for list buckets
9 * and put bucket functions.
10 *
11 * We use the keys with a delimiter of '/' to create our heirarchy.
12 *
13 */
14
15
16 /**
17 * driver settings form. called by fileapi.module when creating a respository using this driver.
18 * @param $settings
19 * settings array from database.
20 * @todo convert form to multistep to allow input of credentials, then bucket selection/creation.
21 * @todo add bucket access control policy settings
22 */
23
24 function fileapi_driver_s3_settings_form($settings = array()) {
25 //debug_msg($settings);
26 $form = array(
27 '#type' => 'fieldset',
28 '#title' => t('Amazon S3 storage driver settings'),
29 '#tree' => TRUE,
30 );
31
32 $form['driver'] = array(
33 '#type' => 'hidden',
34 '#value' => 's3',
35 );
36
37 $form['s3 url'] = array(
38 '#type' => 'textfield',
39 '#title' => t('Amazon S3 url'),
40 '#description' => t('The URL must not contain a trailing slash.'),
41 '#default_value' => strlen($settings['s3 url']) ? $settings['s3 url'] : 'http://s3.amazonaws.com',
42 );
43
44 $form['awsID'] = array(
45 '#type' => 'textfield',
46 '#title' => t('AWS Access Key ID'),
47 '#default_value' => $settings['awsID'],
48 );
49
50 $form['awsSecret'] = array(
51 '#type' => 'textfield',
52 '#title' => t('AWS Secret'),
53 '#default_value' => $settings['awsSecret'],
54 );
55
56 $form['bucket'] = array(
57 '#type' => 'textfield',
58 '#title' => t('S3 Bucket'),
59 '#default_value' => $settings['bucket'],
60 );
61
62 return $form;
63 }
64
65 function fileapi_driver_s3_settings_form_validate() {
66 //@todo test for trailing slash in 's3 url';
67 }
68
69 function fileapi_driver_s3_settings_form_submit() {
70 //@todo create bucket if it doesn't exist.
71 }
72
73
74 /**
75 * test if a path is a file.
76 *
77 * for S3 we are going to operate on an object if an object
78 * has the key we're requesting.
79 * see: S3 Developers Guide pg 67.
80 *
81 * @param $path
82 * path to be tested
83 *
84 */
85 function fileapi_driver_s3_is_file($settings, $path) {
86 // request meta data for an object with the key $path.
87 $result = s3_request('HEAD', $path, $settings);
88
89 //parse results for request...
90 }
91
92 /**
93 * test if a path is a directory.
94 * @param $path
95 * path to be tested
96 */
97 function fileapi_driver_s3_is_dir($settings, $path) {
98 }
99
100
101 /**
102 * create a directory using standard php functions
103 * @param $path
104 */
105 function fileapi_driver_s3_mkdir($settings, $path) {
106 // there are technically no directories, so we can safely do
107 // nothing here.
108 return TRUE;
109 }
110
111
112 /**
113 * remove a directory using standard php functions
114 * @param $path
115 */
116
117 function fileapi_driver_s3_rmdir($settings, $path) {
118 // there are technically no directories.
119 // so we can test is there is a file in the 'directory' and return false here.
120 }
121
122
123 /**
124 * remove a file using standard php functions
125 * @param $path
126 */
127 function fileapi_driver_s3_remove($settings, $path) {
128
129 }
130
131 /**
132 * copy a file using standard php functions
133 * @param $src
134 * @param $dst
135 */
136 function fileapi_driver_s3_copy($settings, $src, $dst) {
137
138 }
139
140 /**
141 * move a file using standard php functions
142 * @param $src
143 * @param $dst
144 */
145 function fileapi_driver_s3_move($settings, $src, $dst) {
146
147 }
148
149 /**
150 * check if a file exists using standard php functions
151 * @param $path
152 */
153 function fileapi_driver_s3_exists($settings, $path) {
154 }
155
156 /**
157 * touch a path and create a file there.
158 * @param $path
159 * path to be touched.
160 */
161 function fileapi_driver_s3_touch($settings, $path) {
162 $tmp = file_directory_tmp() .'/'. basename($path);
163 touch($tmp);
164 $headers = array();
165 $headers['Content-Type'] = 'text/plain';
166 $body = file_get_contents($tmp);
167 s3_request('PUT', $path, $settings, array(), $body);
168 unlink($tmp);
169 }
170
171
172 /**
173 * read the contents of a directory.
174 * @param $path
175 * directory to be read.
176 * @return array
177 * action results and array of directory contents.
178 */
179 function fileapi_driver_s3_readdir($settings, $path) {
180 $result = s3_request('GET', $settings['bucket'] .'?delimiter=/&key=$path', $settings);
181 }
182
183 /**
184 * read the contents of a file.
185 * @param $path
186 * path of file to be read.
187 *
188 * NOTE: we are not including offset and maxlen since it is only supported in php > 5.1.0
189 * and our support target is 4.3.0.
190 */
191 function fileapi_driver_s3_fileread($settings, $path) {
192 $result = s3_request('GET', $path, $settings);
193 return $result;
194 }
195
196 function fileapi_driver_s3_filewrite($settings, $path, $data) {
197 $headers = array('Content-Type' => 'text/plain');
198 $result = s3_request('PUT', $settings['bucket'] .'/'. $path, $settings, array(), $data);
199 return $result;
200 }
201
202 function s3_request($method, $resource, $settings, $headers=array(), $amzheaders=array(), $body=NULL) {
203
204 $url = $settings['s3 url'];
205
206 // Set date to proper format for S3.
207 $headers['Date'] = gmdate(DATE_RFC822);
208 $headers['Authorization'] = 'AWS '. $settings['awsID'] .':'. $signature;
209
210 // Build S3 authorization hash.
211 $auth_string = $method ."\n\n". $headers['Content-type'] ."\n" . $headers['Date'] ."\n";
212 if (count($amzheaders)) {
213 $auth_string .= implode("\n",$amzheaders) ."\n";
214 }
215 $auth_string .= '/'. $resource;
216 $signature = hex2b64(s3_hmac_sha1($settings['awsSecret'], $auth_string));
217 print "auth_string:\n$auth_string\n";
218 print "signature: $signature\n";
219
220 // Set date to proper format for S3.
221 $headers['Date'] = gmdate(DATE_RFC822);
222 $headers['Authorization'] = 'AWS '. $settings['awsID'] .':'. $signature;
223
224 $result = drupal_http_request($url .'/'. $resource, array_merge($headers, $amzheaders), $method, $body);
225 return $result;
226 // drupal_set_message('<pre>'. print_r($result, TRUE) .'</pre>');
227 // @todo error handling.
228 }
229
230
231 /**
232 * Generate an sha1 signed hash of a string.
233 * @param K
234 * key to be used for the signature.
235 * @param string
236 * string to be signed.
237 */
238 function s3_hmac_sha1($K, $string) {
239 // hash function
240 $h = 'sha1';
241 // byte length of blocks operated on by hash function.
242 $B = '64';
243 // byte length of hash function output.
244 // seems unused in the HMAC algorithm
245 $L = '20';
246 return s3_hmac($h, $B, $K, $string);
247 }
248
249 /**
250 * HMAC implementation for drupal as per
251 * http://www.ietf.org/rfc/rfc2104.txt
252 *
253 * @param $h
254 * hashing function can be any
255 * @param $B
256 * block length iterated over by hashing algorithm
257 * @param $K
258 * key to be used for signing.
259 * @param $string
260 * string to be signed.
261 */
262 function s3_hmac($h, $B, $K, $string) {
263 // Hash the key if it exceeds the blocklength.
264 if (strlen($K) > $B) {
265 // Pack that dirty string.
266 $K = pack('H*', $h($K));
267 }
268 // pad it with 0 bytes to block length
269 $K = str_pad($K, $B, chr(0x00));
270
271 // Setup inner and outer pads as per the RFC.
272 $ipad = str_repeat(chr(0x36), $B)^$K;
273 $opad = str_repeat(chr(0x5C), $B)^$K;
274
275 // Do inner concat XOR hashing. Pack that dirty string.
276 $string = pack('H*', $h($ipad.$string));
277
278 // return outer concat XOR hash
279 return $h($opad.$string);
280 }
281
282 // conversion.
283 function hex2b64($str)
284 {
285 $raw = '';
286 for ($i=0; $i < strlen($str); $i+=2)
287 {
288 $raw .= chr(hexdec(substr($str, $i, 2)));
289 }
290 return base64_encode($raw);
291 }
292

  ViewVC Help
Powered by ViewVC 1.1.2