1
0
Fork 0
photos/cmd/control/control.go

105 lines
2.6 KiB
Go

package main
import (
"fmt"
"net/http"
"time"
"git.makerforce.io/photos/photos/internal/httphelpers"
lib "git.makerforce.io/photos/photos/pkg/bucket"
"git.makerforce.io/photos/photos/pkg/credentials"
"git.makerforce.io/photos/photos/pkg/signer"
)
var creds *credentials.Client
var sig *signer.Signer
func main() {
var err error
// Setup bucket credential source
creds, err = credentials.NewClientFromEnv()
if err != nil {
panic(err)
}
// Setup bucket signer
sig, err = signer.NewSignerFromEnv()
if err != nil {
panic(err)
}
transport := &http.Transport{
MaxIdleConns: 4,
MaxIdleConnsPerHost: 4,
IdleConnTimeout: 60 * time.Second,
DisableCompression: true,
}
http.DefaultClient = &http.Client{
Transport: transport,
Timeout: 60 * time.Second,
}
server := &http.Server{
Addr: ":8000",
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
http.HandleFunc("/sign", sign)
err = server.ListenAndServe()
if err != nil {
panic(err)
}
}
func sign(w http.ResponseWriter, req *http.Request) {
var err error
bucket := lib.Bucket(req.FormValue("bucket"))
token := req.FormValue("token")
resource := SafePathable(req.FormValue("resource"))
err = bucket.Validate()
if err != nil {
err := fmt.Errorf("%w: %v", httphelpers.ErrorBadRequest, err.Error())
httphelpers.ErrorResponse(w, err)
return
}
err = resource.Validate()
if err != nil {
err := fmt.Errorf("%w: %v", httphelpers.ErrorBadRequest, err.Error())
httphelpers.ErrorResponse(w, err)
return
}
var cred credentials.Credential
if token == "todo" {
cred, err = creds.Get(bucket)
if err != nil {
err := fmt.Errorf("%w: error getting credentials: %v", httphelpers.ErrorBadRequest, err.Error())
httphelpers.ErrorResponse(w, err)
return
}
}
var signedReq *http.Request
unsignedReq, err := http.NewRequest(req.Method, bucket.URL(resource).String(), nil)
if err != nil {
err := fmt.Errorf("%w: error creating request: %v", httphelpers.ErrorBadRequest, err.Error())
httphelpers.ErrorResponse(w, err)
return
}
if req.Method == http.MethodGet {
signedReq = sig.PreSignRead(unsignedReq, cred)
} else if req.Method == http.MethodPost || req.Method == http.MethodPut || req.Method == http.MethodDelete {
signedReq = sig.PreSignWrite(unsignedReq, cred)
} else {
err := fmt.Errorf("%w: %v", httphelpers.ErrorMethodNotAllowed, req.Method)
httphelpers.ErrorResponse(w, err)
return
}
w.Header().Add("Access-Control-Allow-Origin", "*")
w.Header().Add("Location", signedReq.URL.String())
w.WriteHeader(http.StatusTemporaryRedirect)
}