BasicS3Uploader is a Javascript uploader that uploads files to an S3 bucket directly from the client side. It was designed to be very generic and easily customizable. You simply configure it, give it a file, and then tell it to start uploading.
-
Very configurable: There are many options you can specify when using the uploader. These include things like your ACL (Access Control List) or whether you'd like your uploads to be encrypted or not.
-
Parallel chunk uploads: Instead of uploading the entire file in a single request, this uploader sends the bits in chunks. Up to 5 chunks can be sent at the same time, which can result in much faster uploads.
-
Automatic retries: Should an upload fail in the process, this uploader will automatically attempt to retry the upload again, provided it hasn't exceeded the maximum number of retries.
-
Event driven: There are many events for you to hook into that allow you to do things like calculate upload progress or report upload failures/retries.
-
Extensible: The code was written to be easy to understand and modify, should you find the need for a feature that BasicS3Uploader does not currently provide.
BasicS3Uploader uses Amazon's REST API for multipart uploads. Specifically, it only requires these 4 APIs:
- Initiate Multipart Upload
- Upload Part
- List Parts
- Complete Multipart Upload
Each of these APIs require authorization. BasicS3Uploader uses AWS Signature Version 4 to authorize each request.
In order to generate signatures in a secure manner, a server-side application is required. For more information about how to generate signatures or how to use the uploader, check out the documentation section.
There are three requirements in order to get BasicS3Uploader working:
- A modern browser
- Proper CORS configuration for your S3 bucket
- A server-side application used for generating signatures
The following browsers have been known to work with this uploader:
- Firefox 13+
- Chrome 20+
- Safari 6+
- Internet Explorer 10+
BasicS3Uploader relies on the HTML5 File, Blob, and FileReader APIs. As a result, this uploader will not work in browsers that do not fully support them.
In order for BasicS3Uploader to upload to your S3 bucket, you must have the proper CORS config in place for that bucket. Below is a sample of what that configuration should look like.
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>[your domain]</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
<ExposeHeader>ETag</ExposeHeader>
</CORSRule>
</CORSConfiguration>
The only thing that should be modified is the <AllowedOrigin>
configuration. Everything
else should be the way you see it.
As previously stated, BasicS3Uploader needs to communicate with a server-side application in order to retrieve upload signatures. This application can be written in any language and use any framework.
Check out the sample app and documentation section for more info.
This project comes with a sample application that contains everything you need to start uploading. You will need to set up this application and make some minor configuration changes in order for it to work.
First, here is the list of files and description of each file used for the sample app:
- sample_app/
- app.rb: Simple Sinatra app that provides routes for both the front end and signature backend
- s3_upload_request.rb: A simple class used to generate headers
- Gemfile
- Gemfile.lock
- public/
- javascripts/
- dist/
- basic_s3_uploader.js: The uploader
- basic_s3_worker.js: A web worker file that helps speed up hashing file chunks
- main.js: An example of how one might use the uploader
- jquery-2.0.3.min.js: Not necessary for the uploader, but nice to use for main.js
- stylesheets/
- main.css
- views/
- layout.erb: The application layout
- index.erb: The index view
The sample app provided runs on Sinatra, a lightweight Rack application. In order to run the application, you must have Ruby installed.
cd basic_s3_uploader/sample_app
gem install bundler
bundle install
You need to modify the sample app by providing it with your AWS keys. This can
be accomplished by defining the AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
constants found in the s3_upload_request.rb
file.
Next, you will need to edit public/javascripts/main.js
and provide the uploader settings with
your bucket name, region, and a key for your upload (the key is going to be used for the
file name when it is uploaded, and may also include subfolders).
Example:
$("#fileinput").on("change", function(element) {
file = element.target.files[0];
settings = {
bucket: "your-bucket-name",
region: "us-east-1",
key: "a-key-for-the-upload",
...
Once you have the application set up and configured, you should be able to start it like so:
ruby app.rb
If you are running the app on your system ruby, you might need to prefix the command with
sudo
. This generally is not necessary unless you change the port to one that needs root
access. The sample ruby app is setup to use port 8080, which does not need root access.
Open a web browser and navigate to http://localhost:8080
Note: If you are using this URL, you'll need to add this domain as an allowed host for your bucket's CORS config. You can either add a specific entry for it or just use a wildcard:
<AllowedOrigin>*</AllowedOrigin>
Once the page loads, select a file using the file picker and click the "Upload it" button.
Want to help make this better? Please perform the following steps to contribute:
- Fork the project
- Create a new branch with your changes
- Be sure if adding/removing/changing logic to update the appropriate tests found in spec/
- Make sure all specs are passing. You can run them through grunt and karma:
*
npm install
*grunt
,grunt test
, or evengrunt watch
- Make sure you update the distributed copy by running the 'build' task
grunt build
(merges the src files together and copies it to dist/. Also copies the built file into the sample app).
- Use the sample app provided to "smoke test" your changes.
- Send me a pull request