92 lines
2.2 KiB
Go
92 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
)
|
|
|
|
type mergeRequest struct {
|
|
Name string `json:"name"`
|
|
URLs []string `json:"urls"`
|
|
MergeRequestID int64 `json:"mergeRequestID"`
|
|
TOrderHeaderID int64 `json:"T_OrderHeaderID"`
|
|
}
|
|
|
|
type mergeFunc func(urls []string) ([]byte, error)
|
|
|
|
type mergeHandler struct {
|
|
secret string
|
|
merge mergeFunc
|
|
}
|
|
|
|
func newMergeHandler(secret string, merge mergeFunc) http.Handler {
|
|
return &mergeHandler{secret: secret, merge: merge}
|
|
}
|
|
|
|
func (h *mergeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
writeError(w, http.StatusMethodNotAllowed, "method not allowed")
|
|
return
|
|
}
|
|
|
|
if r.Header.Get("X-Internal-Secret") != h.secret {
|
|
writeError(w, http.StatusUnauthorized, "unauthorized")
|
|
return
|
|
}
|
|
|
|
var req mergeRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
writeError(w, http.StatusBadRequest, "invalid request body")
|
|
return
|
|
}
|
|
|
|
if err := validateMergeRequest(&req); err != nil {
|
|
writeError(w, http.StatusUnprocessableEntity, err.Error())
|
|
return
|
|
}
|
|
|
|
pdfBytes, err := h.merge(req.URLs)
|
|
if err != nil {
|
|
var fe *fetchError
|
|
if errors.As(err, &fe) {
|
|
if fe.HTTPStatus == http.StatusNotFound {
|
|
writeError(w, http.StatusNotFound, "source PDF not found")
|
|
return
|
|
}
|
|
writeError(w, http.StatusBadGateway, "source PDF unavailable")
|
|
return
|
|
}
|
|
writeError(w, http.StatusInternalServerError, "merge failed")
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/pdf")
|
|
w.Header().Set("Content-Disposition", `inline; filename="`+req.Name+`"`)
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write(pdfBytes)
|
|
}
|
|
|
|
func validateMergeRequest(req *mergeRequest) error {
|
|
if req.Name == "" {
|
|
return fmt.Errorf("name is required")
|
|
}
|
|
if len(req.URLs) == 0 {
|
|
return fmt.Errorf("urls must not be empty")
|
|
}
|
|
if req.MergeRequestID <= 0 {
|
|
return fmt.Errorf("mergeRequestID is required")
|
|
}
|
|
if req.TOrderHeaderID <= 0 {
|
|
return fmt.Errorf("T_OrderHeaderID is required")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func writeError(w http.ResponseWriter, code int, msg string) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(code)
|
|
_ = json.NewEncoder(w).Encode(map[string]string{"error": msg})
|
|
}
|