Created
May 3, 2012 15:30
-
-
Save mynameisfiber/2586507 to your computer and use it in GitHub Desktop.
imggtr.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"errors" | |
"fmt" | |
"io" | |
"net/http" | |
"net/url" | |
"path" | |
"strings" | |
) | |
func rev(in []byte) []byte { | |
msize := len(in) - 1 | |
out := make([]byte, len(in)) | |
for i := msize; i >= 0; i-- { | |
out[msize-i] = in[i] | |
} | |
return out | |
} | |
func bytesToInt(in []byte) int { | |
value := 0 | |
for _, b := range in { | |
value = (value << 8) | (int(b) & 0xFF) | |
} | |
return value | |
} | |
func extractSizePNG(body_fd io.Reader) (width, height int, err error) { | |
// Offsets from PNG v1.2 specs. See: | |
// http://www.libpng.org/pub/png/spec/1.2/PNG-Structure.html | |
body := make([]byte, 24) | |
io.ReadFull(body_fd, body) | |
if bytes.Equal(body[1:4], []byte{80, 78, 71}) == false { | |
return 0, 0, errors.New("Not a valid PNG") | |
} | |
return bytesToInt(body[16:20]), bytesToInt(body[20:24]), nil | |
} | |
func extractSizeGIF(body_fd io.Reader) (width, height int, err error) { | |
// http://www.onicos.com/staff/iz/formats/gif.html | |
body := make([]byte, 10) | |
io.ReadFull(body_fd, body) | |
if bytes.Equal(body[:3], []byte{71, 73, 70}) == false { | |
return 0, 0, errors.New("Not a valid GIF") | |
} | |
return bytesToInt(rev(body[6:8])), bytesToInt(rev(body[8:10])), nil | |
} | |
func extractSizeJPEG(body_fd io.Reader) (width, height int, err error) { | |
// http://www.onicos.com/staff/iz/formats/jpeg.html | |
header := make([]byte, 10) | |
io.ReadFull(body_fd, header) | |
if bytes.Equal(header[6:10], []byte{74, 70, 73, 70}) == false { | |
return 0, 0, errors.New("Not a valid JPEG") | |
} | |
b := make([]byte, 2) | |
for bytes.Equal(b, []byte{255, 192}) == false { | |
io.ReadFull(body_fd, b) | |
} | |
c0header := make([]byte, 8) | |
io.ReadFull(body_fd, c0header) | |
fmt.Println(c0header) | |
return bytesToInt(c0header[5:7]), bytesToInt(c0header[3:5]), nil | |
} | |
func extractSize(ext string, body_fd io.Reader) (width, height int, err error) { | |
if ext == ".png" { | |
return extractSizePNG(body_fd) | |
} else if ext == ".gif" { | |
return extractSizeGIF(body_fd) | |
} else if ext == ".jpg" || ext == ".jpeg" || ext == ".jpe" { | |
return extractSizeJPEG(body_fd) | |
} else { | |
return 0, 0, errors.New("Unknown filetype") | |
} | |
return | |
} | |
func FetchImage(imgUrlRaw string, w http.ResponseWriter) { | |
imgUrl, err := url.Parse(imgUrlRaw) | |
if err != nil { | |
fmt.Fprintf(w, "Malformed image URL: %s", err) | |
return | |
} | |
resp, err := http.Get(imgUrlRaw) | |
if err != nil { | |
fmt.Fprintf(w, "%s", err) | |
return | |
} | |
defer resp.Body.Close() | |
ext := strings.ToLower(path.Ext(imgUrl.Path)) | |
width, height, err := extractSize(ext, resp.Body) | |
if err != nil { | |
fmt.Fprintf(w, "Could not extract resolution: %s", err) | |
return | |
} | |
fmt.Fprintf(w, "%d x %d\n", width, height) | |
} | |
func GetHandler(w http.ResponseWriter, r *http.Request) { | |
reqParams, err := url.ParseQuery(r.URL.RawQuery) | |
if err != nil { | |
fmt.Fprintf(w, "Error decoding request URI: %s", r.URL.RawQuery) | |
return | |
} | |
reqUrl := reqParams.Get("url") | |
if reqUrl == "" { | |
fmt.Fprintf(w, "Missing required parameter 'url'") | |
return | |
} | |
FetchImage(reqUrl, w) | |
} | |
func PingHandler(w http.ResponseWriter, r *http.Request) { | |
fmt.Fprintf(w, "OK") | |
} | |
func main() { | |
http.HandleFunc("/get", GetHandler) | |
http.HandleFunc("/ping", PingHandler) | |
http.HandleFunc("/", PingHandler) | |
http.ListenAndServe(":8080", nil) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment