diff --git a/internal/route/routes/context.go b/internal/route/routes/context.go index 0bb60dc8..3365417a 100644 --- a/internal/route/routes/context.go +++ b/internal/route/routes/context.go @@ -2,10 +2,6 @@ package routes import ( "context" - "crypto/tls" - "fmt" - "io" - "mime/multipart" "net/http" "net/url" "reflect" @@ -34,7 +30,8 @@ func (r *RouteContext) Value(key any) any { func WithRouteContext(r *http.Request, route types.HTTPRoute) *http.Request { // we don't want to copy the request object every fucking requests // return r.WithContext(context.WithValue(r.Context(), routeContextKey, route)) - (*requestInternal)(unsafe.Pointer(r)).ctx = &RouteContext{ + ctxFieldPtr := (*context.Context)(unsafe.Pointer(uintptr(unsafe.Pointer(r)) + ctxFieldOffset)) + *ctxFieldPtr = &RouteContext{ Context: r.Context(), Route: route, } @@ -107,43 +104,12 @@ func TryGetUpstreamURL(r *http.Request) string { return "" } -type requestInternal struct { - Method string - URL *url.URL - Proto string - ProtoMajor int - ProtoMinor int - Header http.Header - Body io.ReadCloser - GetBody func() (io.ReadCloser, error) - ContentLength int64 - TransferEncoding []string - Close bool - Host string - Form url.Values - PostForm url.Values - MultipartForm *multipart.Form - Trailer http.Header - RemoteAddr string - RequestURI string - TLS *tls.ConnectionState - Cancel <-chan struct{} - Response *http.Response - Pattern string - ctx context.Context -} +var ctxFieldOffset uintptr func init() { - // make sure ctx has the same offset as http.Request - f, ok := reflect.TypeFor[requestInternal]().FieldByName("ctx") + f, ok := reflect.TypeFor[http.Request]().FieldByName("ctx") if !ok { panic("ctx field not found") } - f2, ok := reflect.TypeFor[http.Request]().FieldByName("ctx") - if !ok { - panic("ctx field not found") - } - if f.Offset != f2.Offset { - panic(fmt.Sprintf("ctx has different offset than http.Request: %d != %d", f.Offset, f2.Offset)) - } + ctxFieldOffset = f.Offset }