aboutsummaryrefslogtreecommitdiff
path: root/src/server/handlers/post.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/handlers/post.go')
-rw-r--r--src/server/handlers/post.go121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/server/handlers/post.go b/src/server/handlers/post.go
new file mode 100644
index 0000000..2c014ca
--- /dev/null
+++ b/src/server/handlers/post.go
@@ -0,0 +1,121 @@
+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)
+}