2017-07-23 12:24:45 +00:00
|
|
|
/*
|
2017-12-08 19:45:59 +00:00
|
|
|
* Minio Go Library for Amazon S3 Compatible Cloud Storage
|
|
|
|
* Copyright 2015-2017 Minio, Inc.
|
2017-07-23 12:24:45 +00:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package s3signer
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"bytes"
|
|
|
|
"crypto/tls"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
// N B minio-go should compile on go1.5.3 onwards and httptest package is
|
|
|
|
// available only from go.1.7.x. The following function is taken from
|
|
|
|
// Go httptest package to be able to build on older versions of Go.
|
|
|
|
|
|
|
|
// NewRequest returns a new incoming server Request, suitable
|
|
|
|
// for passing to an http.Handler for testing.
|
|
|
|
//
|
|
|
|
// The target is the RFC 7230 "request-target": it may be either a
|
|
|
|
// path or an absolute URL. If target is an absolute URL, the host name
|
|
|
|
// from the URL is used. Otherwise, "example.com" is used.
|
|
|
|
//
|
|
|
|
// The TLS field is set to a non-nil dummy value if target has scheme
|
|
|
|
// "https".
|
|
|
|
//
|
|
|
|
// The Request.Proto is always HTTP/1.1.
|
|
|
|
//
|
|
|
|
// An empty method means "GET".
|
|
|
|
//
|
|
|
|
// The provided body may be nil. If the body is of type *bytes.Reader,
|
|
|
|
// *strings.Reader, or *bytes.Buffer, the Request.ContentLength is
|
|
|
|
// set.
|
|
|
|
//
|
|
|
|
// NewRequest panics on error for ease of use in testing, where a
|
|
|
|
// panic is acceptable.
|
|
|
|
func NewRequest(method, target string, body io.Reader) *http.Request {
|
|
|
|
if method == "" {
|
|
|
|
method = "GET"
|
|
|
|
}
|
|
|
|
req, err := http.ReadRequest(bufio.NewReader(strings.NewReader(method + " " + target + " HTTP/1.0\r\n\r\n")))
|
|
|
|
if err != nil {
|
|
|
|
panic("invalid NewRequest arguments; " + err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
// HTTP/1.0 was used above to avoid needing a Host field. Change it to 1.1 here.
|
|
|
|
req.Proto = "HTTP/1.1"
|
|
|
|
req.ProtoMinor = 1
|
|
|
|
req.Close = false
|
|
|
|
|
|
|
|
if body != nil {
|
|
|
|
switch v := body.(type) {
|
|
|
|
case *bytes.Buffer:
|
|
|
|
req.ContentLength = int64(v.Len())
|
|
|
|
case *bytes.Reader:
|
|
|
|
req.ContentLength = int64(v.Len())
|
|
|
|
case *strings.Reader:
|
|
|
|
req.ContentLength = int64(v.Len())
|
|
|
|
default:
|
|
|
|
req.ContentLength = -1
|
|
|
|
}
|
|
|
|
if rc, ok := body.(io.ReadCloser); ok {
|
|
|
|
req.Body = rc
|
|
|
|
} else {
|
|
|
|
req.Body = ioutil.NopCloser(body)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 192.0.2.0/24 is "TEST-NET" in RFC 5737 for use solely in
|
|
|
|
// documentation and example source code and should not be
|
|
|
|
// used publicly.
|
|
|
|
req.RemoteAddr = "192.0.2.1:1234"
|
|
|
|
|
|
|
|
if req.Host == "" {
|
|
|
|
req.Host = "example.com"
|
|
|
|
}
|
|
|
|
|
|
|
|
if strings.HasPrefix(target, "https://") {
|
|
|
|
req.TLS = &tls.ConnectionState{
|
|
|
|
Version: tls.VersionTLS12,
|
|
|
|
HandshakeComplete: true,
|
|
|
|
ServerName: req.Host,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return req
|
|
|
|
}
|