···11+package handlers
22+33+import (
44+ "encoding/json"
55+ "log/slog"
66+ "net/http"
77+ "strconv"
88+ "time"
99+1010+ "github.com/eagleusb/proxycon/internal/types"
1111+)
1212+1313+// averageEndpoint is the handler function for `GET /average?start=<timestamp>&end=<timestamp>`
1414+func (h *HttpServer) averageEndpoint(w http.ResponseWriter, r *http.Request) {
1515+ startStr := r.URL.Query().Get("start")
1616+ endStr := r.URL.Query().Get("end")
1717+1818+ if startStr == "" || endStr == "" {
1919+ http.Error(w, "missing query parameters: start and end are required", http.StatusBadRequest)
2020+ return
2121+ }
2222+2323+ startTime, err := time.Parse(time.RFC3339, startStr)
2424+ if err != nil {
2525+ http.Error(w, "invalid start timestamp: must be RFC3339 format", http.StatusBadRequest)
2626+ return
2727+ }
2828+2929+ endTime, err := time.Parse(time.RFC3339, endStr)
3030+ if err != nil {
3131+ http.Error(w, "invalid end timestamp: must be RFC3339 format", http.StatusBadRequest)
3232+ return
3333+ }
3434+3535+ if startTime.After(endTime) {
3636+ http.Error(w, "start timestamp must be before end timestamp", http.StatusBadRequest)
3737+ return
3838+ }
3939+4040+ prices := h.datasource.GetPrices()
4141+4242+ var matched []types.Price
4343+ for _, p := range prices {
4444+ t, err := time.Parse(time.RFC3339, p.Timestamp)
4545+ if err != nil {
4646+ continue
4747+ }
4848+ if (t.Equal(startTime) || t.After(startTime)) && (t.Equal(endTime) || t.Before(endTime)) {
4949+ matched = append(matched, p)
5050+ }
5151+ }
5252+5353+ if len(matched) == 0 {
5454+ http.Error(w, "no prices found in the given range", http.StatusNotFound)
5555+ return
5656+ }
5757+5858+ entries := make([]types.Entry, len(matched))
5959+ var sum int64
6060+ for i, p := range matched {
6161+ val, _ := strconv.ParseInt(p.Price, 10, 64)
6262+ sum += val
6363+ entries[i] = types.Entry{
6464+ Amount: p.Price,
6565+ Timestamp: p.Timestamp,
6666+ }
6767+ }
6868+6969+ avg := sum / int64(len(matched))
7070+7171+ w.Header().Set("Content-Type", "application/json")
7272+ if err := json.NewEncoder(w).Encode(types.AverageResponse{
7373+ Start: matched[0].Timestamp,
7474+ End: matched[len(matched)-1].Timestamp,
7575+ Avg: strconv.FormatInt(avg, 10),
7676+ Data: entries,
7777+ }); err != nil {
7878+ slog.Error("encode average response", "error", err)
7979+ }
8080+}
+1-1
internal/handlers/list.go
···99 "github.com/eagleusb/proxycon/internal/types"
1010)
11111212-// listEndpoint is the handler function for `/list`
1212+// listEndpoint is the handler function for `GET /list`
1313func (h *HttpServer) listEndpoint(w http.ResponseWriter, r *http.Request) {
1414 cursor := 0
1515