package handlers import ( "bytes" "encoding/base64" "encoding/json" "image" _ "image/gif" _ "image/jpeg" "image/png" "strconv" "golang.org/x/image/draw" "net/http" "server/database" "server/helper" ) const thumbnail_size = 128 func makeThumbnail(source image.Image) ([]byte, error) { dest := image.NewRGBA(image.Rect(0, 0, thumbnail_size, thumbnail_size)) draw.NearestNeighbor.Scale(dest, dest.Rect, source, source.Bounds(), draw.Over, nil) var buffer bytes.Buffer err := png.Encode(&buffer, dest) if err != nil { return nil, err } return buffer.Bytes(), nil } type postRequest struct { Title string Contents string Subreact string File string } type postResponse struct { Uid int `json:"uid"` } func Post(writer http.ResponseWriter, request *http.Request) { if request.Method != "POST" { helper.WriteErrorJson("expected GET method", writer, http.StatusBadRequest) return } claims := helper.GetValidClaims(writer, request) if claims == nil { return } user_uid, err := strconv.Atoi(claims.Subject) // TODO UID if err != nil { helper.WriteInternalErrorJson(err, writer) return } var post_request postRequest err = json.NewDecoder(request.Body).Decode(&post_request) if err != nil { helper.WriteErrorJson(err.Error(), writer, http.StatusBadRequest) return } post_request.Title = helper.CleanTitle(post_request.Title) if !helper.IsValidRange(post_request.Title, "title", 8, 128, writer) { return } post_request.Contents = helper.CleanContents(post_request.Contents) if !helper.IsValidRange(post_request.Contents, "contents", 8, 2048, writer) { return } if !helper.IsValidSubreact(post_request.Subreact, writer) { return } image_blob, err := base64.StdEncoding.DecodeString(post_request.File) if err != nil { helper.WriteErrorJson("failed to decode image from base64", writer, http.StatusBadRequest) return } image, format, err := image.Decode(bytes.NewReader(image_blob)) if err != nil { helper.WriteErrorJson("failed to decode image", writer, http.StatusBadRequest) return } if !helper.IsImageSupported(image, format, writer) { return } thumbnail_blob, err := makeThumbnail(image) if err != nil { helper.WriteInternalErrorJson(err, writer) return } image_uid, err := database.WritePost(user_uid, nil, post_request.Title, post_request.Contents, post_request.Subreact, image_blob, thumbnail_blob) if err != nil { helper.WriteInternalErrorJson(err, writer) return } resp, err := json.Marshal(postResponse{Uid: image_uid}) if err != nil { helper.WriteInternalErrorJson(err, writer) return } writer.Write(resp) }