summaryrefslogtreecommitdiffhomepage
path: root/http/put.go
blob: bc49e74b82dbf43174fcd4ec5171ccbd604176a9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package http

import (
	"encoding/base64"
	"fmt"

	"github.com/twmb/murmur3"
	"github.com/valyala/fasthttp"
	"toast.cafe/x/brpaste/v2/storage"
)

func Put(store storage.CHR, put bool) handler {
	return func(ctx *fasthttp.RequestCtx) {
		data := ctx.FormValue("data")
		if len(data) == 0 { // works with nil
			ctx.Error("Missing data field", fasthttp.StatusBadRequest)
			return
		}

		ukey := ctx.UserValue("key")
		var key string
		if ukey != nil {
			key = ukey.(string)
		} else {
			hasher := murmur3.New32()
			hasher.Write(data)
			keybuf := hasher.Sum(nil)
			key = base64.RawURLEncoding.EncodeToString(keybuf)
		}
		val := string(data)

		err := store.Create(key, val, put)

		switch err {
		case storage.Collision:
			ctx.Error("Collision detected when undesired", fasthttp.StatusConflict)
		case storage.Unhealthy:
			ctx.Error("Backend did not respond", fasthttp.StatusInternalServerError)
		case nil: // everything succeeded
			if isBrowser(string(ctx.UserAgent())) {
				ctx.Redirect(fmt.Sprintf("/%s", key), fasthttp.StatusSeeOther)
			} else {
				ctx.SetStatusCode(fasthttp.StatusCreated)
				ctx.SetBodyString(key)
			}
		default:
			ctx.Error(err.Error(), fasthttp.StatusInternalServerError)
		}
	}
}