Last active
April 27, 2017 13:50
-
-
Save mlc/10a156a7da996f3fa9938e464129ca55 to your computer and use it in GitHub Desktop.
javascript amazon lambda for https://oulipo.link/
This file contains hidden or 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
'use strict'; | |
const AWS = require('aws-sdk'); | |
const url = require('url'); | |
const bucket = process.env["OULIPO_BUCKET"]; | |
const region = process.env["OULIPO_REGION"]; | |
const prefix = process.env["OULIPO_PREFIX"]; | |
const cdn_prefix = process.env["OULIPO_CDN_PREFIX"]; | |
const chars = "abcdfghjijklmnopqrstuvWXYZABCDFGHIJKLMNOPQRSTUVWXYZ0123456789"; | |
const generate = () => | |
'xxxxxx'.replace(/x/g, (c) => chars[Math.random()*chars.length|0]); | |
exports.handler = (event, context, callback) => { | |
const s3 = new AWS.S3({ region: region }); | |
const url_long = event.url_long; | |
let retry = 0; | |
const done = (url_short, error) => { | |
if (error) { | |
callback(null, {error: error}) | |
} else { | |
callback(null, {url_long: url_long, url_short: url_short}); | |
} | |
} | |
const check_and_create_s3_redirect = (s3_bucket, id_short) => { | |
const key_short = prefix + "/" + id_short; | |
s3.headObject({ Bucket: bucket, Key: key_short }, (err, data) => { | |
if (err) { | |
// we should normally have a NotFound error showing that the id is not already in use | |
if (err.code === "NotFound") { | |
// normal execution path | |
s3.putObject({ Bucket: s3_bucket, Key: key_short, Body: "", WebsiteRedirectLocation: url_long, ContentType: "text/plain", CacheControl: "public, max-age=315576000" }, | |
(err, data) => { | |
if (err) { | |
done("", err.message); | |
} else { | |
const ret_url = "https://" + cdn_prefix + "/" + id_short; | |
console.log("Okay! short_url = " + ret_url); | |
done(ret_url, ""); | |
} | |
}); | |
} else { | |
// treat all other errors as fatal | |
done("", "Could not find an okay string: " + err.code); | |
} | |
} else { | |
// we found a duplicate, let's retry a limited number of times | |
retry += 1; | |
if (retry <= 3) { | |
check_and_create_s3_redirect(bucket, generate(), url_long); | |
} else { | |
// abort after 3 tries | |
done("", "Cannot find a good short id, aborting." ); | |
} | |
} | |
}); | |
} | |
if (event.cdn_prefix !== cdn_prefix) { | |
return done("", "Invalid CDN location"); | |
} | |
const url_check = url.parse(url_long); | |
if (!(url_check && url_check.host && ["https:", "http:"].indexOf(url_check.protocol) >= 0)) { | |
return done("", "Invalid URL format"); | |
} | |
console.log("shrinking " + url_long); | |
check_and_create_s3_redirect(bucket, generate(), url_long); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
using this doc as a basis, but with a handful of adaptations