1
0
Fork 0

Complete new bucket layout with preview
continuous-integration/drone/push Build is failing Details

main
Ambrose Chua 2020-06-14 19:19:38 +08:00
parent 8a313c2b28
commit b439555c46
Signed by: ambrose
GPG Key ID: BC367D33F140B5C2
4 changed files with 39 additions and 11 deletions

View File

@ -4,16 +4,17 @@ import (
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"net/url"
"sync" "sync"
"time" "time"
"git.makerforce.io/photos/photos/internal/httphelpers" "git.makerforce.io/photos/photos/internal/httphelpers"
lib "git.makerforce.io/photos/photos/pkg/bucket" lib "git.makerforce.io/photos/photos/pkg/bucket"
"github.com/minio/minio-go" "git.makerforce.io/photos/photos/pkg/credentials"
"git.makerforce.io/photos/photos/pkg/signer"
"github.com/davidbyttow/govips/pkg/vips"
) )
var creds *credentials.Cred var creds *credentials.Client
var sig *signer.Signer var sig *signer.Signer
type resizeOperation struct { type resizeOperation struct {
@ -44,18 +45,18 @@ func main() {
transport := &http.Transport{ transport := &http.Transport{
MaxIdleConns: 4, MaxIdleConns: 4,
MaxIdleConnsPerHost: 4, MaxIdleConnsPerHost: 4,
IdleConnTimeout: 30 * time.Second, IdleConnTimeout: 60 * time.Second,
DisableCompression: true, DisableCompression: true,
} }
http.DefaultClient = &http.Client{ http.DefaultClient = &http.Client{
Transport: transport, Transport: transport,
Timeout: 5 * time.Second, Timeout: 60 * time.Second,
} }
server := &http.Server{ server := &http.Server{
Addr: ":8003", Addr: ":8003",
ReadTimeout: 5 * time.Second, ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second, WriteTimeout: 60 * time.Second,
} }
http.HandleFunc("/update", update) http.HandleFunc("/update", update)
err = server.ListenAndServe() err = server.ListenAndServe()
@ -65,6 +66,8 @@ func main() {
} }
func update(w http.ResponseWriter, req *http.Request) { func update(w http.ResponseWriter, req *http.Request) {
var err error
if req.Method != http.MethodPost { if req.Method != http.MethodPost {
err := fmt.Errorf("%w: %v", httphelpers.ErrorMethodNotAllowed, req.Method) err := fmt.Errorf("%w: %v", httphelpers.ErrorMethodNotAllowed, req.Method)
httphelpers.ErrorResponse(w, err) httphelpers.ErrorResponse(w, err)
@ -94,6 +97,7 @@ func update(w http.ResponseWriter, req *http.Request) {
httphelpers.ErrorResponse(w, err) httphelpers.ErrorResponse(w, err)
return return
} }
log.Printf("Got credentials")
// Obtain preview options // Obtain preview options
/* /*
@ -101,6 +105,7 @@ func update(w http.ResponseWriter, req *http.Request) {
previewOptions := bucketMetadata.PreviewOptions previewOptions := bucketMetadata.PreviewOptions
*/ */
previewOptions := lib.DefaultPreviewOptions() previewOptions := lib.DefaultPreviewOptions()
log.Printf("Preview options: %v", previewOptions)
// Get photo // Get photo
original, err := getPhoto(bucket, cred, photo) original, err := getPhoto(bucket, cred, photo)
@ -108,6 +113,7 @@ func update(w http.ResponseWriter, req *http.Request) {
httphelpers.ErrorResponse(w, err) httphelpers.ErrorResponse(w, err)
return return
} }
log.Printf("Original photo filesize: %v", len(original))
// First, extract photo size // First, extract photo size
width, height, err := readsize(original) width, height, err := readsize(original)
@ -115,10 +121,11 @@ func update(w http.ResponseWriter, req *http.Request) {
httphelpers.ErrorResponse(w, err) httphelpers.ErrorResponse(w, err)
return return
} }
s := bucket.PhotoMetadataSize{ s := lib.PhotoMetadataSize{
Width: width, Width: width,
Height: height, Height: height,
} }
log.Printf("Photo size: %v", s)
err = putPhotoMetadataSize(bucket, cred, photo, s) err = putPhotoMetadataSize(bucket, cred, photo, s)
if err != nil { if err != nil {
httphelpers.ErrorResponse(w, err) httphelpers.ErrorResponse(w, err)
@ -126,6 +133,7 @@ func update(w http.ResponseWriter, req *http.Request) {
} }
// Do other resizes // Do other resizes
log.Printf("Starting resizes")
resizes := make([]resizeOperation, len(previewOptions)) resizes := make([]resizeOperation, len(previewOptions))
for i := range resizes { for i := range resizes {
resizes[i] = resizeOperation{ resizes[i] = resizeOperation{
@ -172,7 +180,7 @@ func update(w http.ResponseWriter, req *http.Request) {
wg.Add(1) wg.Add(1)
go func() { go func() {
preview := photo.GetPreview(op.previewOption) preview := photo.GetPreview(op.previewOption)
err := client.PutPreview(bucket, preview, op.output) err := putPreview(bucket, cred, preview, op.output)
log.Printf("Uploaded photo %s at h%dq%d: %v", photo, op.previewOption.Height, op.previewOption.Quality, err) log.Printf("Uploaded photo %s at h%dq%d: %v", photo, op.previewOption.Height, op.previewOption.Quality, err)
op.err = err op.err = err
wg.Done() wg.Done()
@ -192,5 +200,6 @@ func update(w http.ResponseWriter, req *http.Request) {
for _, op := range resizes { for _, op := range resizes {
timings = append(timings, op.took) timings = append(timings, op.took)
} }
log.Printf("Resizes took: %v", timings)
w.Header().Add("X-Debug-Resize-Timings", fmt.Sprintf("%v", timings)) w.Header().Add("X-Debug-Resize-Timings", fmt.Sprintf("%v", timings))
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"bytes"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -12,7 +13,7 @@ import (
// TODO: handle errors nicer // TODO: handle errors nicer
func getPhoto(bucket lib.Bucket, cred credentials.Credential, photo lib.Photo) ([]byte, error) { func getPhoto(bucket lib.Bucket, cred credentials.Credential, photo lib.Photo) ([]byte, error) {
unsignedReq, err := http.NewRequest(http.MethodGET, bucket.URL(photo).String(), nil) unsignedReq, err := http.NewRequest(http.MethodGet, bucket.URL(photo).String(), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -40,7 +41,23 @@ func putPhotoMetadataSize(bucket lib.Bucket, cred credentials.Credential, photo
if err != nil { if err != nil {
return err return err
} }
unsignedReq, err := http.NewRequest(http.MethodPUT, bucket.URL(photo.MetadataSize()).String(), bytes.NewBuffer(buf)) unsignedReq, err := http.NewRequest(http.MethodPut, bucket.URL(photo.MetadataSize()).String(), bytes.NewBuffer(buf))
if err != nil {
return err
}
signedReq := sig.Sign(unsignedReq, cred)
resp, err := http.DefaultClient.Do(signedReq)
if err != nil {
return err
}
defer resp.Body.Close()
return httphelpers.ErrorFromStatus(resp.StatusCode)
}
func putPreview(bucket lib.Bucket, cred credentials.Credential, preview lib.Preview, buf []byte) error {
unsignedReq, err := http.NewRequest(http.MethodPut, bucket.URL(preview).String(), bytes.NewBuffer(buf))
if err != nil { if err != nil {
return err return err
} }

View File

@ -17,7 +17,7 @@ func (b Bucket) Validate() error {
// Ensure is URL // Ensure is URL
u, err := url.ParseRequestURI(string(b)) u, err := url.ParseRequestURI(string(b))
if err != nil { if err != nil {
return fmt.Errorf("%w: %w: %v", ErrorInvalidBucket, err, b) return fmt.Errorf("%w: %v: %v", ErrorInvalidBucket, err.Error(), b)
} }
if u.Scheme != "http" && u.Scheme != "https" { if u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("%w: %v", ErrorInvalidBucket, b) return fmt.Errorf("%w: %v", ErrorInvalidBucket, b)

View File

@ -67,6 +67,8 @@ func (s *Signer) PreSignWrite(req *http.Request, cred credentials.Credential) *h
} }
func (s *Signer) Sign(req *http.Request, cred credentials.Credential) *http.Request { func (s *Signer) Sign(req *http.Request, cred credentials.Credential) *http.Request {
// All payloads unsigned
req.Header.Set("X-Amz-Content-Sha256", "UNSIGNED-PAYLOAD")
signedReq := signer.SignV4( signedReq := signer.SignV4(
*req, *req,
cred.AccessKey, cred.SecretKey, "", cred.AccessKey, cred.SecretKey, "",