s3cmd: Handle support for s3cmd.

master
Harshavardhana 9 years ago
parent 7187668828
commit 3c71c5c80c
  1. 25
      README.md
  2. 8
      api-errors.go
  3. 2
      api-headers.go
  4. 21
      generic-handlers.go
  5. 3
      routers.go
  6. 2
      signature-handler.go

@ -126,11 +126,28 @@ Listening on http://172.30.2.17:9000
Please follow the documentation here - [Using aws-sdk-go with Minio server](./AWS-SDK-GO.md) Please follow the documentation here - [Using aws-sdk-go with Minio server](./AWS-SDK-GO.md)
#### How to use s3cmd with Minio? #### How to use s3cmd with Minio?
<blockquote>
Even with Signature version '4' enabled, 's3cmd' falls back to Signature version '2' for listing your buckets. Since minio server is only Signature version '4' listing your buckets with Signature version '2' fails. We have no immediate plans on supporting Signature version '2'. Please follow https://github.com/minio/minio/issues/987 to know more on this issue.
</blockquote>
`s3cmd` is currently not supported. Edit the following fields in your s3cmd configuration file. ~/.s3cfg
```
host_base = localhost:9000
host_bucket = localhost:9000
access_key = YOUR_ACCESS_KEY_HERE
secret_key = YOUR_SECRET_KEY_HERE
```
To list your buckets.
```
$ s3cmd --region us-east-1 ls s3://
2015-12-09 16:12 s3://testbbucket
```
To list contents inside buckets.
```
$ s3cmd --region us-east-1 ls s3://testbucket/
DIR s3://testbucket/test/
2015-12-09 16:05 138504 s3://testbucket/newfile
```
## Contribute to Minio Project ## Contribute to Minio Project
Please follow Minio [Contributor's Guide](./CONTRIBUTING.md) Please follow Minio [Contributor's Guide](./CONTRIBUTING.md)

@ -33,6 +33,8 @@ type APIErrorResponse struct {
XMLName xml.Name `xml:"Error" json:"-"` XMLName xml.Name `xml:"Error" json:"-"`
Code string Code string
Message string Message string
Key string
BucketName string
Resource string Resource string
RequestID string `xml:"RequestId"` RequestID string `xml:"RequestId"`
HostID string `xml:"HostId"` HostID string `xml:"HostId"`
@ -70,6 +72,7 @@ const (
InvalidPartOrder InvalidPartOrder
AuthorizationHeaderMalformed AuthorizationHeaderMalformed
MalformedPOSTRequest MalformedPOSTRequest
SignatureVersionNotSupported
BucketNotEmpty BucketNotEmpty
RootPathFull RootPathFull
) )
@ -221,6 +224,11 @@ var errorCodeResponse = map[int]APIError{
Description: "The body of your POST request is not well-formed multipart/form-data.", Description: "The body of your POST request is not well-formed multipart/form-data.",
HTTPStatusCode: http.StatusBadRequest, HTTPStatusCode: http.StatusBadRequest,
}, },
SignatureVersionNotSupported: {
Code: "InvalidRequest",
Description: "The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.",
HTTPStatusCode: http.StatusBadRequest,
},
BucketNotEmpty: { BucketNotEmpty: {
Code: "BucketNotEmpty", Code: "BucketNotEmpty",
Description: "The bucket you tried to delete is not empty.", Description: "The bucket you tried to delete is not empty.",

@ -57,6 +57,7 @@ func setCommonHeaders(w http.ResponseWriter, contentLength int) {
func encodeErrorResponse(response interface{}) []byte { func encodeErrorResponse(response interface{}) []byte {
var bytesBuffer bytes.Buffer var bytesBuffer bytes.Buffer
// write common headers // write common headers
bytesBuffer.WriteString(xml.Header)
e := xml.NewEncoder(&bytesBuffer) e := xml.NewEncoder(&bytesBuffer)
e.Encode(response) e.Encode(response)
return bytesBuffer.Bytes() return bytesBuffer.Bytes()
@ -92,6 +93,7 @@ func setObjectHeaders(w http.ResponseWriter, metadata fs.ObjectMetadata, content
func encodeSuccessResponse(response interface{}) []byte { func encodeSuccessResponse(response interface{}) []byte {
var bytesBuffer bytes.Buffer var bytesBuffer bytes.Buffer
bytesBuffer.WriteString(xml.Header)
e := xml.NewEncoder(&bytesBuffer) e := xml.NewEncoder(&bytesBuffer)
e.Encode(response) e.Encode(response)
return bytesBuffer.Bytes() return bytesBuffer.Bytes()

@ -46,6 +46,10 @@ type resourceHandler struct {
handler http.Handler handler http.Handler
} }
type ignoreSignatureV2RequestHandler struct {
handler http.Handler
}
func parseDate(req *http.Request) (time.Time, error) { func parseDate(req *http.Request) (time.Time, error) {
amzDate := req.Header.Get(http.CanonicalHeaderKey("x-amz-date")) amzDate := req.Header.Get(http.CanonicalHeaderKey("x-amz-date"))
switch { switch {
@ -128,6 +132,23 @@ func CorsHandler(h http.Handler) http.Handler {
return c.Handler(h) return c.Handler(h)
} }
// IgnoreSignatureV2RequestHandler -
// Verify if authorization header has signature version '2', reject it cleanly.
func IgnoreSignatureV2RequestHandler(h http.Handler) http.Handler {
return ignoreSignatureV2RequestHandler{h}
}
// Ignore signature version '2' ServerHTTP() wrapper.
func (h ignoreSignatureV2RequestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if _, ok := r.Header["Authorization"]; ok {
if !strings.HasPrefix(r.Header.Get("Authorization"), authHeaderPrefix) {
writeErrorResponse(w, r, SignatureVersionNotSupported, r.URL.Path)
return
}
}
h.handler.ServeHTTP(w, r)
}
// IgnoreResourcesHandler - // IgnoreResourcesHandler -
// Ignore resources handler is wrapper handler used for API request resource validation // Ignore resources handler is wrapper handler used for API request resource validation
// Since we do not support all the S3 queries, it is necessary for us to throw back a // Since we do not support all the S3 queries, it is necessary for us to throw back a

@ -80,9 +80,10 @@ func getNewCloudStorageAPI(conf cloudServerConfig) CloudStorageAPI {
func getCloudStorageAPIHandler(api CloudStorageAPI) http.Handler { func getCloudStorageAPIHandler(api CloudStorageAPI) http.Handler {
var mwHandlers = []MiddlewareHandler{ var mwHandlers = []MiddlewareHandler{
CorsHandler,
TimeValidityHandler, TimeValidityHandler,
IgnoreResourcesHandler, IgnoreResourcesHandler,
CorsHandler, IgnoreSignatureV2RequestHandler,
} }
if !api.Anonymous { if !api.Anonymous {
mwHandlers = append(mwHandlers, SignatureHandler) mwHandlers = append(mwHandlers, SignatureHandler)

@ -37,8 +37,10 @@ func SignatureHandler(h http.Handler) http.Handler {
func isRequestSignatureV4(req *http.Request) bool { func isRequestSignatureV4(req *http.Request) bool {
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
if strings.HasPrefix(req.Header.Get("Authorization"), authHeaderPrefix) {
return ok return ok
} }
}
return false return false
} }

Loading…
Cancel
Save