diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6af4d61 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +root = true + +[*.go] +charset = utf-8 +indent_style = tabs +indent_size = 2 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true + +[Makefile] +charset = utf-8 +indent_style = tabs +indent_size = 2 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/fixtures/john.JPG b/fixtures/john.JPG new file mode 100644 index 0000000..5a357a8 Binary files /dev/null and b/fixtures/john.JPG differ diff --git a/fixtures/large.jpg b/fixtures/large.jpg new file mode 100644 index 0000000..e8a0ec9 Binary files /dev/null and b/fixtures/large.jpg differ diff --git a/fixtures/medium.jpg b/fixtures/medium.jpg new file mode 100644 index 0000000..73b95ec Binary files /dev/null and b/fixtures/medium.jpg differ diff --git a/main.go b/main.go new file mode 100644 index 0000000..524290a --- /dev/null +++ b/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "runtime" +) + +func main() { + runtime.GOMAXPROCS(runtime.NumCPU()) + + Server(8088) +} + +/* +func main() { + options := vips.Options{ + Width: 300, + Height: 240, + Crop: false, + Extend: vips.EXTEND_WHITE, + Interpolator: vips.BILINEAR, + Gravity: vips.CENTRE, + Quality: 95, + } + + f, _ := os.Open("fixtures/large.jpg") + inBuf, _ := ioutil.ReadAll(f) + + buf, err := vips.Resize(inBuf, options) + if err != nil { + fmt.Fprintln(os.Stderr, err) + return + } + + err = ioutil.WriteFile("image.jpg", buf, 0644) + if err != nil { + fmt.Fprintln(os.Stderr, err) + panic("Cannot write file") + } +} +*/ diff --git a/options.go b/options.go new file mode 100644 index 0000000..ff264b2 --- /dev/null +++ b/options.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/daddye/vips" +) + +type Options struct { + *vips.Options + Width int + Height int + Crop bool +} diff --git a/resize.go b/resize.go new file mode 100644 index 0000000..f2956d4 --- /dev/null +++ b/resize.go @@ -0,0 +1,21 @@ +package main + +import ( + "github.com/daddye/vips" + //"io/ioutil" + //"os" +) + +func Resize(imageBuf []byte) ([]byte, error) { + options := vips.Options{ + Width: 300, + Height: 240, + Crop: false, + Extend: vips.EXTEND_WHITE, + Interpolator: vips.BILINEAR, + Gravity: vips.CENTRE, + Quality: 95, + } + + return vips.Resize(imageBuf, options) +} diff --git a/server.go b/server.go new file mode 100644 index 0000000..ca02d43 --- /dev/null +++ b/server.go @@ -0,0 +1,96 @@ +package main + +import ( + "fmt" + //"io" + "io/ioutil" + "log" + "mime" + "net/http" + "os" + "strings" + "time" +) + +func Server(port int) { + server := &http.Server{ + Addr: ":8088", + ReadTimeout: 120 * time.Second, + WriteTimeout: 60 * time.Second, + MaxHeaderBytes: 1 << 20, + } + + // Register this pat with the default serve mux so that other packages + // may also be exported. (i.e. /debug/pprof/*) + //server.Handle("/", ProcessImage) + http.HandleFunc("/", ProcessImage) + + err := server.ListenAndServe() + if err != nil { + log.Fatal("Error starting the server:", err) + } +} + +func ProcessImage(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Server", "imgine "+Version) + + file, mimeType, err := getPayload(r) + + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + if len(mimeType) == 0 { + w.WriteHeader(http.StatusBadRequest) + return + } + + body, err := Resize(file) + if err != nil { + fmt.Fprintln(os.Stderr, err) + return + } + + w.Write(body) +} + +func getPayload(r *http.Request) ([]byte, string, error) { + file := r.Body + mimeType := getMimeType(r) + + if strings.Contains(mimeType, "form-data") { + file, _, _ = r.FormFile("file") + } + + buf, err := ioutil.ReadAll(file) + + return buf, mimeType, err +} + +func getMimeType(r *http.Request) string { + mimeType := r.Header.Get("Content-Type") + + if len(mimeType) == 0 { + buf, err := ioutil.ReadAll(r.Body) + if err != nil { + return "" + } + mimeType = inferMimeType(buf) + } else { + mimeType, _, _ = mime.ParseMediaType(mimeType) + } + + return mimeType +} + +func inferMimeType(buf []byte) string { + chunk := make([]byte, 512) + filetype := http.DetectContentType(chunk) + + switch filetype { + case "image/jpeg", "image/jpg", "image/png": + return filetype + default: + return "" + } +} diff --git a/upload.html b/upload.html new file mode 100644 index 0000000..4765f4d --- /dev/null +++ b/upload.html @@ -0,0 +1,8 @@ + + +
+ + +
+ + diff --git a/version.go b/version.go new file mode 100644 index 0000000..0354e88 --- /dev/null +++ b/version.go @@ -0,0 +1,3 @@ +package main + +const Version = "0.1.0"