/[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 - (hide 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 dopry 1.1 <?php
2    
3     /**
4     * @file
5     * Amazon S3 storage driver for filesystem.
6 dopry 1.3.4.1 *
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 dopry 1.1 */
14    
15    
16     /**
17 dopry 1.3.4.1 * driver settings form. called by fileapi.module when creating a respository using this driver.
18 dopry 1.1 * @param $settings
19 dopry 1.3.4.1 * 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 dopry 1.1 */
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 dopry 1.3.4.1 '#description' => t('The URL must not contain a trailing slash.'),
41 dopry 1.1 '#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 dopry 1.3.4.1 $form['bucket'] = array(
57     '#type' => 'textfield',
58     '#title' => t('S3 Bucket'),
59     '#default_value' => $settings['bucket'],
60     );
61    
62 dopry 1.1 return $form;
63     }
64    
65     function fileapi_driver_s3_settings_form_validate() {
66 dopry 1.3.4.1 //@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 dopry 1.1 }
72    
73    
74     /**
75     * test if a path is a file.
76 dopry 1.3.4.1 *
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 dopry 1.1 * @param $path
82     * path to be tested
83 dopry 1.3.4.1 *
84 dopry 1.1 */
85     function fileapi_driver_s3_is_file($settings, $path) {
86 dopry 1.3.4.1 // request meta data for an object with the key $path.
87     $result = s3_request('HEAD', $path, $settings);
88    
89     //parse results for request...
90 dopry 1.1 }
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 dopry 1.3 // there are technically no directories, so we can safely do
107     // nothing here.
108     return TRUE;
109 dopry 1.1 }
110    
111 dopry 1.3
112 dopry 1.1 /**
113     * remove a directory using standard php functions
114     * @param $path
115     */
116    
117     function fileapi_driver_s3_rmdir($settings, $path) {
118 dopry 1.3 // there are technically no directories.
119     // so we can test is there is a file in the 'directory' and return false here.
120 dopry 1.1 }
121    
122    
123     /**
124     * remove a file using standard php functions
125     * @param $path
126     */
127     function fileapi_driver_s3_remove($settings, $path) {
128 dopry 1.3
129 dopry 1.1 }
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 dopry 1.3
138 dopry 1.1 }
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 dopry 1.3
147 dopry 1.1 }
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 dopry 1.3 s3_request('PUT', $path, $settings, array(), $body);
168     unlink($tmp);
169 dopry 1.1 }
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 dopry 1.3.4.1 $result = s3_request('GET', $settings['bucket'] .'?delimiter=/&key=$path', $settings);
181 dopry 1.1 }
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 dopry 1.3.4.1 $result = s3_request('GET', $path, $settings);
193     return $result;
194 dopry 1.1 }
195    
196     function fileapi_driver_s3_filewrite($settings, $path, $data) {
197 dopry 1.3 $headers = array('Content-Type' => 'text/plain');
198 dopry 1.3.4.1 $result = s3_request('PUT', $settings['bucket'] .'/'. $path, $settings, array(), $data);
199     return $result;
200 dopry 1.1 }
201    
202 dopry 1.3.4.1 function s3_request($method, $resource, $settings, $headers=array(), $amzheaders=array(), $body=NULL) {
203    
204     $url = $settings['s3 url'];
205 dopry 1.3
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 dopry 1.3.4.1 $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 dopry 1.3 $signature = hex2b64(s3_hmac_sha1($settings['awsSecret'], $auth_string));
217 dopry 1.3.4.1 print "auth_string:\n$auth_string\n";
218     print "signature: $signature\n";
219 dopry 1.3
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 dopry 1.3.4.1 return $result;
226     // drupal_set_message('<pre>'. print_r($result, TRUE) .'</pre>');
227     // @todo error handling.
228 dopry 1.3 }
229 dopry 1.1
230 dopry 1.3.4.1
231 dopry 1.1 /**
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 dopry 1.2
282 dopry 1.3.4.1 // 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 dopry 1.2

  ViewVC Help
Powered by ViewVC 1.1.2