116 lines
2.5 KiB
Go
116 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/letsencrypt/boulder/akamai"
|
|
"github.com/letsencrypt/boulder/cmd"
|
|
)
|
|
|
|
func main() {
|
|
listenAddr := flag.String("listen", "localhost:6789", "Address to listen on")
|
|
secret := flag.String("secret", "", "Akamai client secret")
|
|
flag.Parse()
|
|
|
|
v3Purges := [][]string{}
|
|
mu := sync.Mutex{}
|
|
|
|
http.HandleFunc("/debug/get-purges", func(w http.ResponseWriter, r *http.Request) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
body, err := json.Marshal(struct {
|
|
V3 [][]string
|
|
}{V3: v3Purges})
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.Write(body)
|
|
})
|
|
|
|
http.HandleFunc("/debug/reset-purges", func(w http.ResponseWriter, r *http.Request) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
v3Purges = [][]string{}
|
|
w.WriteHeader(http.StatusOK)
|
|
})
|
|
|
|
http.HandleFunc("/ccu/", func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
fmt.Println("Wrong method:", r.Method)
|
|
return
|
|
}
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
var purgeRequest struct {
|
|
Objects []string `json:"objects"`
|
|
}
|
|
body, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
fmt.Println("Can't read body:", err)
|
|
return
|
|
}
|
|
if err = akamai.CheckSignature(*secret, "http://"+*listenAddr, r, body); err != nil {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
fmt.Println("Bad signature:", err)
|
|
return
|
|
}
|
|
if err = json.Unmarshal(body, &purgeRequest); err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
fmt.Println("Can't unmarshal:", err)
|
|
return
|
|
}
|
|
if len(purgeRequest.Objects) == 0 {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
fmt.Println("Bad parameters:", purgeRequest)
|
|
return
|
|
}
|
|
v3Purges = append(v3Purges, purgeRequest.Objects)
|
|
|
|
respObj := struct {
|
|
PurgeID string
|
|
HTTPStatus int
|
|
EstimatedSeconds int
|
|
}{
|
|
PurgeID: "welcome-to-the-purge",
|
|
HTTPStatus: http.StatusCreated,
|
|
EstimatedSeconds: 153,
|
|
}
|
|
w.WriteHeader(http.StatusCreated)
|
|
resp, err := json.Marshal(respObj)
|
|
if err != nil {
|
|
return
|
|
}
|
|
w.Write(resp)
|
|
})
|
|
|
|
s := http.Server{
|
|
ReadTimeout: 30 * time.Second,
|
|
Addr: *listenAddr,
|
|
}
|
|
|
|
go func() {
|
|
err := s.ListenAndServe()
|
|
if err != nil && err != http.ErrServerClosed {
|
|
cmd.FailOnError(err, "Running TLS server")
|
|
}
|
|
}()
|
|
|
|
defer func() {
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
defer cancel()
|
|
_ = s.Shutdown(ctx)
|
|
}()
|
|
|
|
cmd.WaitForSignal()
|
|
}
|