Added access log to server and modified mock-fts to use it
This commit is contained in:
1 parent
2490519c2b
commit
02e3d910a2
10 files changed
+389
-29
No files matched your search
@@ -5,9 +5,13 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestLogField(t *testing.T) {
|
||||
@@ -152,3 +156,96 @@ func TestAccessLog(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// A handler behind AccessLog can hijack the connection through
|
||||
// http.ResponseController, as a WebSocket upgrade does, and the request is
|
||||
// still logged.
|
||||
func TestAccessLogHijack(t *testing.T) {
|
||||
var buffer lockedBuffer
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
conn, readWriter, err := http.NewResponseController(w).Hijack()
|
||||
if err != nil {
|
||||
t.Errorf("hijack: %v", err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
readWriter.WriteString("HTTP/1.1 204 No Content\r\n\r\n")
|
||||
readWriter.Flush()
|
||||
})
|
||||
server := httptest.NewServer(AccessLog(log.New(&buffer, "", 0), true, handler))
|
||||
defer server.Close()
|
||||
|
||||
res, err := http.Get(server.URL + "/hijacked")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res.Body.Close()
|
||||
if res.StatusCode != http.StatusNoContent {
|
||||
t.Errorf("status = %d; want 204 from the hijacked connection", res.StatusCode)
|
||||
}
|
||||
|
||||
// The line is written when the handler returns, after the client has its
|
||||
// response.
|
||||
deadline := time.Now().Add(time.Second)
|
||||
for !strings.Contains(buffer.String(), `"GET /hijacked HTTP/1.1"`) {
|
||||
if time.Now().After(deadline) {
|
||||
t.Fatalf("request not logged: %q", buffer.String())
|
||||
}
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
// lockedBuffer is a bytes.Buffer safe to write from the server's goroutine
|
||||
// while the test reads it.
|
||||
type lockedBuffer struct {
|
||||
mu sync.Mutex
|
||||
buffer bytes.Buffer
|
||||
}
|
||||
|
||||
func (b *lockedBuffer) Write(data []byte) (int, error) {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
return b.buffer.Write(data)
|
||||
}
|
||||
|
||||
func (b *lockedBuffer) String() string {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
return b.buffer.String()
|
||||
}
|
||||
|
||||
// An access log file is created if needed and appended to; "-" is stdout.
|
||||
func TestOpenAccessLog(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "access.log")
|
||||
os.WriteFile(path, []byte("earlier line\n"), 0o600)
|
||||
|
||||
logger, closeLog, err := OpenAccessLog(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
logger.Print("new line")
|
||||
if err := closeLog(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(filepath.Clean(path))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := string(data); got != "earlier line\nnew line\n" {
|
||||
t.Errorf("access log = %q; want the new line appended", got)
|
||||
}
|
||||
|
||||
logger, closeLog, err = OpenAccessLog("-")
|
||||
if err != nil || logger.Writer() != os.Stdout {
|
||||
t.Errorf("OpenAccessLog(-) = %v, %v; want stdout", logger, err)
|
||||
}
|
||||
if err := closeLog(); err != nil {
|
||||
t.Errorf("closing stdout's access log: %v", err)
|
||||
}
|
||||
|
||||
_, _, err = OpenAccessLog(filepath.Join(t.TempDir(), "missing", "a.log"))
|
||||
if err == nil || !strings.Contains(err.Error(), "opening access log") {
|
||||
t.Errorf("missing directory: %v; want an error", err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user