123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- 'use strict';
- module.exports = exports;
- const url = require('url');
- const fs = require('fs');
- const path = require('path');
- module.exports.detect = function(opts, config) {
- const to = opts.hosted_path;
- const uri = url.parse(to);
- config.prefix = (!uri.pathname || uri.pathname === '/') ? '' : uri.pathname.replace('/', '');
- if (opts.bucket && opts.region) {
- config.bucket = opts.bucket;
- config.region = opts.region;
- config.endpoint = opts.host;
- config.s3ForcePathStyle = opts.s3ForcePathStyle;
- } else {
- const parts = uri.hostname.split('.s3');
- const bucket = parts[0];
- if (!bucket) {
- return;
- }
- if (!config.bucket) {
- config.bucket = bucket;
- }
- if (!config.region) {
- const region = parts[1].slice(1).split('.')[0];
- if (region === 'amazonaws') {
- config.region = 'us-east-1';
- } else {
- config.region = region;
- }
- }
- }
- };
- module.exports.get_s3 = function(config) {
- if (process.env.node_pre_gyp_mock_s3) {
- // here we're mocking. node_pre_gyp_mock_s3 is the scratch directory
- // for the mock code.
- const AWSMock = require('mock-aws-s3');
- const os = require('os');
- AWSMock.config.basePath = `${os.tmpdir()}/mock`;
- const s3 = AWSMock.S3();
- // wrapped callback maker. fs calls return code of ENOENT but AWS.S3 returns
- // NotFound.
- const wcb = (fn) => (err, ...args) => {
- if (err && err.code === 'ENOENT') {
- err.code = 'NotFound';
- }
- return fn(err, ...args);
- };
- return {
- listObjects(params, callback) {
- return s3.listObjects(params, wcb(callback));
- },
- headObject(params, callback) {
- return s3.headObject(params, wcb(callback));
- },
- deleteObject(params, callback) {
- return s3.deleteObject(params, wcb(callback));
- },
- putObject(params, callback) {
- return s3.putObject(params, wcb(callback));
- }
- };
- }
- // if not mocking then setup real s3.
- const AWS = require('aws-sdk');
- AWS.config.update(config);
- const s3 = new AWS.S3();
- // need to change if additional options need to be specified.
- return {
- listObjects(params, callback) {
- return s3.listObjects(params, callback);
- },
- headObject(params, callback) {
- return s3.headObject(params, callback);
- },
- deleteObject(params, callback) {
- return s3.deleteObject(params, callback);
- },
- putObject(params, callback) {
- return s3.putObject(params, callback);
- }
- };
- };
- //
- // function to get the mocking control function. if not mocking it returns a no-op.
- //
- // if mocking it sets up the mock http interceptors that use the mocked s3 file system
- // to fulfill reponses.
- module.exports.get_mockS3Http = function() {
- let mock_s3 = false;
- if (!process.env.node_pre_gyp_mock_s3) {
- return () => mock_s3;
- }
- const nock = require('nock');
- // the bucket used for testing, as addressed by https.
- const host = 'https://mapbox-node-pre-gyp-public-testing-bucket.s3.us-east-1.amazonaws.com';
- const mockDir = process.env.node_pre_gyp_mock_s3 + '/mapbox-node-pre-gyp-public-testing-bucket';
- // function to setup interceptors. they are "turned off" by setting mock_s3 to false.
- const mock_http = () => {
- // eslint-disable-next-line no-unused-vars
- function get(uri, requestBody) {
- const filepath = path.join(mockDir, uri.replace('%2B', '+'));
- try {
- fs.accessSync(filepath, fs.constants.R_OK);
- } catch (e) {
- return [404, 'not found\n'];
- }
- // the mock s3 functions just write to disk, so just read from it.
- return [200, fs.createReadStream(filepath)];
- }
- // eslint-disable-next-line no-unused-vars
- return nock(host)
- .persist()
- .get(() => mock_s3) // mock any uri for s3 when true
- .reply(get);
- };
- // setup interceptors. they check the mock_s3 flag to determine whether to intercept.
- mock_http(nock, host, mockDir);
- // function to turn matching all requests to s3 on/off.
- const mockS3Http = (action) => {
- const previous = mock_s3;
- if (action === 'off') {
- mock_s3 = false;
- } else if (action === 'on') {
- mock_s3 = true;
- } else if (action !== 'get') {
- throw new Error(`illegal action for setMockHttp ${action}`);
- }
- return previous;
- };
- // call mockS3Http with the argument
- // - 'on' - turn it on
- // - 'off' - turn it off (used by fetch.test.js so it doesn't interfere with redirects)
- // - 'get' - return true or false for 'on' or 'off'
- return mockS3Http;
- };
|