-
Notifications
You must be signed in to change notification settings - Fork 238
Adds koa route #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Adds koa route #80
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import Router from 'koa-router'; | ||
import uuid from 'node-uuid'; | ||
import AWS from 'aws-sdk'; | ||
|
||
const { S3_ACCESS_KEY, S3_SECRET_ACCESS_KEY, S3_ENDPOINT } = process.env; | ||
|
||
function checkTrailingSlash (path) { | ||
let newPath; | ||
|
||
if (path && path[path.length - 1] !== '/') { | ||
newPath = path + '/'; | ||
} | ||
|
||
return newPath; | ||
} | ||
|
||
export default function S3Router (options) { | ||
const S3_BUCKET = options.bucket; | ||
|
||
if (!S3_BUCKET) { | ||
throw new Error('S3_BUCKET is required.'); | ||
} | ||
|
||
const s3Options = {}; | ||
if (options.region) { | ||
s3Options.region = options.region; | ||
} | ||
if (options.signatureVersion) { | ||
s3Options.signatureVersion = options.signatureVersion; | ||
} | ||
if (options.endpoint) { | ||
s3Options.endpoint = options.endpoint; | ||
} | ||
|
||
const s3 = new AWS.S3({ | ||
...s3Options, | ||
accessKeyId: S3_ACCESS_KEY, | ||
secretAccessKey: S3_SECRET_ACCESS_KEY, | ||
endpoint: S3_ENDPOINT | ||
}); | ||
|
||
const router = new Router({ | ||
prefix: options.prefix || 's3' | ||
}); | ||
|
||
/** | ||
* Redirects image requests with a temporary signed URL, giving access | ||
* to GET an upload. | ||
*/ | ||
function * tempRedirect() { | ||
const self = this; | ||
|
||
const params = { | ||
Bucket: S3_BUCKET, | ||
Key: options.key | ||
}; | ||
|
||
s3.getSignedUrl('getObject', params, function (err, url) { | ||
self.redirect(url); | ||
}); | ||
} | ||
|
||
/** | ||
* Image specific route. | ||
*/ | ||
router.get(/\/img\/(.*)/, tempRedirect); | ||
|
||
/** | ||
* Other file type(s) route. | ||
*/ | ||
router.get(/\/uploads\/(.*)/, tempRedirect); | ||
|
||
/** | ||
* Returns an object with `signedUrl` and `publicUrl` properties that | ||
* give temporary access to PUT an object in an S3 bucket. | ||
*/ | ||
router.get('/sign', function * () { | ||
const self = this; | ||
const filename = uuid.v4() + '_' + this.query.objectName; | ||
const mimeType = this.query.contentType; | ||
|
||
// Set any custom headers | ||
if (options.headers) { | ||
this.set(options.headers); | ||
} | ||
|
||
const params = { | ||
Bucket: S3_BUCKET, | ||
Key: checkTrailingSlash(options.key) + filename, | ||
Expires: 60, | ||
ContentType: mimeType, | ||
ACL: options.ACL || 'private' | ||
}; | ||
|
||
s3.getSignedUrl('putObject', params, function (err, data) { | ||
if (err) { | ||
console.log(err); | ||
self.status = 500; | ||
self.body = 'Cannot create S3 signed URL'; | ||
} | ||
|
||
self.body = { | ||
signedUrl: data, | ||
publicUrl: '/s3/uploads/' + filename, | ||
filename | ||
}; | ||
}); | ||
}); | ||
|
||
return router.routes(); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At first glance, this file looks just the same as the bundled router, except for the unused generator annotations on the methods. Can you let me know what this file does differently to support koa, and why the existing router doesn't work? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At second glance, it is quite a bit different. You are using ES6/7 things here, which we didn't do in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe Koa requires ES6/7 because it uses generators, which are an ES6 feature. So anyone using Koa will be using that. However, I should probably remove the imports too be save because even some ES6/Koa people are not guaranteed to use that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im not familiar with koa, but notice we took out the
express
dependency in this file, and are just relying on people have it installed if they are using the bundled router. That keeps it so that people not usingexpress
(or in this casekoa
) don't have to download the dependency.Is koa a large library? Does it have a lot of dependencies? If so, we should probably remove it from this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Koa would need to be in the server.js (presumably) already to work. You'll do
No real way to not already have koa.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are using this router, the assumption would be that you already have a dependency on
koa
. But if you aren't using this router, you don't want thekoa
dependency, and you would get it if this line exists inpackage.json
. So we should delete this line from here I think. Make sense?