Files
eiblog/vendor/github.com/qiniu/x/mockhttp.v7/mockhttp.go
2017-07-11 23:50:01 +08:00

111 lines
2.2 KiB
Go

package mockhttp
import (
"errors"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"strconv"
"qiniupkg.com/x/log.v7"
)
var (
ErrServerNotFound = errors.New("server not found")
)
// --------------------------------------------------------------------
type mockServerRequestBody struct {
reader io.Reader
closeSignal bool
}
func (r *mockServerRequestBody) Read(p []byte) (int, error) {
if r.closeSignal || r.reader == nil {
return 0, io.EOF
}
return r.reader.Read(p)
}
func (r *mockServerRequestBody) Close() error {
r.closeSignal = true
if c, ok := r.reader.(io.Closer); ok {
return c.Close()
}
return nil
}
// --------------------------------------------------------------------
// type Transport
type Transport struct {
route map[string]http.Handler
}
func NewTransport() *Transport {
return &Transport{
route: make(map[string]http.Handler),
}
}
func (p *Transport) ListenAndServe(host string, h http.Handler) {
if h == nil {
h = http.DefaultServeMux
}
p.route[host] = h
}
func (p *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
h := p.route[req.URL.Host]
if h == nil {
log.Warn("Server not found:", req.Host)
return nil, ErrServerNotFound
}
cp := *req
cp.URL.Scheme = ""
cp.URL.Host = ""
cp.RemoteAddr = "127.0.0.1:8000"
cp.Body = &mockServerRequestBody{req.Body, false}
req = &cp
rw := httptest.NewRecorder()
h.ServeHTTP(rw, req)
req.Body.Close()
ctlen := int64(-1)
if v := rw.HeaderMap.Get("Content-Length"); v != "" {
ctlen, _ = strconv.ParseInt(v, 10, 64)
}
return &http.Response{
Status: "",
StatusCode: rw.Code,
Header: rw.HeaderMap,
Body: ioutil.NopCloser(rw.Body),
ContentLength: ctlen,
TransferEncoding: nil,
Close: false,
Trailer: nil,
Request: req,
}, nil
}
// --------------------------------------------------------------------
var DefaultTransport = NewTransport()
var DefaultClient = &http.Client{Transport: DefaultTransport}
func ListenAndServe(host string, h http.Handler) {
DefaultTransport.ListenAndServe(host, h)
}
// --------------------------------------------------------------------