105 lines
2.2 KiB
Go
Executable File
105 lines
2.2 KiB
Go
Executable File
package handlers
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"reflect"
|
|
|
|
"git.wishpal.cn/wishpal_ironfan/xframe/component/logger"
|
|
"git.wishpal.cn/wishpal_ironfan/xframe/serving_base/http/utils"
|
|
)
|
|
|
|
type HttpHandler struct {
|
|
// 这个变量不能改,通过反射调用的
|
|
Processor http.HandlerFunc
|
|
}
|
|
|
|
type HttpHandlerPayload struct {
|
|
Method string
|
|
RequestURI string
|
|
URL *url.URL
|
|
Header http.Header
|
|
ContentLength int64
|
|
Body []byte
|
|
}
|
|
|
|
func (h HttpHandler) NewParam() (reflect.Value, error) {
|
|
p := new(HttpHandlerPayload)
|
|
return reflect.ValueOf(p), nil
|
|
}
|
|
|
|
func (h HttpHandler) Call(ctx context.Context, v reflect.Value, p reflect.Value) error {
|
|
vh, ok := v.Interface().(*HttpHandlerPayload)
|
|
if !ok {
|
|
return errors.New("")
|
|
}
|
|
|
|
r := &http.Request{
|
|
Method: vh.Method,
|
|
RequestURI: vh.RequestURI,
|
|
URL: vh.URL,
|
|
Header: vh.Header,
|
|
ContentLength: vh.ContentLength,
|
|
Body: io.NopCloser(bytes.NewReader(vh.Body)),
|
|
}
|
|
r.WithContext(ctx)
|
|
|
|
p.Call([]reflect.Value{
|
|
reflect.ValueOf(newFakeResponseWriter(ctx)),
|
|
reflect.ValueOf(r),
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func MustRegistHttpHandler(typ string, f http.HandlerFunc) {
|
|
handler := HttpHandler{
|
|
Processor: f,
|
|
}
|
|
|
|
lock.Lock()
|
|
handlers[typ] = handler
|
|
lock.Unlock()
|
|
}
|
|
|
|
func RequestToPayload(r *http.Request) HttpHandlerPayload {
|
|
body, _ := utils.GetRequestBody(r)
|
|
return HttpHandlerPayload{
|
|
Method: r.Method,
|
|
RequestURI: r.RequestURI,
|
|
URL: r.URL,
|
|
Header: r.Header,
|
|
ContentLength: r.ContentLength,
|
|
Body: body,
|
|
}
|
|
}
|
|
|
|
// A FakeResponseWriter is a http.ResponseWriter implementation.
|
|
type FakeResponseWriter struct {
|
|
context.Context
|
|
Code int
|
|
}
|
|
|
|
// NewFakeResponseWriter returns a FakeResponseWriter.
|
|
func newFakeResponseWriter(ctx context.Context) *FakeResponseWriter {
|
|
return &FakeResponseWriter{
|
|
Context: ctx,
|
|
}
|
|
}
|
|
|
|
func (w *FakeResponseWriter) Header() http.Header {
|
|
return http.Header{}
|
|
}
|
|
|
|
func (w *FakeResponseWriter) Write(bytes []byte) (int, error) {
|
|
logger.WithContext(w.Context).Infof("[FakeResponseWriter] write code:%d, data:%s", w.Code, string(bytes))
|
|
return len(bytes), nil
|
|
}
|
|
|
|
func (w *FakeResponseWriter) WriteHeader(code int) {
|
|
w.Code = code
|
|
}
|