Created
April 7, 2017 06:54
-
-
Save Xuanwo/b8ba70b044ad23537958e9aa219aab09 to your computer and use it in GitHub Desktop.
put object with browser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<head> | |
<title>Upload</title> | |
</head> | |
<body> | |
<div class="container"> | |
<header class="navbar navbar-default" role="navigation"> | |
<div class="navbar-header"> | |
<a class="navbar-brand" href="/">Upload</a> | |
</div> | |
</header> | |
<div id="main"> | |
{{> uploader}} | |
</div> | |
</div> | |
</body> | |
<template name="uploader"> | |
<input type="file" id="files" name="files[]" multiple /> | |
<output id="list"></output> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import request from 'request'; | |
import {Config, QingStor} from 'qingstor-sdk'; | |
import async from 'async'; | |
const signatureServer = "http://127.0.0.1:9000"; | |
// Setup config. | |
const config = new Config().loadConfig({ | |
'host': 'qingstor.com', | |
'port': 443, | |
'protocol': 'https', | |
'log_level': 'debug', | |
}); | |
// Initialize bucket. | |
const qsService = new QingStor(config); | |
const bucket = qsService.Bucket('aspire-js-sdk', 'pek3a'); | |
Template.uploader.events({ | |
'change input[type="file"]' (event, template) { | |
let f = event.target.files[0]; // FileList object | |
// files is a FileList of File objects. List some properties. | |
let output = []; | |
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ', | |
f.size, ' bytes, last modified: ', | |
f.lastModifiedDate.toLocaleDateString(), '</li>'); | |
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>'; | |
let reader = new FileReader(); | |
reader.readAsBinaryString(f); | |
reader.onload = (function(theFile) { | |
return function(e) { | |
const putObjectRequest = bucket.putObjectRequest(theFile.name, {body: e.target.result}); | |
console.log(putObjectRequest.operation); | |
putObjectRequest.operation.headers['Content-Type'] = theFile.type || 'application/octet-stream'; | |
let string_to_sign = `PUT\n\n${theFile.type || 'application/octet-stream'}\n\n${putObjectRequest.operation.headers['X-QS-Date']}\n/aspire-js-sdk/${theFile.name}`; | |
// Sign request operation by Authorization header. | |
const body = JSON.stringify({string_to_sign}); | |
console.log('Sending request to signature server: ', body); | |
request({ | |
method: 'POST', | |
uri: `${signatureServer}/string-to-sign?header`, | |
headers: {'Content-Type': 'application/json'}, | |
body, | |
}, (error, response) => { | |
// Apply signature. | |
putObjectRequest.applySignature(JSON.parse(response.body).authorization); | |
// Send signed request. | |
putObjectRequest.send((error, response) => { | |
console.log('Finished put object request.'); | |
console.log(response.body); | |
}); | |
}); | |
}; | |
})(f); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// +------------------------------------------------------------------------- | |
// | Copyright (C) 2017 Yunify, Inc. | |
// +------------------------------------------------------------------------- | |
// | Licensed under the Apache License, Version 2.0 (the "License"); | |
// | you may not use this work except in compliance with the License. | |
// | You may obtain a copy of the License in the LICENSE file, or at: | |
// | | |
// | http://www.apache.org/licenses/LICENSE-2.0 | |
// | | |
// | Unless required by applicable law or agreed to in writing, software | |
// | distributed under the License is distributed on an "AS IS" BASIS, | |
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
// | See the License for the specific language governing permissions and | |
// | limitations under the License. | |
// +------------------------------------------------------------------------- | |
import _ from 'lodash'; | |
import cors from 'cors'; | |
import express from 'express'; | |
import body from 'body-parser'; | |
import {Config, Signer} from 'qingstor-sdk'; | |
import {createHmac} from 'crypto'; | |
const settings = { | |
access_key_id: 'key', | |
secret_access_key: 'secret', | |
log_level: "debug", | |
host: "127.0.0.1", | |
port: 9000 | |
}; | |
// Initialize server. | |
const server = express(); | |
server.disable('x-powered-by'); | |
server.disable('etag'); | |
server.use(cors({ | |
"origin": "http://127.0.0.1:3000", | |
"credentials": true | |
})); | |
server.use(body.urlencoded({extended: false})); | |
server.use(body.json()); | |
// Setup config. | |
const config = new Config().loadConfig({ | |
'access_key_id': settings.access_key_id, | |
'secret_access_key': settings.secret_access_key, | |
'log_level': settings.log_level, | |
}); | |
// Setup handlers. | |
const router = express.Router(); | |
// Sign operation. | |
router.post('/operation', (request, response) => { | |
const defaultOperation = { | |
method: 'GET', | |
uri: '', | |
body: '', | |
headers: {}, | |
params: {}, | |
}; | |
const operation = _.merge({}, defaultOperation, request.body); | |
const signer = new Signer( | |
operation, config.access_key_id, config.secret_access_key, | |
); | |
switch (request.query.channel) { | |
// Sign operation by query parameters. | |
// | |
// Request Example: | |
// | |
// POST /operation?channel=query HTTP/1.1 | |
// Content-Type: application/json; charset=utf-8 | |
// Host: 127.0.0.1:9000 | |
// Connection: close | |
// User-Agent: WTF/3.0.16 (Macintosh; OS X/10.12.3) GCDHTTPRequest | |
// Content-Length: 127 | |
// | |
// { | |
// "method": "GET", | |
// "uri": "https://pek3a.qingstor.com:443/aspire-test?prefix=test%2F", | |
// "body": "", | |
// "headers": { | |
// "Host": "pek3a.qingstor.com", | |
// "X-QS-Date": "Wed, 15 Mar 2017 09:44:38 GMT", | |
// "Content-Type": "application/octet-stream", | |
// "Content-Length": 0, | |
// "User-Agent": "qingstor-sdk-js/2.2.1 (Node.js v7.7.2; darwin x64)" | |
// }, | |
// "expires": 1489571836 | |
// } | |
// | |
// Response Example: | |
// | |
// HTTP/1.1 200 OK | |
// Content-Type: application/json; charset=utf-8 | |
// Content-Length: 147 | |
// Date: Wed, 15 Mar 2017 07:07:52 GMT | |
// Connection: close | |
// | |
// { | |
// "access_key_id": "OGFTIRSEHFOJPZQFYLZQ", | |
// "signature": "+2FHsEepCCbgMlamqU88ZUP6QZh2Vp7BxTASvAiZBlo=", | |
// "expires": 1489571836 | |
// } | |
case 'query': { | |
const params = signer.signQuery(operation.expires).params; | |
const data = { | |
'access_key_id': params.access_key_id, | |
'signature': params.signature, | |
'expires': params.expires, | |
}; | |
console.log('Sending response: ', JSON.stringify(data, null, 2)); | |
response.json(data); | |
break; | |
} | |
// Sign operation by Authorization header. | |
// | |
// Request Example: | |
// | |
// POST /operation?channel=header HTTP/1.1 | |
// Content-Type: application/json; charset=utf-8 | |
// Host: 127.0.0.1:9000 | |
// Connection: close | |
// User-Agent: WTF/3.0.16 (Macintosh; OS X/10.12.3) GCDHTTPRequest | |
// Content-Length: 327 | |
// | |
// { | |
// "method": "PUT", | |
// "uri": "https://pek3a.qingstor.com:443/aspire-test/test-file", | |
// "body": "Hello", | |
// "headers": { | |
// "Host": "pek3a.qingstor.com", | |
// "X-QS-Date": "Wed, 15 Mar 2017 08:57:16 GMT", | |
// "Content-Type": "", | |
// "Content-Length": 5, | |
// "User-Agent": "qingstor-sdk-js/2.2.1 (Node.js v7.7.2; darwin x64)" | |
// } | |
// } | |
// | |
// Response Example: | |
// | |
// HTTP/1.1 200 OK | |
// Content-Type: application/json; charset=utf-8 | |
// Content-Length: 92 | |
// Date: Wed, 15 Mar 2017 07:07:52 GMT | |
// Connection: close | |
// | |
// { | |
// "authorization": "QS GFTIRSEHJPZQFYLZQOFO:ed+84K2ZGigwF76eWm56aR2/MF5FkqMVJMr18FkBSoc=" | |
// } | |
case 'header': { | |
const data = { | |
'authorization': signer.sign().headers.Authorization, | |
}; | |
console.log('Sending response: ', JSON.stringify(data, null, 2)); | |
response.json(data); | |
break; | |
} | |
default: { | |
response.json({}); | |
} | |
} | |
}); | |
// Sign string to sign. | |
router.post('/string-to-sign', (request, response) => { | |
const signer = new Signer( | |
{}, config.access_key_id, config.secret_access_key, | |
); | |
const signature = signer.calculateSignature(request.body.string_to_sign); | |
switch (request.query.channel) { | |
// Sign operation by query parameters. | |
// | |
// Request Example: | |
// | |
// POST /operation?channel=query HTTP/1.1 | |
// Content-Type: application/json; charset=utf-8 | |
// Host: 127.0.0.1:9000 | |
// Connection: close | |
// User-Agent: WTF/3.0.16 (Macintosh; OS X/10.12.3) GCDHTTPRequest | |
// Content-Length: 127 | |
// | |
// { | |
// "string_to_sign": "GET\n\napplication/octet-stream\1489571836\n/aspire-test/test-file", | |
// "expires": 1489571836 | |
// } | |
// | |
// Response Example: | |
// | |
// HTTP/1.1 200 OK | |
// Content-Type: application/json; charset=utf-8 | |
// Content-Length: 147 | |
// Date: Wed, 15 Mar 2017 07:07:52 GMT | |
// Connection: close | |
// | |
// { | |
// "access_key_id": "OGFTIRSEHFOJPZQFYLZQ", | |
// "signature": "+gZYDVc91cxaqpSDj5tFmkL8VDv4+Ay25VQVrQTXsLg=", | |
// "expires": 1489571836 | |
// } | |
case 'query': { | |
const data = { | |
'access_key_id': config.access_key_id, | |
'expires': request.body.expires, | |
signature, | |
}; | |
console.log('Sending response: ', JSON.stringify(data, null, 2)); | |
response.json(data); | |
break; | |
} | |
// Sign operation by Authorization header. | |
// | |
// Request Example: | |
// | |
// POST /operation?channel=header HTTP/1.1 | |
// Content-Type: application/json; charset=utf-8 | |
// Host: 127.0.0.1:9000 | |
// Connection: close | |
// User-Agent: WTF/3.0.16 (Macintosh; OS X/10.12.3) GCDHTTPRequest | |
// Content-Length: 327 | |
// | |
// { | |
// "method": "PUT", | |
// "uri": "https://pek3a.qingstor.com:443/aspire-test/test-file", | |
// "body": "Hello", | |
// "headers": { | |
// "Host": "pek3a.qingstor.com", | |
// "X-QS-Date": "Wed, 15 Mar 2017 08:57:16 GMT", | |
// "Content-Type": "", | |
// "Content-Length": 5, | |
// "User-Agent": "qingstor-sdk-js/2.2.1 (Node.js v7.7.2; darwin x64)" | |
// } | |
// } | |
// | |
// Response Example: | |
// | |
// HTTP/1.1 200 OK | |
// Content-Type: application/json; charset=utf-8 | |
// Content-Length: 92 | |
// Date: Wed, 15 Mar 2017 07:07:52 GMT | |
// Connection: close | |
// | |
// { | |
// "authorization": "QS GFTIRJPZQFYLZQOSEHFO:8otBnH4VqE+v8J4TEHAPg9O95nJNQyK22SAWF7PfGhY=" | |
// } | |
case 'header': { | |
const data = { | |
'authorization': `QS ${config.access_key_id}:${signature}`, | |
}; | |
console.log('Sending response: ', JSON.stringify(data, null, 2)); | |
response.json(data); | |
break; | |
} | |
default: { | |
response.json({}); | |
} | |
} | |
}); | |
router.post('/post-upload', (request, response) => { | |
let key = request.body['file']; | |
let policy = new Buffer(JSON.stringify({key})).toString('base64'); | |
let h = createHmac('sha256', config.secret_access_key); | |
h.update(policy); | |
let signature = new Buffer(h.digest()).toString('base64'); | |
let data = { | |
"access_key_id": config.access_key_id, | |
"key": key, | |
"policy": policy, | |
"signature": signature | |
}; | |
response.json(data); | |
}); | |
// Apply router. | |
server.use('/', router); | |
// Run server. | |
server.listen(settings.port, settings.host, () => { | |
console.log(`Demo server running at: ${settings.host}:${settings.port}`) | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment