103 lines
1.9 KiB
Go
103 lines
1.9 KiB
Go
package common
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"sync"
|
|
|
|
"git.optclblast.xyz/draincloud/draincloud-core/internal/logger"
|
|
"git.optclblast.xyz/draincloud/draincloud-core/internal/storage/models"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type RequestPool struct {
|
|
sp sync.Pool
|
|
}
|
|
|
|
func (p *RequestPool) Get() *Request {
|
|
r, _ := p.sp.Get().(*Request)
|
|
return r
|
|
}
|
|
|
|
func (p *RequestPool) Put(r *Request) {
|
|
r.ID = ""
|
|
r.Metadata = &sync.Map{}
|
|
r.ResolveValues = &sync.Map{}
|
|
r.Session = nil
|
|
r.User = nil
|
|
r.Body = nil
|
|
p.sp.Put(r)
|
|
}
|
|
|
|
func NewRequestPool() *RequestPool {
|
|
return &RequestPool{
|
|
sp: sync.Pool{
|
|
New: func() any {
|
|
return &Request{
|
|
ResolveValues: &sync.Map{},
|
|
Metadata: &sync.Map{},
|
|
}
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
type Request struct {
|
|
ID string
|
|
Session *models.Session
|
|
User *models.User
|
|
ResolveValues *sync.Map
|
|
Metadata *sync.Map
|
|
Body []byte
|
|
RawReq *http.Request
|
|
}
|
|
|
|
// NewRequestFromHttp builds a new *Request struct from raw http Request. No auth data validated.
|
|
func NewRequestFromHttp(pool *RequestPool, req *http.Request) *Request {
|
|
out := pool.sp.Get().(*Request)
|
|
|
|
cookies := req.Cookies()
|
|
headers := req.Header
|
|
|
|
out.Metadata = &sync.Map{}
|
|
out.RawReq = req
|
|
|
|
for _, cookie := range cookies {
|
|
out.Metadata.Store(cookie.Name, cookie.Value)
|
|
}
|
|
|
|
for hname, hval := range headers {
|
|
out.Metadata.Store(hname, hval)
|
|
}
|
|
|
|
body, err := io.ReadAll(req.Body)
|
|
if err != nil {
|
|
logger.Error(context.TODO(), "failed to read request body", logger.Err(err))
|
|
}
|
|
out.Body = body
|
|
|
|
reqID := uuid.NewString()
|
|
out.ID = reqID
|
|
return out
|
|
}
|
|
|
|
func GetValue[T any](vals *sync.Map, key string) (T, error) {
|
|
var out T
|
|
if vals == nil {
|
|
return out, fmt.Errorf("nil vals map")
|
|
}
|
|
rawVal, ok := vals.Load(key)
|
|
if !ok {
|
|
return out, fmt.Errorf("value not found in resolve values set")
|
|
}
|
|
|
|
out, ok = rawVal.(T)
|
|
if !ok {
|
|
return out, fmt.Errorf("type of a value is unexpected")
|
|
}
|
|
|
|
return out, nil
|
|
}
|