• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nagayon-935 / Conduit / 23599548151

26 Mar 2026 02:24PM UTC coverage: 69.507% (+9.2%) from 60.314%
23599548151

push

github

nagayon-935
test: increase coverage for connlog, tunnel, and api packages

620 of 892 relevant lines covered (69.51%)

8.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.91
/internal/api/handler.go
1
package api
2

3
import (
4
        "encoding/json"
5
        "log/slog"
6
        "net/http"
7

8
        "github.com/gorilla/websocket"
9
        "github.com/nagayon-935/conduit/internal/config"
10
        "github.com/nagayon-935/conduit/internal/connlog"
11
        "github.com/nagayon-935/conduit/internal/session"
12
        "github.com/nagayon-935/conduit/internal/sshconn"
13
        "github.com/nagayon-935/conduit/internal/vault"
14
)
15

16
const (
17
        contentTypeJSON    = "application/json"
18
        wsReadBufferSize   = 4096
19
        wsWriteBufferSize  = 4096
20
)
21

22
// Handler is the root HTTP handler for the Conduit API.
23
type Handler struct {
24
        config   *config.Config
25
        sessions *session.Manager
26
        vault    vault.VaultClient
27
        dialer   sshconn.SSHDialer
28
        upgrader websocket.Upgrader
29
        logs     *connlog.Store
30
}
31

32
// NewHandler constructs a Handler wiring together all application dependencies.
33
func NewHandler(cfg *config.Config, sm *session.Manager, vc vault.VaultClient, d sshconn.SSHDialer, ls *connlog.Store) *Handler {
18✔
34
        return &Handler{
18✔
35
                config:   cfg,
18✔
36
                sessions: sm,
18✔
37
                vault:    vc,
18✔
38
                dialer:   d,
18✔
39
                logs:     ls,
18✔
40
                upgrader: websocket.Upgrader{
18✔
41
                        // Allow all origins for development; tighten for production.
18✔
42
                        CheckOrigin:     func(r *http.Request) bool { return true },
20✔
43
                        ReadBufferSize:  wsReadBufferSize,
44
                        WriteBufferSize: wsWriteBufferSize,
45
                },
46
        }
47
}
48

49
// Routes registers all API routes and returns the root http.Handler.
50
func (h *Handler) Routes() http.Handler {
18✔
51
        mux := http.NewServeMux()
18✔
52
        mux.HandleFunc("POST /api/connect", h.handleConnect)
18✔
53
        mux.HandleFunc("GET /ws", h.handleTerminal)
18✔
54
        mux.HandleFunc("GET /healthz", h.handleHealth)
18✔
55
        mux.HandleFunc("GET /api/sessions", h.handleListSessions)
18✔
56
        mux.HandleFunc("DELETE /api/sessions/{token}", h.handleKillSession)
18✔
57
        mux.HandleFunc("GET /api/logs", h.handleListLogs)
18✔
58
        return corsMiddleware(loggingMiddleware(mux))
18✔
59
}
18✔
60

61
// handleHealth is a simple liveness probe.
62
func (h *Handler) handleHealth(w http.ResponseWriter, r *http.Request) {
2✔
63
        w.Header().Set("Content-Type", contentTypeJSON)
2✔
64
        w.WriteHeader(http.StatusOK)
2✔
65
        _, _ = w.Write([]byte(`{"status":"ok"}`))
2✔
66
}
2✔
67

68
// apiError writes a structured JSON error response.
69
func apiError(w http.ResponseWriter, code int, message, errCode string) {
9✔
70
        w.Header().Set("Content-Type", contentTypeJSON)
9✔
71
        w.WriteHeader(code)
9✔
72
        body, _ := json.Marshal(map[string]string{
9✔
73
                "error": message,
9✔
74
                "code":  errCode,
9✔
75
        })
9✔
76
        _, _ = w.Write(body)
9✔
77
}
9✔
78

79
// writeJSON marshals v and writes it as a JSON response.
80
func writeJSON(w http.ResponseWriter, code int, v any) {
7✔
81
        w.Header().Set("Content-Type", contentTypeJSON)
7✔
82
        w.WriteHeader(code)
7✔
83
        if err := json.NewEncoder(w).Encode(v); err != nil {
7✔
84
                slog.Error("writeJSON: encode failed", "error", err)
×
85
        }
×
86
}
87

88
// corsMiddleware adds permissive CORS headers (suitable for development).
89
func corsMiddleware(next http.Handler) http.Handler {
18✔
90
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
40✔
91
                w.Header().Set("Access-Control-Allow-Origin", "*")
22✔
92
                w.Header().Set("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS")
22✔
93
                w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
22✔
94
                if r.Method == http.MethodOptions {
22✔
95
                        w.WriteHeader(http.StatusNoContent)
×
96
                        return
×
97
                }
×
98
                next.ServeHTTP(w, r)
22✔
99
        })
100
}
101

102
// loggingMiddleware logs each incoming HTTP request.
103
func loggingMiddleware(next http.Handler) http.Handler {
18✔
104
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
40✔
105
                slog.Info("http request", "method", r.Method, "path", r.URL.Path, "remote_addr", r.RemoteAddr)
22✔
106
                next.ServeHTTP(w, r)
22✔
107
        })
22✔
108
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc