Skip to content

Commit

Permalink
Add RealIPHeaderName option
Browse files Browse the repository at this point in the history
  • Loading branch information
janos committed May 2, 2022
1 parent 8c141ac commit 94401d4
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 18 deletions.
2 changes: 2 additions & 0 deletions cmd/compromised/config/compromised.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type CompromisedOptions struct {
Listen string `json:"listen" yaml:"listen" envconfig:"LISTEN"`
ListenInstrumentation string `json:"listen-instrumentation" yaml:"listen-instrumentation" envconfig:"LISTEN_INSTRUMENTATION"`
Headers map[string]string `json:"headers" yaml:"headers" envconfig:"HEADERS"`
RealIPHeaderName string `json:"real-ip-header-name" yaml:"real-ip-header-name" envconfig:"REAL_IP_HEADER_NAME"`
// Passwords
PasswordsDB string `json:"passwords-db" yaml:"passwords-db" envconfig:"PASSWORDS_DB"`
// Logging
Expand Down Expand Up @@ -48,6 +49,7 @@ func NewCompromisedOptions() *CompromisedOptions {
"Server": Name + "/" + compromised.Version(),
"X-Frame-Options": "SAMEORIGIN",
},
RealIPHeaderName: "X-Real-IP",
PasswordsDB: "",
LogDir: "",
LogLevel: logging.DEBUG,
Expand Down
1 change: 1 addition & 0 deletions cmd/compromised/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ Refer to https://resenje.org/compromised documentation.`)
apiHandler, err := api.New(api.Options{
Version: compromised.Version(),
Headers: options.Headers,
RealIPHeaderName: options.RealIPHeaderName,
Logger: logger,
AccessLogger: accessLogger,
RecoveryService: recoveryService,
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module resenje.org/compromised
go 1.18

require (
github.com/felixge/httpsnoop v1.0.1
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
github.com/prometheus/client_golang v1.12.1
Expand All @@ -18,7 +19,6 @@ require (
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/felixge/httpsnoop v1.0.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/kelseyhightower/envconfig v1.4.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
Expand Down
54 changes: 41 additions & 13 deletions pkg/api/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,53 @@ package api

import (
"net/http"
"time"
"strings"

"github.com/felixge/httpsnoop"
"resenje.org/jsonhttp"
"resenje.org/logging"
"resenje.org/web"
accessLog "resenje.org/web/log/access"
"resenje.org/web/recovery"
)

func (s *server) accessLogHandler(h http.Handler) http.Handler {
return accessLog.NewHandler(h, s.AccessLogger)
func (s *server) accessLogAndMetricsHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
s.metrics.PageviewCount.Inc()
m := httpsnoop.CaptureMetrics(h, w, r)
referrer := r.Referer()
if referrer == "" {
referrer = "-"
}
userAgent := r.UserAgent()
if userAgent == "" {
userAgent = "-"
}
ips := []string{}
if v := r.Header.Get(s.RealIPHeaderName); v != "" {
ips = append(ips, v)
}
xips := "-"
if len(ips) > 0 {
xips = strings.Join(ips, ", ")
}
status := m.Code
var level logging.Level
switch {
case status >= 500:
level = logging.ERROR
case status >= 400:
level = logging.WARNING
case status >= 300:
level = logging.INFO
case status >= 200:
level = logging.INFO
default:
level = logging.DEBUG
}
s.AccessLogger.Logf(level, "%s \"%s\" \"%v %s %v\" %d %d %f \"%s\" \"%s\"", r.RemoteAddr, xips, r.Method, r.RequestURI, r.Proto, status, m.Written, m.Duration.Seconds(), referrer, userAgent)

s.metrics.ResponseDuration.Observe(m.Duration.Seconds())
})
}

func (s *server) jsonRecoveryHandler(h http.Handler) http.Handler {
Expand All @@ -27,15 +64,6 @@ func (s *server) jsonRecoveryHandler(h http.Handler) http.Handler {
)
}

func (s *server) pageviewMetricsHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
s.metrics.PageviewCount.Inc()
h.ServeHTTP(w, r)
s.metrics.ResponseDuration.Observe(time.Since(start).Seconds())
})
}

func jsonMaxBodyBytesHandler(h http.Handler) http.Handler {
return web.MaxBodyBytesHandler{
Handler: h,
Expand Down
3 changes: 1 addition & 2 deletions pkg/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func newRouter(s *server) http.Handler {
return web.ChainHandlers(
handlers.CompressHandler,
s.jsonRecoveryHandler,
s.accessLogHandler,
s.accessLogAndMetricsHandler,
func(h http.Handler) http.Handler {
return web.NewSetHeadersHandler(h, s.Headers)
},
Expand All @@ -51,7 +51,6 @@ func newV1Router(s *server) http.Handler {

return web.ChainHandlers(
jsonMaxBodyBytesHandler,
s.pageviewMetricsHandler,
web.NoCacheHeadersHandler,
web.FinalHandler(r),
)
Expand Down
5 changes: 3 additions & 2 deletions pkg/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ type server struct {

// Options structure contains optional properties for the Handler.
type Options struct {
Version string
Headers map[string]string
Version string
Headers map[string]string
RealIPHeaderName string

Logger *logging.Logger
AccessLogger *logging.Logger
Expand Down

0 comments on commit 94401d4

Please sign in to comment.