mirror of
https://github.com/eiblog/eiblog.git
synced 2026-02-10 16:42:26 +08:00
111 lines
2.2 KiB
Go
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)
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|