Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
# Ignore all
*
# Env files
**/*.env

# env file
*.env
# Editor/IDE
# .idea/
.vscode/

# Git folders
.git*
.github
!.github

# Docusaurus
.docusaurus
node_modules

# Dev folders
.dev
dev-env.sh
*.local.*

# Ignore yml files
*.yaml
*.yml
# Editor config
.editorconfig

# Markdown files
*.md
**/*.md

!LICENSE

# Include data/
!data/*

# Ignore source files
*.go
go.mod
go.sum

# Include build
!app
!dist/*
# Include source files
!*.go
7 changes: 4 additions & 3 deletions .github/workflows/docker-image-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ on:
- beta
- alpha
- dev
- feat

env:
TYPES: "rc,beta,alpha,dev"
TYPES: "rc,beta,alpha,dev,feat"

TYPE: ${{ inputs.type }}
BASE_TAG: ${{ inputs.base-tag }}
Expand Down Expand Up @@ -113,7 +114,7 @@ jobs:
echo "COUNT=$COUNT" >> "$GITHUB_ENV"

- name: Login to Registry
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
Expand Down Expand Up @@ -181,7 +182,7 @@ jobs:

update:
needs: resolve-tag
uses: codeshelldev/gh-actions/.github/workflows/docker-image-go.yml@main
uses: codeshelldev/gh-actions/.github/workflows/docker-image.yml@main
name: Development Image
with:
registry: ghcr.io
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
update:
needs: check
if: needs.check.outputs.continue == 'true'
uses: codeshelldev/gh-actions/.github/workflows/docker-image-go.yml@main
uses: codeshelldev/gh-actions/.github/workflows/docker-image.yml@main
name: Stable Image
with:
registry: ghcr.io
Expand Down
27 changes: 2 additions & 25 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,28 +1,5 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Code coverage profiles and other test artifacts
*.out
coverage.*
*.coverprofile
profile.cov

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work
go.work.sum

# env file
*.env
# Env files
**/*.env

# Editor/IDE
# .idea/
Expand Down
29 changes: 18 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.26-alpine AS builder

ARG TARGETOS
ARG TARGETARCH

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY . .

RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
go build -ldflags="-s -w" -o /app/app .

FROM alpine:3.22

RUN apk --no-cache add ca-certificates

ARG IMAGE_TAG
ENV IMAGE_TAG=$IMAGE_TAG
LABEL org.opencontainers.image.version=$IMAGE_TAG

ENV SERVICE__PORT=8880

ENV DEFAULTS_PATH=/app/data/defaults.yml
ENV FAVICON_PATH=/app/data/favicon.ico

Expand All @@ -15,19 +29,12 @@ ENV TOKENS_DIR=/config/tokens

ENV DB_PATH=/db/db.sqlite3

ENV CGO_ENABLED=1

ENV REDACT_TOKENS=true

ARG TARGETOS
ARG TARGETARCH

WORKDIR /app

COPY . .

COPY dist/${TARGETOS}/${TARGETARCH}/app .
COPY --from=builder /app/app .

RUN rm dist/ -r
COPY data/ /app/data/

CMD ["./app"]
5 changes: 5 additions & 0 deletions data/defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,8 @@ settings:
matchType: prefix
- pattern: /v1/contacts
matchType: prefix

cors:
methods: [GET, POST, PUT, PATCH, DELETE, OPTIONS]
headers:
["Content-Type", "Authorization", "Accept", "Accept-Language", "Origin"]
2 changes: 0 additions & 2 deletions dev-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ export CONFIG_PATH=$DIR/.dev/config.yml
export TOKENS_DIR=$DIR/.dev/tokens
export DB_PATH=$DIR/.dev/db/db.sqlite3

export CGO_ENABLED=1

export API_URL=http://127.0.0.1:8881

export LOG_LEVEL=dev
Expand Down
16 changes: 13 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/codeshelldev/secured-signal-api

go 1.26.0
go 1.26.1

require (
github.com/codeshelldev/gotl/pkg/configutils v0.0.22
Expand All @@ -20,6 +20,17 @@ require (
github.com/go-viper/mapstructure/v2 v2.5.0
github.com/knadh/koanf/parsers/yaml v1.1.0
golang.org/x/time v0.14.0
modernc.org/sqlite v1.47.0
)

require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
modernc.org/libc v1.70.0 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
)

require (
Expand All @@ -32,11 +43,10 @@ require (
github.com/knadh/koanf/providers/file v1.2.1 // indirect
github.com/knadh/koanf/v2 v2.3.3 // indirect
github.com/mattn/go-runewidth v0.0.20 // indirect
github.com/mattn/go-sqlite3 v1.14.34
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.1 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/sys v0.42.0 // indirect
)
53 changes: 49 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,18 @@ github.com/codeshelldev/gotl/pkg/templating v0.0.16 h1:0dl/NEApCtlm4kyEscQPknx4D
github.com/codeshelldev/gotl/pkg/templating v0.0.16/go.mod h1:MHM4ouEsLNKXRYO+fS9qqpS1SFlL4Z6Q/0kxtS+auLk=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo=
github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
github.com/knadh/koanf/parsers/yaml v1.1.0 h1:3ltfm9ljprAHt4jxgeYLlFPmUaunuCgu1yILuTXRdM4=
Expand All @@ -46,16 +52,20 @@ github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.20 h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ=
github.com/mattn/go-runewidth v0.0.20/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk=
github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
Expand All @@ -66,12 +76,47 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.32.0 h1:hjG66bI/kqIPX1b2yT6fr/jt+QedtP2fqojG2VrFuVw=
modernc.org/ccgo/v4 v4.32.0/go.mod h1:6F08EBCx5uQc38kMGl+0Nm0oWczoo1c7cgpzEry7Uc0=
modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/gc/v3 v3.1.2 h1:ZtDCnhonXSZexk/AYsegNRV1lJGgaNZJuKjJSWKyEqo=
modernc.org/gc/v3 v3.1.2/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.70.0 h1:U58NawXqXbgpZ/dcdS9kMshu08aiA6b7gusEusqzNkw=
modernc.org/libc v1.70.0/go.mod h1:OVmxFGP1CI/Z4L3E0Q3Mf1PDE0BucwMkcXjjLntvHJo=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.47.0 h1:R1XyaNpoW4Et9yly+I2EeX7pBza/w+pmYee/0HJDyKk=
modernc.org/sqlite v1.47.0/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
14 changes: 14 additions & 0 deletions internals/config/structure/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ type Templating struct {
}

type Scheduling struct {
// Enabled is needed because this isn't a data-driven setting, but rather a toggle
Enabled bool `koanf:"enabled"`
MaxHorizon t.Opt[g.TimeDuration] `koanf:"maxhorizon"`
}
Expand All @@ -113,6 +114,19 @@ type ACCESS struct {
IP_FILTER t.Opt[IPFilter] `koanf:"ipfilter"`
TRUSTED_IPS t.Opt[[]g.IPOrNet] `koanf:"trustedips"`
TRUSTED_PROXIES t.Opt[[]g.IPOrNet] `koanf:"trustedproxies"`
CORS t.Opt[Cors] `koanf:"cors"`
}

type Cors struct {
Origins []Origin `koanf:"origins"`
Methods t.Opt[[]string] `koanf:"methods"`
Headers t.Opt[[]string] `koanf:"headers"`
}

type Origin struct {
URL g.URL `koanf:"url"`
Methods t.Opt[[]string] `koanf:"methods"`
Headers t.Opt[[]string] `koanf:"headers"`
}

type FieldPolicies = *t.Comp[c.RFieldPolicies, c.FieldPolicies]
Expand Down
8 changes: 6 additions & 2 deletions internals/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import (
"bytes"
"database/sql"
"encoding/gob"
"os"
"path/filepath"

_ "embed"

"github.com/codeshelldev/gotl/pkg/logger"
"github.com/codeshelldev/secured-signal-api/internals/config"
_ "github.com/mattn/go-sqlite3"
_ "modernc.org/sqlite"
)

var db *sql.DB
Expand All @@ -20,7 +22,9 @@ var schema string
func Init() {
var err error

db, err = sql.Open("sqlite3", config.ENV.DB_PATH)
os.MkdirAll(filepath.Dir(config.ENV.DB_PATH), 0755)

db, err = sql.Open("sqlite", config.ENV.DB_PATH)

if err != nil {
logger.Fatal("Error opening database: ", err.Error())
Expand Down
12 changes: 12 additions & 0 deletions internals/proxy/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,16 @@ func WriteError(w http.ResponseWriter, status int, msg string) {

w.WriteHeader(status)
res.Write(w)
}

func AddResponseHook(req *http.Request, hook func(res *http.Response) error) *http.Request {
hooks := GetResponseHooks(req)

hooks = append(hooks, hook)

return SetContext(req, ResponseHooksKey, hooks)
}

func GetResponseHooks(req *http.Request) []func(*http.Response) error {
return GetContext[[]func(*http.Response) error](req, ResponseHooksKey)
}
Loading
Loading