Compare commits
4 Commits
developmen
...
refactor/r
Author | SHA1 | Date |
---|---|---|
Bennett Buchanan | 1ab37bb05c | |
Bennett Buchanan | dc6b9c712f | |
Bennett Buchanan | 822ae24ed2 | |
Bennett Buchanan | 8b5dcf2d7c |
|
@ -0,0 +1,74 @@
|
||||||
|
const { responseNoBody, parseContentMD5, responseXMLBody } =
|
||||||
|
require('../routesUtils');
|
||||||
|
const errors = require('../../errors');
|
||||||
|
|
||||||
|
class AuthController {
|
||||||
|
static bucketPut(req, res, log) {
|
||||||
|
// content-length for object is handled separately below
|
||||||
|
const contentLength = req.headers['content-length'];
|
||||||
|
if ((contentLength && (isNaN(contentLength) || contentLength < 0)) ||
|
||||||
|
contentLength === '') {
|
||||||
|
log.debug('invalid content-length header');
|
||||||
|
return responseNoBody(errors.BadRequest, null, res, null, log);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eslint-disable no-param-reassign */
|
||||||
|
static objectPutAction(req, res, log) {
|
||||||
|
// PUT object, PUT object ACL, PUT object multipart or
|
||||||
|
// PUT object copy
|
||||||
|
// if content-md5 is not present in the headers, try to
|
||||||
|
// parse content-md5 from meta headers
|
||||||
|
|
||||||
|
if (req.headers['content-md5'] === '') {
|
||||||
|
log.debug('empty content-md5 header', {
|
||||||
|
method: 'routePUT',
|
||||||
|
});
|
||||||
|
return responseNoBody(errors.InvalidDigest, null, res, 200, log);
|
||||||
|
}
|
||||||
|
if (req.headers['content-md5']) {
|
||||||
|
req.contentMD5 = req.headers['content-md5'];
|
||||||
|
} else {
|
||||||
|
req.contentMD5 = parseContentMD5(req.headers);
|
||||||
|
}
|
||||||
|
if (req.contentMD5 && req.contentMD5.length !== 32) {
|
||||||
|
req.contentMD5 = Buffer.from(req.contentMD5, 'base64')
|
||||||
|
.toString('hex');
|
||||||
|
if (req.contentMD5 && req.contentMD5.length !== 32) {
|
||||||
|
log.debug('invalid md5 digest', { contentMD5: req.contentMD5 });
|
||||||
|
return responseNoBody(errors.InvalidDigest, null, res, 200,
|
||||||
|
log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const encryptionHeaders = [
|
||||||
|
'x-amz-server-side-encryption',
|
||||||
|
'x-amz-server-side-encryption-customer-algorithm',
|
||||||
|
'x-amz-server-side-encryption-aws-kms-key-id',
|
||||||
|
'x-amz-server-side-encryption-context',
|
||||||
|
'x-amz-server-side-encryption-customer-key',
|
||||||
|
'x-amz-server-side-encryption-customer-key-md5',
|
||||||
|
];
|
||||||
|
// object level encryption
|
||||||
|
if (encryptionHeaders.some(i => req.headers[i] !== undefined)) {
|
||||||
|
return responseXMLBody(errors.NotImplemented, null, res, log);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
static objectPut(req, res, log) {
|
||||||
|
if (req.headers['content-length'] === undefined &&
|
||||||
|
req.headers['x-amz-decoded-content-length'] === undefined) {
|
||||||
|
return responseNoBody(errors.MissingContentLength, null, res, 411,
|
||||||
|
log);
|
||||||
|
}
|
||||||
|
if (Number.isNaN(req.parsedContentLength) ||
|
||||||
|
req.parsedContentLength < 0) {
|
||||||
|
return responseNoBody(errors.BadRequest, null, res, 400, log);
|
||||||
|
}
|
||||||
|
log.end().addDefaultFields({ contentLength: req.parsedContentLength });
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = AuthController;
|
|
@ -0,0 +1,50 @@
|
||||||
|
const { statsReport500, responseNoBody } = require('../routesUtils');
|
||||||
|
|
||||||
|
class BucketController {
|
||||||
|
static bucketPutACL(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log, (err, corsHeaders) => {
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
return responseNoBody(err, corsHeaders, res, 200, log);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static bucketPutVersioning(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log, (err, corsHeaders) => {
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
return responseNoBody(err, corsHeaders, res, 200, log);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static bucketPutWebsite(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log, (err, corsHeaders) => {
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
return responseNoBody(err, corsHeaders, res, 200, log);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static bucketPutCors(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log, (err, corsHeaders) => {
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
return responseNoBody(err, corsHeaders, res, 200, log);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static bucketPutReplication(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log, (err, corsHeaders) => {
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
return responseNoBody(err, corsHeaders, res, 200, log);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static bucketPut(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log, (err, corsHeaders) => {
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
const location = { Location: `/${req.bucketName}` };
|
||||||
|
const resHeaders = corsHeaders ?
|
||||||
|
Object.assign({}, location, corsHeaders) : location;
|
||||||
|
return responseNoBody(err, resHeaders, res, 200, log);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BucketController;
|
|
@ -0,0 +1,57 @@
|
||||||
|
const { statsReport500, responseNoBody, responseXMLBody } =
|
||||||
|
require('../routesUtils');
|
||||||
|
|
||||||
|
class ObjectController {
|
||||||
|
static objectPutCopyPart(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log,
|
||||||
|
(err, xml, additionalHeaders) => {
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
return responseXMLBody(err, xml, res, log, additionalHeaders);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static objectPutPart(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log,
|
||||||
|
(err, calculatedHash, corsHeaders) => {
|
||||||
|
if (err) {
|
||||||
|
return responseNoBody(err, corsHeaders, res, 200, log);
|
||||||
|
}
|
||||||
|
const resMetaHeaders = corsHeaders || {};
|
||||||
|
// ETag's hex should always be enclosed in quotes
|
||||||
|
resMetaHeaders.ETag = `"${calculatedHash}"`;
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
return responseNoBody(err, resMetaHeaders, res, 200, log);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static objectPutACL(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log, (err, resHeaders) => {
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
return responseNoBody(err, resHeaders, res, 200, log);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static objectPutTagging(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log, (err, resHeaders) => {
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
return responseNoBody(err, resHeaders, res, 200, log);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static objectCopy(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log,
|
||||||
|
(err, xml, additionalHeaders) => {
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
responseXMLBody(err, xml, res, log, additionalHeaders);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static objectPut(action, req, res, api, log, statsClient) {
|
||||||
|
return api.callApiMethod(action, req, res, log, (err, resHeaders) => {
|
||||||
|
statsReport500(err, statsClient);
|
||||||
|
return responseNoBody(err, resHeaders, res, 200, log);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ObjectController;
|
|
@ -9,6 +9,8 @@ const routePOST = require('./routes/routePOST');
|
||||||
const routeOPTIONS = require('./routes/routeOPTIONS');
|
const routeOPTIONS = require('./routes/routeOPTIONS');
|
||||||
const routesUtils = require('./routesUtils');
|
const routesUtils = require('./routesUtils');
|
||||||
const routeWebsite = require('./routes/routeWebsite');
|
const routeWebsite = require('./routes/routeWebsite');
|
||||||
|
const routesObjects = require('./routes/routesObjects.json');
|
||||||
|
const Router = require('./routes/Router');
|
||||||
|
|
||||||
const routeMap = {
|
const routeMap = {
|
||||||
GET: routeGET,
|
GET: routeGET,
|
||||||
|
@ -212,6 +214,10 @@ function routes(req, res, params, logger) {
|
||||||
return routeWebsite(req, res, api, log, statsClient, dataRetrievalFn);
|
return routeWebsite(req, res, api, log, statsClient, dataRetrievalFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reqMethod === 'PUT') {
|
||||||
|
return new Router(routesObjects).exec(req, res, api, log, statsClient);
|
||||||
|
}
|
||||||
|
|
||||||
return method(req, res, api, log, statsClient, dataRetrievalFn);
|
return method(req, res, api, log, statsClient, dataRetrievalFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
const BucketController = require('../controller/BucketController');
|
||||||
|
const ObjectController = require('../controller/ObjectController');
|
||||||
|
const AuthController = require('../controller/AuthController');
|
||||||
|
|
||||||
|
class Router {
|
||||||
|
constructor(routes) {
|
||||||
|
this._routes = routes;
|
||||||
|
this._controllers = { BucketController, ObjectController };
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_matchRoute(route, req) {
|
||||||
|
const query = route.query || [];
|
||||||
|
const headers = route.headers || [];
|
||||||
|
return req.method === route.method &&
|
||||||
|
Boolean(req.bucketName) === Boolean(route.bucket) &&
|
||||||
|
Boolean(req.objectKey) === Boolean(route.object) &&
|
||||||
|
query.every(q => q in req.query) &&
|
||||||
|
headers.every(h => h in req.headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
exec(req, res, api, log, statsClient) {
|
||||||
|
const route = this._routes.find(r => this._matchRoute(r, req));
|
||||||
|
const { controller, action, auth } = route;
|
||||||
|
for (let i = 0; i < auth.length; i++) {
|
||||||
|
const authMethod = auth[i];
|
||||||
|
const authResponse = AuthController[authMethod](req, res, log);
|
||||||
|
if (authResponse !== undefined) {
|
||||||
|
return authResponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const routeMethod = this._controllers[controller][action];
|
||||||
|
return routeMethod(action, req, res, api, log, statsClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Router;
|
|
@ -1,181 +1,7 @@
|
||||||
const errors = require('../../errors');
|
|
||||||
const routesUtils = require('../routesUtils');
|
|
||||||
|
|
||||||
const encryptionHeaders = [
|
|
||||||
'x-amz-server-side-encryption',
|
|
||||||
'x-amz-server-side-encryption-customer-algorithm',
|
|
||||||
'x-amz-server-side-encryption-aws-kms-key-id',
|
|
||||||
'x-amz-server-side-encryption-context',
|
|
||||||
'x-amz-server-side-encryption-customer-key',
|
|
||||||
'x-amz-server-side-encryption-customer-key-md5',
|
|
||||||
];
|
|
||||||
|
|
||||||
/* eslint-disable no-param-reassign */
|
/* eslint-disable no-param-reassign */
|
||||||
function routePUT(request, response, api, log, statsClient) {
|
function routePUT(request, response, api, log) {
|
||||||
log.debug('routing request', { method: 'routePUT' });
|
log.debug('routing request', { method: 'routePUT' });
|
||||||
|
|
||||||
if (request.objectKey === undefined) {
|
|
||||||
// PUT bucket - PUT bucket ACL
|
|
||||||
|
|
||||||
// content-length for object is handled separately below
|
|
||||||
const contentLength = request.headers['content-length'];
|
|
||||||
if ((contentLength && (isNaN(contentLength) || contentLength < 0)) ||
|
|
||||||
contentLength === '') {
|
|
||||||
log.debug('invalid content-length header');
|
|
||||||
return routesUtils.responseNoBody(
|
|
||||||
errors.BadRequest, null, response, null, log);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PUT bucket ACL
|
|
||||||
if (request.query.acl !== undefined) {
|
|
||||||
api.callApiMethod('bucketPutACL', request, response, log,
|
|
||||||
(err, corsHeaders) => {
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
return routesUtils.responseNoBody(err, corsHeaders,
|
|
||||||
response, 200, log);
|
|
||||||
});
|
|
||||||
} else if (request.query.versioning !== undefined) {
|
|
||||||
api.callApiMethod('bucketPutVersioning', request, response, log,
|
|
||||||
(err, corsHeaders) => {
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
routesUtils.responseNoBody(err, corsHeaders, response, 200,
|
|
||||||
log);
|
|
||||||
});
|
|
||||||
} else if (request.query.website !== undefined) {
|
|
||||||
api.callApiMethod('bucketPutWebsite', request, response, log,
|
|
||||||
(err, corsHeaders) => {
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
return routesUtils.responseNoBody(err, corsHeaders,
|
|
||||||
response, 200, log);
|
|
||||||
});
|
|
||||||
} else if (request.query.cors !== undefined) {
|
|
||||||
api.callApiMethod('bucketPutCors', request, response, log,
|
|
||||||
(err, corsHeaders) => {
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
return routesUtils.responseNoBody(err, corsHeaders,
|
|
||||||
response, 200, log);
|
|
||||||
});
|
|
||||||
} else if (request.query.replication !== undefined) {
|
|
||||||
api.callApiMethod('bucketPutReplication', request, response, log,
|
|
||||||
(err, corsHeaders) => {
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
routesUtils.responseNoBody(err, corsHeaders, response, 200,
|
|
||||||
log);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// PUT bucket
|
|
||||||
return api.callApiMethod('bucketPut', request, response, log,
|
|
||||||
(err, corsHeaders) => {
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
const location = { Location: `/${request.bucketName}` };
|
|
||||||
const resHeaders = corsHeaders ?
|
|
||||||
Object.assign({}, location, corsHeaders) : location;
|
|
||||||
return routesUtils.responseNoBody(err, resHeaders,
|
|
||||||
response, 200, log);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// PUT object, PUT object ACL, PUT object multipart or
|
|
||||||
// PUT object copy
|
|
||||||
// if content-md5 is not present in the headers, try to
|
|
||||||
// parse content-md5 from meta headers
|
|
||||||
|
|
||||||
if (request.headers['content-md5'] === '') {
|
|
||||||
log.debug('empty content-md5 header', {
|
|
||||||
method: 'routePUT',
|
|
||||||
});
|
|
||||||
return routesUtils
|
|
||||||
.responseNoBody(errors.InvalidDigest, null, response, 200, log);
|
|
||||||
}
|
|
||||||
if (request.headers['content-md5']) {
|
|
||||||
request.contentMD5 = request.headers['content-md5'];
|
|
||||||
} else {
|
|
||||||
request.contentMD5 = routesUtils.parseContentMD5(request.headers);
|
|
||||||
}
|
|
||||||
if (request.contentMD5 && request.contentMD5.length !== 32) {
|
|
||||||
request.contentMD5 = Buffer.from(request.contentMD5, 'base64')
|
|
||||||
.toString('hex');
|
|
||||||
if (request.contentMD5 && request.contentMD5.length !== 32) {
|
|
||||||
log.debug('invalid md5 digest', {
|
|
||||||
contentMD5: request.contentMD5,
|
|
||||||
});
|
|
||||||
return routesUtils
|
|
||||||
.responseNoBody(errors.InvalidDigest, null, response, 200,
|
|
||||||
log);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// object level encryption
|
|
||||||
if (encryptionHeaders.some(i => request.headers[i] !== undefined)) {
|
|
||||||
return routesUtils.responseXMLBody(errors.NotImplemented, null,
|
|
||||||
response, log);
|
|
||||||
}
|
|
||||||
if (request.query.partNumber) {
|
|
||||||
if (request.headers['x-amz-copy-source']) {
|
|
||||||
api.callApiMethod('objectPutCopyPart', request, response, log,
|
|
||||||
(err, xml, additionalHeaders) => {
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
return routesUtils.responseXMLBody(err, xml, response, log,
|
|
||||||
additionalHeaders);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
api.callApiMethod('objectPutPart', request, response, log,
|
|
||||||
(err, calculatedHash, corsHeaders) => {
|
|
||||||
if (err) {
|
|
||||||
return routesUtils.responseNoBody(err, corsHeaders,
|
|
||||||
response, 200, log);
|
|
||||||
}
|
|
||||||
// ETag's hex should always be enclosed in quotes
|
|
||||||
const resMetaHeaders = corsHeaders || {};
|
|
||||||
resMetaHeaders.ETag = `"${calculatedHash}"`;
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
return routesUtils.responseNoBody(err, resMetaHeaders,
|
|
||||||
response, 200, log);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (request.query.acl !== undefined) {
|
|
||||||
api.callApiMethod('objectPutACL', request, response, log,
|
|
||||||
(err, resHeaders) => {
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
return routesUtils.responseNoBody(err, resHeaders,
|
|
||||||
response, 200, log);
|
|
||||||
});
|
|
||||||
} else if (request.query.tagging !== undefined) {
|
|
||||||
api.callApiMethod('objectPutTagging', request, response, log,
|
|
||||||
(err, resHeaders) => {
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
return routesUtils.responseNoBody(err, resHeaders,
|
|
||||||
response, 200, log);
|
|
||||||
});
|
|
||||||
} else if (request.headers['x-amz-copy-source']) {
|
|
||||||
return api.callApiMethod('objectCopy', request, response, log,
|
|
||||||
(err, xml, additionalHeaders) => {
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
routesUtils.responseXMLBody(err, xml, response, log,
|
|
||||||
additionalHeaders);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (request.headers['content-length'] === undefined &&
|
|
||||||
request.headers['x-amz-decoded-content-length'] === undefined) {
|
|
||||||
return routesUtils.responseNoBody(errors.MissingContentLength,
|
|
||||||
null, response, 411, log);
|
|
||||||
}
|
|
||||||
if (Number.isNaN(request.parsedContentLength) ||
|
|
||||||
request.parsedContentLength < 0) {
|
|
||||||
return routesUtils.responseNoBody(errors.BadRequest,
|
|
||||||
null, response, 400, log);
|
|
||||||
}
|
|
||||||
log.end().addDefaultFields({
|
|
||||||
contentLength: request.parsedContentLength,
|
|
||||||
});
|
|
||||||
|
|
||||||
api.callApiMethod('objectPut', request, response, log,
|
|
||||||
(err, resHeaders) => {
|
|
||||||
routesUtils.statsReport500(err, statsClient);
|
|
||||||
return routesUtils.responseNoBody(err, resHeaders,
|
|
||||||
response, 200, log);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
/* eslint-enable no-param-reassign */
|
/* eslint-enable no-param-reassign */
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "BucketController",
|
||||||
|
"action": "bucketPutACL",
|
||||||
|
"query": [ "acl" ],
|
||||||
|
"auth": [ "bucketPut" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "BucketController",
|
||||||
|
"action": "bucketPutVersioning",
|
||||||
|
"query": [ "versioning" ],
|
||||||
|
"auth": [ "bucketPut" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "BucketController",
|
||||||
|
"action": "bucketPutWebsite",
|
||||||
|
"query": [ "website" ],
|
||||||
|
"auth": [ "bucketPut" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "BucketController",
|
||||||
|
"action": "bucketPutCors",
|
||||||
|
"query": [ "cors" ],
|
||||||
|
"auth": [ "bucketPut" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "BucketController",
|
||||||
|
"action": "bucketPutReplication",
|
||||||
|
"query": [ "replication" ],
|
||||||
|
"auth": [ "bucketPut" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "BucketController",
|
||||||
|
"action": "bucketPut",
|
||||||
|
"auth": [ "bucketPut" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"object": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "ObjectController",
|
||||||
|
"action": "objectPutCopyPart",
|
||||||
|
"headers": [ "x-amz-copy-source" ],
|
||||||
|
"query": [ "partNumber" ],
|
||||||
|
"auth": [ "objectPutAction" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"object": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "ObjectController",
|
||||||
|
"action": "objectPutPart",
|
||||||
|
"query": [ "partNumber" ],
|
||||||
|
"auth": [ "objectPutAction" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"object": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "ObjectController",
|
||||||
|
"action": "objectPutACL",
|
||||||
|
"query": [ "acl" ],
|
||||||
|
"auth": [ "objectPutAction" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"object": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "ObjectController",
|
||||||
|
"action": "objectPutTagging",
|
||||||
|
"query": [ "tagging" ],
|
||||||
|
"auth": [ "objectPutAction" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"object": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "ObjectController",
|
||||||
|
"action": "objectCopy",
|
||||||
|
"headers": [ "x-amz-copy-source" ],
|
||||||
|
"auth": [ "objectPutAction" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bucket": true,
|
||||||
|
"object": true,
|
||||||
|
"method": "PUT",
|
||||||
|
"controller": "ObjectController",
|
||||||
|
"action": "objectPut",
|
||||||
|
"auth": [ "objectPutAction", "objectPut" ]
|
||||||
|
}
|
||||||
|
]
|
Loading…
Reference in New Issue