Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload file to Digital Ocean Spaces using Javascript

I am looking to use Digital Oceans spaces (which seems to have an identical API to S3), and would like to try it by uploading a sample file. I am having lots of difficulty. Here's what I've done so far

{'hi' : 'world'}

Is the contents of a file hiworld.json that I would like to upload. I understand that I need to create an aws v4 signature before I can make this request.

var aws4 = require('aws4') var request = require('request')

var opts = {'json': true,'body': "{'hi':'world'}",host: '${myspace}.nyc3.digitaloceanspaces.com', path: '/hiworld.json'}

aws4.sign(opts, {accessKeyId: '${SECRET}', secretAccessKey: '${SECRET}'})

Then I send the request

request.put(opts,function(error, response) {
    if(error) {
        console.log(error);
    }
    console.log(response.body);
});

However, when I check my Digital Ocean space, I see that my file was not created. I have noticed that if I changed my PUT to GET and try to access an existing file, I have no issues.

Here's what my headers look like

headers: { Host: '${myspace}.nyc3.digitaloceanspaces.com', 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 'Content-Length': 14, 'X-Amz-Date': '20171008T175325Z', Authorization: 'AWS4-HMAC-SHA256 Credential=${mykey}/20171008/us-east-1//aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date, Signature=475e691d4ddb81cca28eb0dcdc7c926359797d5e383e7bef70989656822accc0' }, method: 'POST' }

like image 323
user2202911 Avatar asked Mar 07 '23 20:03

user2202911


2 Answers

As an alternative, using aws-sdk:

// 1. Importing the SDK
import AWS from 'aws-sdk';

// 2. Configuring the S3 instance for Digital Ocean Spaces 
const spacesEndpoint = new AWS.Endpoint(
  `${REGION}.digitaloceanspaces.com`
);
const url = `https://${BUCKET}.${REGION}.digitaloceanspaces.com/${file.path}`;
const S3 = new AWS.S3({
  endpoint: spacesEndpoint,
  accessKeyId: ACCESS_KEY_ID,
  secretAccessKey: SECRET_ACCESS_KEY
});

// 3. Using .putObject() to make the PUT request, S3 signs the request
const params = { Body: file.stream, Bucket: BUCKET, Key: file.path };
S3.putObject(params)
  .on('build', request => {
    request.httpRequest.headers.Host = `https://${BUCKET}.${REGION}.digitaloceanspaces.com`;
    // Note: I am assigning the size to the file Stream manually
    request.httpRequest.headers['Content-Length'] = file.size;
    request.httpRequest.headers['Content-Type'] = file.mimetype;
    request.httpRequest.headers['x-amz-acl'] = 'public-read';
  })
  .send((err, data) => {
    if (err) logger(err, err.stack);
    else logger(JSON.stringify(data, '', 2));
  });
like image 163
Ria Carmin Avatar answered Mar 10 '23 11:03

Ria Carmin


var str = {
    'hi': 'world'
}

var c = JSON.stringify(str);

request(aws4.sign({
  'uri': 'https://${space}.nyc3.digitaloceanspaces.com/newworlds.json',
  'method': 'PUT',
  'path': '/newworlds.json',
  'headers': {
    "Cache-Control":"no-cache",
    "Content-Type":"application/x-www-form-urlencoded",
    "accept":"*/*",
    "host":"${space}.nyc3.digitaloceanspaces.com",
    "accept-encoding":"gzip, deflate",
    "content-length": c.length
  },
  body: c
},{accessKeyId: '${secret}', secretAccessKey: '${secret}'}),function(err,res){
    if(err) {
        console.log(err);
    } else {
        console.log(res);
    }
})

This gave me a successful PUT

like image 29
user2202911 Avatar answered Mar 10 '23 09:03

user2202911