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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ log.Fatalf(...) // Fatal level - program will panic/exit

// for http servers there is also
// access log type including user-agent, forwarded ip/proto (behind load balancer case),
// TLS crypto used
// TLS crypto used and CN of peer certificate if any.
log.LogRequest(r, "some info")
```

Expand Down
12 changes: 9 additions & 3 deletions http_logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,21 @@ import (
"net/http"
)

// TLSInfo returns " https <cipher suite>" if the request is using TLS, or "" otherwise.
// TLSInfo returns ' https <cipher suite> "<peer CN>"' if the request is using TLS
// (and ' "<peer CN>"' part if mtls / a peer certificate is present) or "" otherwise.
func TLSInfo(r *http.Request) string {
if r.TLS == nil {
return ""
}
return fmt.Sprintf(" https %s", tls.CipherSuiteName(r.TLS.CipherSuite))
cliCert := ""
if len(r.TLS.PeerCertificates) > 0 {
cliCert = fmt.Sprintf(" %q", r.TLS.PeerCertificates[0].Subject)
}
return fmt.Sprintf(" https %s%s", tls.CipherSuiteName(r.TLS.CipherSuite), cliCert)
}

// LogRequest logs the incoming request, including headers when loglevel is verbose.
// LogRequest logs the incoming request, TLSInfo,
// including headers when loglevel is verbose.
//
//nolint:revive
func LogRequest(r *http.Request, msg string) {
Expand Down
7 changes: 5 additions & 2 deletions http_logging_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"bufio"
"bytes"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"net/http"
"testing"
)
Expand All @@ -17,14 +19,15 @@ func TestLogRequest(t *testing.T) {
SetOutput(w)
SetFlags(0) // remove timestamps
h := http.Header{"foo": []string{"bar"}}
r := &http.Request{TLS: &tls.ConnectionState{}, Header: h}
cert := &x509.Certificate{Subject: pkix.Name{CommonName: "x\nyz"}} // make sure special chars are escaped
r := &http.Request{TLS: &tls.ConnectionState{PeerCertificates: []*x509.Certificate{cert}}, Header: h}
LogRequest(r, "test1")
r.TLS = nil
r.Header = nil
LogRequest(r, "test2")
w.Flush()
actual := b.String()
expected := "test1: <nil> () \"\" https 0x0000\nHeader Host: \nHeader foo: bar\n" +
expected := "test1: <nil> () \"\" https 0x0000 \"CN=x\\nyz\"\nHeader Host: \nHeader foo: bar\n" +
"test2: <nil> () \"\"\nHeader Host: \n"
if actual != expected {
t.Errorf("unexpected:\n%q\nvs:\n%q\n", actual, expected)
Expand Down