1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| package main
import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "fmt" "net/http" "strconv" "time" )
const secretKey = "mysecretkey123"
const imagePath = "./images/"
func generateSignedURL(imageName string, validDuration time.Duration) string { expiry := time.Now().Add(validDuration).Unix()
signature := createSignature(imageName, expiry)
return fmt.Sprintf("/image?name=%s&expiry=%d&signature=%s", imageName, expiry, signature) }
func createSignature(imageName string, expiry int64) string { data := fmt.Sprintf("%s|%d", imageName, expiry) h := hmac.New(sha256.New, []byte(secretKey)) h.Write([]byte(data)) return hex.EncodeToString(h.Sum(nil)) }
func validateSignature(imageName string, expiry int64, signature string) bool { if expiry < time.Now().Unix() { return false }
expectedSignature := createSignature(imageName, expiry)
return hmac.Equal([]byte(expectedSignature), []byte(signature)) }
func imageHandler(w http.ResponseWriter, r *http.Request) { imageName := r.URL.Query().Get("name") expiryStr := r.URL.Query().Get("expiry") signature := r.URL.Query().Get("signature")
if imageName == "" || expiryStr == "" || signature == "" { http.Error(w, "Invalid request parameters", http.StatusBadRequest) return }
expiry, err := strconv.ParseInt(expiryStr, 10, 64) if err != nil { http.Error(w, "Invalid expiry parameter", http.StatusBadRequest) return }
if !validateSignature(imageName, expiry, signature) { http.Error(w, "Invalid or expired signature", http.StatusForbidden) return }
filePath := imagePath + imageName
file, err := http.Dir(imagePath).Open(imageName) if err != nil { http.Error(w, "Image not found", http.StatusNotFound) return } defer file.Close()
http.ServeFile(w, r, filePath) }
func main() { imageName := "cat.jpg" validDuration := 10 * time.Minute signedURL := generateSignedURL(imageName, validDuration) fmt.Printf("Generated signed URL: http://localhost:8080%s\n", signedURL)
http.HandleFunc("/image", imageHandler)
fmt.Println("Starting server on :8080...") if err := http.ListenAndServe(":8080", nil); err != nil { fmt.Println("Error starting server:", err) } }
|