Esempio n. 1
0
func newResizeHandler(ro resizeOpts) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		log.Println("Starting resizeHandler")

		imageKey := r.URL.Path[len(ro.path):]

		// fetch the query param
		resizeQuery := r.URL.Query().Get("resize")

		key := fmt.Sprintf("%s/%s", ro.prefix, imageKey)

		if resizeQuery == "" {
			log.Println("Completed resizeHandler: Redirected, no resize parameter")
			urlStr := fmt.Sprintf("https://s3-%s.amazonaws.com/%s/%s", ro.region, ro.bucket, key)
			http.Redirect(w, r, urlStr, http.StatusTemporaryRedirect)
			return
		}

		resizeX, resizeY, err := waltz.ParseResize(resizeQuery)
		if err != nil {
			log.Println("Completed resizeHandler: ERROR: Resize parameters invalid:", err.Error())
			http.Error(w, "", http.StatusBadRequest)
			return
		}

		params := &s3.GetObjectInput{
			Bucket: aws.String(ro.bucket),
			Key:    aws.String(key),
		}

		log.Println("Getting", *params.Key, "from bucket", *params.Bucket)

		ifNoneMatch := r.Header.Get("If-None-Match")
		if ifNoneMatch != "" {
			params.IfNoneMatch = aws.String(ifNoneMatch)
		}

		resp, err := ro.client.GetObject(params)
		if err != nil {
			if awsErr, ok := err.(awserr.Error); ok {

				if reqErr, ok := err.(awserr.RequestFailure); ok {

					// if this is a not modified error, then cut quick
					if reqErr.StatusCode() == http.StatusNotModified {
						log.Println("Completed resizeHandler: Object not modified")
						w.WriteHeader(http.StatusNotModified)
						return
					}

					if reqErr.StatusCode() == http.StatusNotFound {
						log.Println("Completed resizeHandler: Key not found")
						w.WriteHeader(http.StatusNotFound)
						return
					}

					// A service error occurred
					log.Println("Completed resizeHandler: ERROR: AWS Service error:", reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID())
					http.Error(w, "", http.StatusInternalServerError)
					return

				}

				// Generic AWS error with Code, Message, and original error (if any)
				log.Println("Completed resizeHandler: ERROR: Generic AWS error:", awsErr.Code(), awsErr.Message(), awsErr.OrigErr())
				http.Error(w, "", http.StatusInternalServerError)
				return

			}

			// This case should never be hit, the SDK should always return an
			// error which satisfies the awserr.Error interface.
			log.Println("Completed resizeHandler: ERROR: Impossible error:", err.Error())
			http.Error(w, "", http.StatusInternalServerError)
			return

		}

		// write out the content type
		w.Header().Set("Cache-control", fmt.Sprintf("public, max-age=%d", int64(imageExpiry.Seconds())))
		w.Header().Set("Content-Type", *resp.ContentType)
		w.Header().Set("Etag", *resp.ETag)

		if err := waltz.Do(resp.Body, w, nil, resizeX, resizeY); err != nil {
			log.Println("Completed resizeHandler: ERROR: Resize Error:", err.Error())
			http.Error(w, "", http.StatusInternalServerError)
			return
		}
	}
}
Esempio n. 2
0
func main() {
	// use all CPU cores for maximum performance
	runtime.GOMAXPROCS(runtime.NumCPU())

	// crop points
	var cropTLX, cropTLY, cropBRX, cropBRY int

	// resize points
	var resizeX, resizeY int

	// string components
	var crop, resize string

	flag.StringVar(&crop, "crop", "", "crop dimensions as 0x0,32x32 to indicate bounds")
	flag.StringVar(&resize, "resize", "", "resize dimensions after the crop as 16x16")

	flag.Parse()

	var (
		cropRectangle *image.Rectangle
		err           error
	)

	if crop != "" {

		crop1 := strings.Split(crop, ",")

		if len(crop1) != 2 {
			log.Fatalf("crop invalid, should be in the form of 0x0,32x32")
		}

		crop2TL := strings.Split(crop1[0], "x")

		if len(crop2TL) != 2 {
			log.Fatalf("crop invalid, should be in the form of 0x0,32x32")
		}

		crop2BR := strings.Split(crop1[1], "x")

		if len(crop2BR) != 2 {
			log.Fatalf("crop invalid, should be in the form of 0x0,32x32")
		}

		if cropTLX, err = strconv.Atoi(crop2TL[0]); err != nil {
			log.Fatalln("crop invalid, should be in the form of 0x0,32x32")
		}

		if cropTLY, err = strconv.Atoi(crop2TL[1]); err != nil {
			log.Fatalln("crop invalid, should be in the form of 0x0,32x32")
		}

		if cropBRX, err = strconv.Atoi(crop2BR[0]); err != nil {
			log.Fatalln("crop invalid, should be in the form of 0x0,32x32")
		}

		if cropBRY, err = strconv.Atoi(crop2BR[1]); err != nil {
			log.Fatalln("crop invalid, should be in the form of 0x0,32x32")
		}

		cr := image.Rect(cropTLX, cropTLY, cropBRX, cropBRY)

		cropRectangle = &cr

	}

	resize1 := strings.Split(resize, "x")

	if len(resize1) < 1 {
		log.Fatalln("resize invalid, should be in the form 16x16")
	}

	if resizeX, err = strconv.Atoi(resize1[0]); err != nil {
		log.Fatalln("resize invalid, should be in the form 16x16")
	}

	if len(resize1) == 2 {
		if resizeY, err = strconv.Atoi(resize1[1]); err != nil {
			log.Fatalln("resize invalid, should be in the form 16x16")
		}
	}

	if err := waltz.Do(os.Stdin, os.Stdout, cropRectangle, resizeX, resizeY); err != nil {
		log.Fatalf("An error occured performing the resize: %s\n", err.Error())
	}
}