Skip to content

Commit

Permalink
config: Add enable_virtual_host_style, default false (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
aprilyang authored Mar 24, 2021
1 parent 19cd82b commit e80e281
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 15 deletions.
8 changes: 8 additions & 0 deletions src/__snapshots__/build.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,11 @@ Object {
"uri": "https://pek3a.qingstor.com/test_bucket/test_object.jpg?acl&upload_id=test_upload_id",
}
`;

exports[`parseVirtualHostRequestURI 1`] = `
Object {
"endpoint": "https://test_bucket.pek3a.qingstor.com",
"path": "/test_object.jpg?acl",
"uri": "https://test_bucket.pek3a.qingstor.com/test_object.jpg?acl&upload_id=test_upload_id",
}
`;
2 changes: 2 additions & 0 deletions src/__snapshots__/sign.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ exports[`getAuthorization 1`] = `"L6q5iKoyWbQky0T5/MYELz5jAFecGbvLDyjLdz6fClw="`

exports[`getCanonicalizedResource 1`] = `"/test_bucket/test_object.jpg?acl&upload_id=test_upload_id"`;

exports[`getCanonicalizedResource by virtual host 1`] = `"/test_bucket/test_object.jpg?acl&upload_id=test_upload_id"`;

exports[`getQuerySignature 1`] = `
Object {
"access_key_id": "test_key",
Expand Down
26 changes: 17 additions & 9 deletions src/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,32 +119,40 @@ class Builder {
}

parseRequestURI(operation) {
let path = operation.uri;
let endpoint = '';
let path = operation.uri;
const parsedProperties = this.parseRequestProperties(operation);

if (parsedProperties['zone']) {
endpoint = `${this.config.protocol}://${parsedProperties.zone}.${this.config.host}`;
endpoint = `${parsedProperties.zone}.${this.config.host}`;
} else {
endpoint = `${this.config.protocol}://${this.config.host}`;
endpoint = this.config.host;
}

if (this.config.enable_virtual_host_style) {
const bucketKey = 'bucket-name';
const prefix = `/<${bucketKey}>`;

if (path.startsWith(prefix) && parsedProperties[bucketKey]) {
path = path.slice(prefix.length);
endpoint = `${parsedProperties[bucketKey]}.${endpoint}`;
}
}

if (this.config.port) {
endpoint += `:${this.config.port}`;
}

endpoint = `${this.config.protocol}://${endpoint}`;

for (const key of Object.keys(parsedProperties)) {
path = path.replace(`<${key}>`, parsedProperties[key]);
}

const parsedParams = this.parseRequestParams(operation);
const parsedUri = buildUri(endpoint, path, parsedParams);
const uri = buildUri(endpoint, path, parsedParams);

return {
endpoint,
path,
uri: parsedUri,
};
return { endpoint, path, uri };
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/build.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,11 @@ test('parseRequestProperties', () => {
test('parseRequestURI', () => {
expect(builder.parseRequestURI(operation)).toMatchSnapshot();
});

test('parseVirtualHostRequestURI', () => {
process.env.QINGSTOR_ENABLE_VIRTUAL_HOST_STYLE = true;

const virtualHostBuilder = new Builder(new Config(), operation);

expect(virtualHostBuilder.parseRequestURI(operation)).toMatchSnapshot();
});
1 change: 1 addition & 0 deletions src/config/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const DEFAULT_CONFIG = {
connection_retries: 3,
// Valid levels are "debug", "info", "warn", "error", and "fatal"
log_level: 'warn',
enable_virtual_host_style: false,
};

class Config {
Expand Down
10 changes: 8 additions & 2 deletions src/config/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const defaultConfigFileContent = [
'port: 443',
'protocol: "https"',
'connection_retries: 3',
'enable_virtual_host_style: false',
'',
'# Additional User-Agent',
'additional_user_agent: ""',
Expand All @@ -41,6 +42,7 @@ const defaultConfigFile = '~/.qingstor/config.yaml';
const configPathEnvName = 'QINGSTOR_CONFIG_PATH';
const accessKeyIdEnvName = 'QINGSTOR_ACCESS_KEY_ID';
const secretAccessKeyEnvName = 'QINGSTOR_SECRET_ACCESS_KEY';
const enableVirtualHostEnvName = 'QINGSTOR_ENABLE_VIRTUAL_HOST_STYLE';

class Config {
constructor(options) {
Expand Down Expand Up @@ -111,14 +113,18 @@ class Config {
overrideConfigByENV() {
const config = {};

if (process.env[accessKeyIdEnvName]) {
if (accessKeyIdEnvName in process.env) {
config.access_key_id = process.env[accessKeyIdEnvName];
}

if (process.env[secretAccessKeyEnvName]) {
if (secretAccessKeyEnvName in process.env) {
config.secret_access_key = process.env[secretAccessKeyEnvName];
}

if (enableVirtualHostEnvName in process.env) {
config.enable_virtual_host_style = process.env[enableVirtualHostEnvName] === 'true';
}

return this.loadConfig(config);
}

Expand Down
7 changes: 6 additions & 1 deletion src/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ class Request {
});
}

this.operation = new Signer(this.config.access_key_id, this.config.secret_access_key).sign(this.operation);
this.operation = new Signer(
this.config.access_key_id,
this.config.secret_access_key,
this.config.enable_virtual_host_style,
).sign(this.operation);

return Promise.resolve(this);
}

Expand Down
16 changes: 14 additions & 2 deletions src/sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@
// +-------------------------------------------------------------------------

import logger from 'loglevel';
import urlParse from 'urlparse';
import hmacSHA256 from 'crypto-js/hmac-sha256';
import Base64 from 'crypto-js/enc-base64';
import { buildUri } from './utils';

class Signer {
constructor(access_key_id, secret_access_key) {
constructor(access_key_id, secret_access_key, enable_virtual_host_style) {
this.access_key_id = access_key_id;
this.secret_access_key = secret_access_key;
this.enable_virtual_host_style = enable_virtual_host_style;
}

getSignature(operation) {
Expand Down Expand Up @@ -128,8 +130,18 @@ class Signer {

getCanonicalizedResource() {
let canonicalizedResource = this.operation.path;
const parsedParams = this.operation.params || {};

if (this.enable_virtual_host_style) {
canonicalizedResource = canonicalizedResource || '/';

const { host } = urlParse(this.operation.endpoint);
const [bucket,] = host.split('.');

canonicalizedResource = `/${bucket}${canonicalizedResource}`;
}

const query = [];
const parsedParams = this.operation.params || {};
if (Object.keys(parsedParams).length !== 0) {
for (const i of Object.keys(parsedParams)) {
if (this.isSubResource(i)) {
Expand Down
13 changes: 13 additions & 0 deletions src/sign.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,19 @@ test('getCanonicalizedResource', () => {
expect(signer.getCanonicalizedResource()).toMatchSnapshot();
});

test('getCanonicalizedResource by virtual host', () => {
const _operation = {
...operation,
path: '/test_object.jpg?acl',
endpoint: 'https://test_bucket.pek3a.qingstor.com',
uri: 'https://test_bucket.pek3a.qingstor.com/test_object.jpg?acl&upload_id=test_upload_id',
};
const vHostSigner = new Signer('test_key', 'test_secret', true);

vHostSigner._setOperation(_operation);
expect(vHostSigner.getCanonicalizedResource()).toMatchSnapshot();
});

test('getAuthorization', () => {
signer._setOperation(operation);
expect(signer.getAuthorization()).toMatchSnapshot();
Expand Down
14 changes: 13 additions & 1 deletion test/build.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const userAgent = [
].join('');

describe('Builder test', function () {
const config = new Config('test_access_key', 'test_secret_key');
const config = new Config();
config.additional_user_agent = 'UserExample';
const operation = {
method: 'PUT',
Expand Down Expand Up @@ -95,6 +95,18 @@ describe('Builder test', function () {
});
});

it('parseVirtualHostRequestUri test', function() {
process.env.QINGSTOR_ENABLE_VIRTUAL_HOST_STYLE = true;
const _config = new Config();
const _test = new Builder(_config, operation);

_test.parseRequestURI(operation).should.eql({
endpoint: 'https://test_bucket.pek3a.qingstor.com',
path: '/test_object.jpg?acl',
uri: 'https://test_bucket.pek3a.qingstor.com/test_object.jpg?acl&upload_id=test_upload_id',
});
});

it('parse test', function () {
test.parse().should.eql({
method: 'PUT',
Expand Down
3 changes: 3 additions & 0 deletions test/config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe('Config test', function () {
config.protocol.should.equal('https');
config.connection_retries.should.equal(3);
config.log_level.should.equal('warn');
config.enable_virtual_host_style.should.equal(false);
});

it('getUserConfigFilePath test', function() {
Expand Down Expand Up @@ -66,11 +67,13 @@ describe('Config test', function () {
it('overrideConfigByENV test', function() {
process.env.QINGSTOR_ACCESS_KEY_ID = 'example_access_key_id';
process.env.QINGSTOR_SECRET_ACCESS_KEY = 'example_secret_access_key';
process.env.QINGSTOR_ENABLE_VIRTUAL_HOST_STYLE = true;

const test = new Config();

test.access_key_id.should.equal('example_access_key_id');
test.secret_access_key.should.equal('example_secret_access_key');
test.enable_virtual_host_style.should.equal(true);
});

it('overrideConfigByOptions with access key test', function () {
Expand Down

0 comments on commit e80e281

Please sign in to comment.