Skip to content

Instantly share code, notes, and snippets.

@hhatto
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hhatto/3794e201aa94eb6720de to your computer and use it in GitHub Desktop.
Save hhatto/3794e201aa94eb6720de to your computer and use it in GitHub Desktop.
reverse-reverse-proxy, that image rotate proxy.
//
// ## reverse-reverse-proxy
// This is reverse(rotate) image proxy server.
// This is my toy Go project:-)
//
// ```
// +-----------+ request +--------------+ request +-------------+
// | client |----------->| rrp |----------->| target host |
// | (browser) |<-----------| |<-----------| |
// +-----------+ response +--------------+ response +-------------+
// rotate image
// (only jpg/png)
// ```
//
// ## Build
// ```
// $ go get github.com/disintegration/imaging
// $ go build -o reverse-reverse-proxy main.go
// ```
//
// ## Usage
// ```
// $ ./reverse-reverse-proxy
// ```
//
// ## Note
// You should use a [willnorris's imageproxy](https://github.com/willnorris/imageproxy)
// in practical applications
//
package main
import (
"bufio"
"bytes"
"fmt"
"image"
"image/jpeg"
"image/png"
"net/http"
"net/http/httputil"
"regexp"
"github.com/disintegration/imaging"
)
var matcher = regexp.MustCompile(`.(jpg|png)$`)
func reverseImage(res *http.Response) (resImg []byte, err error) {
t, format, err := image.Decode(res.Body)
if err != nil {
return nil, err
}
t = imaging.Rotate180(t)
buf := new(bytes.Buffer)
switch format {
case "jpeg":
jpeg.Encode(buf, t, &jpeg.Options{Quality: 90})
case "png":
png.Encode(buf, t)
}
return buf.Bytes(), nil
}
type myTransport struct {
}
func (t *myTransport) RoundTrip(req *http.Request) (res *http.Response, err error) {
if res, err = http.DefaultTransport.RoundTrip(req); err != nil {
return nil, err
}
if !matcher.MatchString(req.URL.String()) || res.StatusCode != 200 {
return res, err
}
defer res.Body.Close()
img, err := reverseImage(res)
if err != nil {
return nil, err
}
fmt.Println("reverse image: ", req.URL.String())
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "%s %s\n", res.Proto, res.Status)
fmt.Fprintf(buf, "Content-Length: %d\n\n", len(img))
buf.Write(img)
return http.ReadResponse(bufio.NewReader(buf), req)
}
func main() {
addr := ":8888"
proxy := &httputil.ReverseProxy{
Director: func(req *http.Request) {},
Transport: &myTransport{},
}
server := http.Server{
Addr: addr,
Handler: proxy,
}
server.ListenAndServe()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment