Skip to content

Instantly share code, notes, and snippets.

@rambabusaravanan
Last active May 9, 2020 20:22
Show Gist options
  • Save rambabusaravanan/cbd50a9325e15b4d7b35c0630ea2a438 to your computer and use it in GitHub Desktop.
Save rambabusaravanan/cbd50a9325e15b4d7b35c0630ea2a438 to your computer and use it in GitHub Desktop.
get S3 Directory Index as JSON

Bucket Policy

Make sure the bucket have the public ListBucket permission

YourBucket >> Permissions >> Bucket Policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicListing",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::yourbucketname"
        }
    ]
}

Enable CORS

You can allow "*" or specific domain

YourBucket >> Permissions >> CORS configuration

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Configure Public Access

Enable / Disable required settings YourBucket >> Permissions >> Public access settings

// source: https://gist.github.com/chinchang/8106a82c56ad007e27b1#file-xmltojson-js
function xmlToJson(xml) {
if (typeof xml === 'string') {
parser = new DOMParser();
xml = parser.parseFromString(xml, 'text/xml');
}
// Create the return object
var obj = {};
if (xml.nodeType == 1) {
// element
// do attributes
if (xml.attributes.length > 0) {
obj['@attributes'] = {};
for (var j = 0; j < xml.attributes.length; j++) {
var attribute = xml.attributes.item(j);
obj['@attributes'][attribute.nodeName] = attribute.nodeValue;
}
}
} else if (xml.nodeType == 3) {
// text
obj = xml.nodeValue;
}
// do children
// If just one text node inside
if (xml.hasChildNodes() && xml.childNodes.length === 1 && xml.childNodes[0].nodeType === 3) {
obj = xml.childNodes[0].nodeValue;
} else if (xml.hasChildNodes()) {
for (var i = 0; i < xml.childNodes.length; i++) {
var item = xml.childNodes.item(i);
var nodeName = item.nodeName;
// camelCase
nodeName = nodeName.charAt(0).toLowerCase() + nodeName.slice(1);
if (typeof obj[nodeName] == 'undefined') {
obj[nodeName] = xmlToJson(item);
} else {
if (typeof obj[nodeName].push == 'undefined') {
var old = obj[nodeName];
obj[nodeName] = [];
obj[nodeName].push(old);
}
obj[nodeName].push(xmlToJson(item));
}
}
}
return obj;
}
function getIndexUrl(bucket, region, prefix) {
// http://yourbucketname.s3.amazonaws.com/?delimiter=/&prefix=downloads/' (only http)
// https://s3.ap-south-1.amazonaws.com/yourbucketname/?delimiter=/&prefix=downloads/
return 'https://s3.' + region + '.amazonaws.com/' + bucket + '/?delimiter=/&prefix=' + prefix;
}
function getIndexJson(xml) {
var json = xmlToJson(xml);
var list = [];
if (json.listBucketResult.commonPrefixes)
list = list.concat(json.listBucketResult.commonPrefixes);
if (json.listBucketResult.contents)
list = list.concat(json.listBucketResult.contents);
return list;
}
// /* description */
// getIndexUrl(bucket, region, prefix) - gives the url for directory index api call
// getIndexJson(xml) - accepts directory index xml data and gives required json
// [ { prefix }, { eTag, key, lastModified, size, storageClass } ]
// /* example usage */
// var bucket = 'yourbucketname';
// var region = 'ap-south-1';
// var prefix = 'downloads/'; // must have trailing slash or can be empty string
// fetch(getIndexUrl(bucket, region, prefix))
// .then(res => res.text())
// .then(getIndexJson)
// .then(j => console.log(j));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment