package image import ( "fmt" "html/template" "io/ioutil" "log" "net/http" "github.com/go-chi/chi" ) var fileTypes = map[string]string{ "image/jpeg": "jpg", "image/png": "png", } // Handler image handler interface type Handler interface { GetImage(w http.ResponseWriter, r *http.Request) PostImage(w http.ResponseWriter, r *http.Request) } // NewHandler create image handler struct func NewHandler(service Servicer) Handler { return &imageHandler{service} } type imageHandler struct { service Servicer } // GetImage handler for returning an image func (h *imageHandler) GetImage(w http.ResponseWriter, r *http.Request) { fileID := chi.URLParam(r, "fileName") fileMeta, err := h.service.GetFile(fileID) if err != nil { http.Error(w, "an error has occured", http.StatusBadRequest) return } fileUrl := fmt.Sprintf("/f/%s", fileMeta.FilePath) data := struct { ImageUrl string ImageTitle string ImageDesc string }{ fileUrl, fileMeta.Title, fileMeta.Desc, } h.service.Render(w, "image.tmpl", data) } // PostImage handler for creating an image post func (h *imageHandler) PostImage(w http.ResponseWriter, r *http.Request) { // max size r.ParseMultipartForm(10 << 20) file, handler, err := r.FormFile("file") if err != nil { log.Printf("%s", err) return } defer file.Close() fileBytes, err := ioutil.ReadAll(file) if err != nil { log.Printf("%s", err) log.Printf("unsupported filetype") w.WriteHeader(400) w.Write([]byte("Incorrect Content Type")) return } fileType := http.DetectContentType(fileBytes) if fileType != handler.Header.Get("Content-Type") { log.Printf("file type and content type do not match") w.WriteHeader(400) w.Write([]byte("Incorrect Content Type")) return } extension, exists := fileTypes[fileType] if !exists { log.Printf("unsupported filetype") w.WriteHeader(400) w.Write([]byte("Incorrect Content Type")) return } formData := r.PostForm rawPostTitle := formData.Get("title") rawPostDesc := formData.Get("desc") postTitle := template.HTMLEscapeString(rawPostTitle) postDesc := template.HTMLEscapeString(rawPostDesc) if len(rawPostDesc) != len(postDesc) { log.Printf("description not clean") w.WriteHeader(400) w.Write([]byte("Incorrect Content Type")) return } if len(rawPostTitle) != len(postTitle) { log.Printf("invalid title") w.WriteHeader(400) w.Write([]byte("Invalid image meta data")) return } postMeta := &PostMeta{ MimeType: fileType, Title: postTitle, Desc: postDesc, } fileName, fileID, err := h.service.AddFile(extension, postMeta, fileBytes) if err != nil { log.Printf("failed to write file") w.WriteHeader(500) w.Write([]byte("An Internal Error Occured")) return } w.WriteHeader(201) w.Write([]byte(fmt.Sprintf("%s %s", fileName, fileID))) return }