testing and linting and linter fixes
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
23d705b93a
commit
997514292a
|
@ -6,4 +6,6 @@ steps:
|
||||||
- name: test
|
- name: test
|
||||||
image: golang
|
image: golang
|
||||||
commands:
|
commands:
|
||||||
- go test -v ./...
|
- go test -race -v ./...
|
||||||
|
- name: lint
|
||||||
|
image: rancher/drone-golangci-lint:latest
|
||||||
|
|
|
@ -116,9 +116,7 @@ func RunCGI(
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptName := req.Path[:len(req.Path)-infoLen]
|
scriptName := req.Path[:len(req.Path)-infoLen]
|
||||||
if strings.HasSuffix(scriptName, "/") {
|
scriptName = strings.TrimSuffix(scriptName, "/")
|
||||||
scriptName = scriptName[:len(scriptName)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := exec.CommandContext(ctx, "./"+basename)
|
cmd := exec.CommandContext(ctx, "./"+basename)
|
||||||
cmd.Env = prepareCGIEnv(ctx, req, scriptName, pathInfo)
|
cmd.Env = prepareCGIEnv(ctx, req, scriptName, pathInfo)
|
||||||
|
|
|
@ -38,7 +38,9 @@ func TestIdentify(t *testing.T) {
|
||||||
leafCert, err := x509.ParseCertificate(clientCert.Certificate[0])
|
leafCert, err := x509.ParseCertificate(clientCert.Certificate[0])
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
go server.Serve()
|
go func() {
|
||||||
|
_ = server.Serve()
|
||||||
|
}()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
requestPath(t, client, server, "/")
|
requestPath(t, client, server, "/")
|
||||||
|
@ -75,7 +77,9 @@ func TestRequiredAuth(t *testing.T) {
|
||||||
gus.FallthroughHandler(handler1, handler2),
|
gus.FallthroughHandler(handler1, handler2),
|
||||||
)
|
)
|
||||||
|
|
||||||
go server.Serve()
|
go func() {
|
||||||
|
_ = server.Serve()
|
||||||
|
}()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
requestPath(t, client, server, "/one")
|
requestPath(t, client, server, "/one")
|
||||||
|
@ -113,7 +117,9 @@ func TestOptionalAuth(t *testing.T) {
|
||||||
handler,
|
handler,
|
||||||
)
|
)
|
||||||
|
|
||||||
go server.Serve()
|
go func() {
|
||||||
|
_ = server.Serve()
|
||||||
|
}()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
requestPath(t, client, server, "/one")
|
requestPath(t, client, server, "/one")
|
||||||
|
|
|
@ -54,7 +54,9 @@ func TestGeminiAuth(t *testing.T) {
|
||||||
|
|
||||||
authlessClient, _ := clientFor(t, server, "", "")
|
authlessClient, _ := clientFor(t, server, "", "")
|
||||||
|
|
||||||
go server.Serve()
|
go func() {
|
||||||
|
_ = server.Serve()
|
||||||
|
}()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
resp := requestPath(t, authClient, server, "/one")
|
resp := requestPath(t, authClient, server, "/one")
|
||||||
|
@ -94,7 +96,9 @@ func TestGeminiOptionalAuth(t *testing.T) {
|
||||||
)
|
)
|
||||||
authlessClient, _ := clientFor(t, server, "", "")
|
authlessClient, _ := clientFor(t, server, "", "")
|
||||||
|
|
||||||
go server.Serve()
|
go func() {
|
||||||
|
_ = server.Serve()
|
||||||
|
}()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
resp := requestPath(t, authClient, server, "/one")
|
resp := requestPath(t, authClient, server, "/one")
|
||||||
|
|
|
@ -27,7 +27,9 @@ func TestRoundTrip(t *testing.T) {
|
||||||
server, err := gemini.NewServer(context.Background(), nil, tlsConf, "tcp", "127.0.0.1:0", handler)
|
server, err := gemini.NewServer(context.Background(), nil, tlsConf, "tcp", "127.0.0.1:0", handler)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
go server.Serve()
|
go func() {
|
||||||
|
_ = server.Serve()
|
||||||
|
}()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
u, err := url.Parse(fmt.Sprintf("gemini://%s/test", server.Address()))
|
u, err := url.Parse(fmt.Sprintf("gemini://%s/test", server.Address()))
|
||||||
|
@ -70,7 +72,9 @@ func TestTitanRequest(t *testing.T) {
|
||||||
server, err := gemini.NewServer(context.Background(), nil, tlsConf, "tcp", "127.0.0.1:0", handler)
|
server, err := gemini.NewServer(context.Background(), nil, tlsConf, "tcp", "127.0.0.1:0", handler)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
go server.Serve()
|
go func() {
|
||||||
|
_ = server.Serve()
|
||||||
|
}()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
conn, err := tls.Dial(server.Network(), server.Address(), testClientTLS())
|
conn, err := tls.Dial(server.Network(), server.Address(), testClientTLS())
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -15,11 +16,13 @@ import (
|
||||||
"tildegit.org/tjp/gus/logging"
|
"tildegit.org/tjp/gus/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type titanRequestBodyKey struct{}
|
||||||
|
|
||||||
// TitanRequestBody is the key set in a handler's context for titan requests.
|
// TitanRequestBody is the key set in a handler's context for titan requests.
|
||||||
//
|
//
|
||||||
// When this key is present in the context (request.URL.Scheme will be "titan"), the
|
// When this key is present in the context (request.URL.Scheme will be "titan"), the
|
||||||
// corresponding value is a *bufio.Reader from which the request body can be read.
|
// corresponding value is a *bufio.Reader from which the request body can be read.
|
||||||
const TitanRequestBody = "titan_request_body"
|
var TitanRequestBody = titanRequestBodyKey{}
|
||||||
|
|
||||||
type server struct {
|
type server struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
@ -70,7 +73,7 @@ func NewServer(
|
||||||
// but be aware that Close() must still be called in that case to avoid
|
// but be aware that Close() must still be called in that case to avoid
|
||||||
// dangling goroutines.
|
// dangling goroutines.
|
||||||
//
|
//
|
||||||
// On titan protocol requests, it sets a key/value pair in the context. The
|
// On titan protocol requests it sets a key/value pair in the context. The
|
||||||
// key is TitanRequestBody, and the value is a *bufio.Reader from which the
|
// key is TitanRequestBody, and the value is a *bufio.Reader from which the
|
||||||
// request body can be read.
|
// request body can be read.
|
||||||
func (s *server) Serve() error {
|
func (s *server) Serve() error {
|
||||||
|
@ -88,7 +91,7 @@ func (s *server) Serve() error {
|
||||||
if s.Closed() {
|
if s.Closed() {
|
||||||
err = nil
|
err = nil
|
||||||
} else {
|
} else {
|
||||||
s.errorLog.Log("msg", "accept_error", "error", err)
|
_ = s.errorLog.Log("msg", "accept error", "error", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
@ -135,7 +138,7 @@ func (s *server) handleConn(conn net.Conn) {
|
||||||
} else {
|
} else {
|
||||||
req.Server = s
|
req.Server = s
|
||||||
req.RemoteAddr = conn.RemoteAddr()
|
req.RemoteAddr = conn.RemoteAddr()
|
||||||
if tlsconn, ok := conn.(*tls.Conn); req != nil && ok {
|
if tlsconn, ok := conn.(*tls.Conn); ok {
|
||||||
state := tlsconn.ConnectionState()
|
state := tlsconn.ConnectionState()
|
||||||
req.TLSState = &state
|
req.TLSState = &state
|
||||||
}
|
}
|
||||||
|
@ -146,12 +149,20 @@ func (s *server) handleConn(conn net.Conn) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ctx = context.WithValue(
|
ctx = context.WithValue(
|
||||||
ctx,
|
ctx,
|
||||||
"titan_request_body",
|
TitanRequestBody,
|
||||||
io.LimitReader(buf, int64(len)),
|
io.LimitReader(buf, int64(len)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
err := fmt.Errorf("%s", r)
|
||||||
|
_ = s.errorLog.Log("msg", "panic in handler", "err", err)
|
||||||
|
_, _ = io.Copy(conn, NewResponseReader(Failure(err)))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
response = s.handler(ctx, req)
|
response = s.handler(ctx, req)
|
||||||
if response == nil {
|
if response == nil {
|
||||||
response = NotFound("Resource does not exist.")
|
response = NotFound("Resource does not exist.")
|
||||||
|
|
|
@ -3,6 +3,7 @@ package logging
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -12,18 +13,9 @@ import (
|
||||||
func LogRequests(logger Logger) gus.Middleware {
|
func LogRequests(logger Logger) gus.Middleware {
|
||||||
return func(inner gus.Handler) gus.Handler {
|
return func(inner gus.Handler) gus.Handler {
|
||||||
return func(ctx context.Context, request *gus.Request) *gus.Response {
|
return func(ctx context.Context, request *gus.Request) *gus.Response {
|
||||||
start := time.Now()
|
|
||||||
|
|
||||||
response := inner(ctx, request)
|
response := inner(ctx, request)
|
||||||
if response != nil {
|
if response != nil {
|
||||||
body := loggedResponseBody{
|
response.Body = loggingBody(logger, request, response)
|
||||||
request: request,
|
|
||||||
response: response,
|
|
||||||
body: response.Body,
|
|
||||||
start: start,
|
|
||||||
logger: logger,
|
|
||||||
}
|
|
||||||
response.Body = &body
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
@ -42,23 +34,6 @@ type loggedResponseBody struct {
|
||||||
logger Logger
|
logger Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func loggingBody(logger Logger, request *gus.Request, response *gus.Response) io.Reader {
|
|
||||||
body := &loggedResponseBody{
|
|
||||||
request: request,
|
|
||||||
response: response,
|
|
||||||
body: response.Body,
|
|
||||||
start: time.Now(),
|
|
||||||
written: 0,
|
|
||||||
logger: logger,
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := response.Body.(io.WriterTo); ok {
|
|
||||||
return loggedWriteToResponseBody{body}
|
|
||||||
}
|
|
||||||
|
|
||||||
return body
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lr *loggedResponseBody) log() {
|
func (lr *loggedResponseBody) log() {
|
||||||
end := time.Now()
|
end := time.Now()
|
||||||
_ = lr.logger.Log(
|
_ = lr.logger.Log(
|
||||||
|
@ -98,6 +73,7 @@ type loggedWriteToResponseBody struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lwtr loggedWriteToResponseBody) WriteTo(dst io.Writer) (int64, error) {
|
func (lwtr loggedWriteToResponseBody) WriteTo(dst io.Writer) (int64, error) {
|
||||||
|
fmt.Println("lwtrb.WriteTo()")
|
||||||
n, err := lwtr.body.(io.WriterTo).WriteTo(dst)
|
n, err := lwtr.body.(io.WriterTo).WriteTo(dst)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
lwtr.written += int(n)
|
lwtr.written += int(n)
|
||||||
|
@ -105,3 +81,20 @@ func (lwtr loggedWriteToResponseBody) WriteTo(dst io.Writer) (int64, error) {
|
||||||
}
|
}
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loggingBody(logger Logger, request *gus.Request, response *gus.Response) io.Reader {
|
||||||
|
body := &loggedResponseBody{
|
||||||
|
request: request,
|
||||||
|
response: response,
|
||||||
|
body: response.Body,
|
||||||
|
start: time.Now(),
|
||||||
|
written: 0,
|
||||||
|
logger: logger,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := response.Body.(io.WriterTo); ok {
|
||||||
|
return loggedWriteToResponseBody{body}
|
||||||
|
}
|
||||||
|
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
|
Reference in New Issue