mirror of
https://github.com/hanzoai/gateway.git
synced 2026-10-30 15:04:44 +00:00
Modules declare go 1.27.1 and the build images follow. go fix applied the modernizers; omitzero is not applied, since it changes what the JSON says. Co-authored-by: Hanzo Dev <[email protected]>
98 lines
2.3 KiB
Go
98 lines
2.3 KiB
Go
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package proxy
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"maps"
|
|
"net/url"
|
|
)
|
|
|
|
// Request contains the data to send to the backend
|
|
type Request struct {
|
|
Method string
|
|
URL *url.URL
|
|
Query url.Values
|
|
Path string
|
|
Body io.ReadCloser
|
|
Params map[string]string
|
|
Headers map[string][]string
|
|
}
|
|
|
|
// GeneratePath takes a pattern and updates the path of the request
|
|
func (r *Request) GeneratePath(URLPattern string) {
|
|
if len(r.Params) == 0 {
|
|
r.Path = URLPattern
|
|
return
|
|
}
|
|
buff := []byte(URLPattern)
|
|
for k, v := range r.Params {
|
|
var key []byte
|
|
|
|
key = append(key, "{{."...)
|
|
key = append(key, k...)
|
|
key = append(key, "}}"...)
|
|
buff = bytes.ReplaceAll(buff, key, []byte(v))
|
|
}
|
|
r.Path = string(buff)
|
|
}
|
|
|
|
// Clone clones itself into a new request. The returned cloned request is not
|
|
// thread-safe, so changes on request.Params and request.Headers could generate
|
|
// race-conditions depending on the part of the pipe they are being executed.
|
|
// For thread-safe request headers and/or params manipulation, use the proxy.CloneRequest
|
|
// function.
|
|
func (r *Request) Clone() Request {
|
|
var clonedURL *url.URL
|
|
if r.URL != nil {
|
|
clonedURL, _ = url.Parse(r.URL.String())
|
|
}
|
|
return Request{
|
|
Method: r.Method,
|
|
URL: clonedURL,
|
|
Query: r.Query,
|
|
Path: r.Path,
|
|
Body: r.Body,
|
|
Params: r.Params,
|
|
Headers: r.Headers,
|
|
}
|
|
}
|
|
|
|
// CloneRequest returns a deep copy of the received request, so the received and the
|
|
// returned proxy.Request do not share a pointer
|
|
func CloneRequest(r *Request) *Request {
|
|
clone := r.Clone()
|
|
clone.Headers = CloneRequestHeaders(r.Headers)
|
|
clone.Params = CloneRequestParams(r.Params)
|
|
if r.Body == nil {
|
|
return &clone
|
|
}
|
|
buf := new(bytes.Buffer)
|
|
buf.ReadFrom(r.Body)
|
|
r.Body.Close()
|
|
|
|
r.Body = io.NopCloser(bytes.NewReader(buf.Bytes()))
|
|
clone.Body = io.NopCloser(buf)
|
|
|
|
return &clone
|
|
}
|
|
|
|
// CloneRequestHeaders returns a copy of the received request headers
|
|
func CloneRequestHeaders(headers map[string][]string) map[string][]string {
|
|
m := make(map[string][]string, len(headers))
|
|
for k, vs := range headers {
|
|
tmp := make([]string, len(vs))
|
|
copy(tmp, vs)
|
|
m[k] = tmp
|
|
}
|
|
return m
|
|
}
|
|
|
|
// CloneRequestParams returns a copy of the received request params
|
|
func CloneRequestParams(params map[string]string) map[string]string {
|
|
m := make(map[string]string, len(params))
|
|
maps.Copy(m, params)
|
|
return m
|
|
}
|