The command is now `sww waf`, and the package is `internal/waf`. Types, functions, files, tests, comments, docs, the Dockerfile, the runit script, `script/`, compose examples, the log field `waf_line` and the `X-From-Waf` test header follow. No behaviour changes, and no setting changes name: rproxy already finds the waf through `SWRP_WAF_BACKEND`. Done with one `sed -i` (Discriminator and DISCRIMINATOR to WAF, discriminator to waf) over the files `git grep -i discriminator` listed, as sneak allowed for this rename, then `git mv` for the package and files. By hand afterwards: the header's spelling, which the linter requires, and the padding after `waf` in `sww`'s usage text. Model: opus-5-5
This commit was merged in pull request #319.
This commit is contained in:
1 parent
ad36dd1775
commit
f7e3190654
89 files changed
+1454
-1489
No files matched your search
+28
-28
@@ -1,10 +1,10 @@
|
||||
// Package rproxy is the reverse proxy in front of one app that asks discriminator
|
||||
// about each request. It passes a request discriminator allows to the app and the
|
||||
// Package rproxy is the reverse proxy in front of one app that asks waf
|
||||
// about each request. It passes a request waf allows to the app and the
|
||||
// app's answer back, within the size and time limits. Any other answer from
|
||||
// discriminator goes to the visitor as discriminator gave it. SWRP_DEFAULT_DISPOSITION
|
||||
// decides only when discriminator cannot be connected to, does not answer at all, or
|
||||
// waf goes to the visitor as waf gave it. SWRP_DEFAULT_DISPOSITION
|
||||
// decides only when waf cannot be connected to, does not answer at all, or
|
||||
// does not answer within SWRP_TIMEOUT_MS. rproxy itself refuses a request with a
|
||||
// method it does not pass on, or one it cannot put to discriminator as the visitor
|
||||
// method it does not pass on, or one it cannot put to waf as the visitor
|
||||
// sent it. It keeps nothing between requests and never touches disk. "rproxy" in
|
||||
// SPEC.md says what it does.
|
||||
package rproxy
|
||||
@@ -22,10 +22,10 @@ import (
|
||||
"time"
|
||||
|
||||
"sneak.berlin/go/smallwebwaf/internal/config"
|
||||
"sneak.berlin/go/smallwebwaf/internal/discriminator"
|
||||
"sneak.berlin/go/smallwebwaf/internal/waf"
|
||||
)
|
||||
|
||||
// How rproxy keeps connections to the app and to discriminator open between
|
||||
// How rproxy keeps connections to the app and to waf open between
|
||||
// requests.
|
||||
const (
|
||||
idleConns = 100
|
||||
@@ -80,14 +80,14 @@ func New(params Params) *Server {
|
||||
backend := params.Config.WAFBackend
|
||||
errorLog := slog.NewLogLogger(params.ProcessLog.Handler(), slog.LevelWarn)
|
||||
h := &handler{
|
||||
config: params.Config,
|
||||
requestLog: params.RequestLog,
|
||||
processLog: params.ProcessLog,
|
||||
errorLog: errorLog,
|
||||
transport: newTransport(),
|
||||
discriminatorTransport: newDiscriminatorTransport(),
|
||||
config: params.Config,
|
||||
requestLog: params.RequestLog,
|
||||
processLog: params.ProcessLog,
|
||||
errorLog: errorLog,
|
||||
transport: newTransport(),
|
||||
wafTransport: newWAFTransport(),
|
||||
reportURL: (&url.URL{
|
||||
Scheme: backend.Scheme, Host: backend.Host, Path: discriminator.ReportPath,
|
||||
Scheme: backend.Scheme, Host: backend.Host, Path: waf.ReportPath,
|
||||
}).String(),
|
||||
}
|
||||
|
||||
@@ -122,10 +122,10 @@ type handler struct {
|
||||
requestLog io.Writer
|
||||
processLog *slog.Logger
|
||||
errorLog *log.Logger
|
||||
// transport carries requests to the app, and discriminatorTransport questions and
|
||||
// reports to discriminator.
|
||||
transport http.RoundTripper
|
||||
discriminatorTransport http.RoundTripper
|
||||
// transport carries requests to the app, and wafTransport questions and
|
||||
// reports to waf.
|
||||
transport http.RoundTripper
|
||||
wafTransport http.RoundTripper
|
||||
// reportURL is where the reports go.
|
||||
reportURL string
|
||||
// reports waits for the reports being sent. reportsMu guards starting one
|
||||
@@ -147,11 +147,11 @@ func newTransport() *http.Transport {
|
||||
}
|
||||
}
|
||||
|
||||
// newDiscriminatorTransport returns what carries questions and reports to
|
||||
// discriminator. It speaks HTTP/1.1 only. Go's HTTP/2 client refuses to send
|
||||
// newWAFTransport returns what carries questions and reports to
|
||||
// waf. It speaks HTTP/1.1 only. Go's HTTP/2 client refuses to send
|
||||
// a visitor's Upgrade header, or a Connection header other than close or
|
||||
// keep-alive, and that would read as discriminator giving no answer.
|
||||
func newDiscriminatorTransport() *http.Transport {
|
||||
// keep-alive, and that would read as waf giving no answer.
|
||||
func newWAFTransport() *http.Transport {
|
||||
transport := newTransport()
|
||||
transport.Protocols = new(http.Protocols)
|
||||
transport.Protocols.SetHTTP1(true)
|
||||
@@ -160,15 +160,15 @@ func newDiscriminatorTransport() *http.Transport {
|
||||
}
|
||||
|
||||
// ServeHTTP handles one request: it answers the health check itself, refuses a
|
||||
// request with a method it does not pass on or one it cannot put to discriminator as
|
||||
// request with a method it does not pass on or one it cannot put to waf as
|
||||
// the visitor sent it, and for any other request reads the first part of the
|
||||
// body, asks discriminator, and does what the answer says. Once the answer has ended,
|
||||
// body, asks waf, and does what the answer says. Once the answer has ended,
|
||||
// it writes the request's log line and sends its report.
|
||||
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
rq := h.newRequest(w, r)
|
||||
defer rq.finish(r.Context())
|
||||
|
||||
if r.Method == http.MethodGet && r.URL.Path == discriminator.HealthPath {
|
||||
if r.Method == http.MethodGet && r.URL.Path == waf.HealthPath {
|
||||
rq.answerHealth()
|
||||
|
||||
return
|
||||
@@ -201,9 +201,9 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
rq.noteAnswer(answer)
|
||||
|
||||
switch rq.disposition {
|
||||
case discriminator.DispositionAllow:
|
||||
case waf.DispositionAllow:
|
||||
rq.passToApp(r.Context())
|
||||
case discriminator.DispositionClose:
|
||||
case waf.DispositionClose:
|
||||
// This panic has Go's server close the connection without an answer,
|
||||
// and log nothing; the deferred finish still runs.
|
||||
panic(http.ErrAbortHandler)
|
||||
@@ -213,7 +213,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// passToApp passes the request on to the app, unless a limit or its path keeps
|
||||
// it from the app. discriminator answers a path under ownEndpointPrefix itself, so
|
||||
// it from the app. waf answers a path under ownEndpointPrefix itself, so
|
||||
// such a request gets here only when SWRP_DEFAULT_DISPOSITION allowed it. ctx is the
|
||||
// request's own context.
|
||||
func (rq *request) passToApp(ctx context.Context) {
|
||||
|
||||
Reference in new issue
Block a user