xframe/component/queue/asynq/internal/handlers/http_handlers.go

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
}