Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
0afc7a5bed
|
|||
|
54fe38821c
|
|||
|
f9c064e948
|
@@ -23,7 +23,7 @@ type info struct{}
|
|||||||
func (info) RegisterHTTP(mux *http.ServeMux) {
|
func (info) RegisterHTTP(mux *http.ServeMux) {
|
||||||
mux.HandleFunc("/app-info", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/app-info", func(w http.ResponseWriter, r *http.Request) {
|
||||||
name, version := service.AppName()
|
name, version := service.AppName()
|
||||||
fmt.Fprint(w, name, version)
|
fmt.Fprint(w, name, '@', version)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
103
app.paste.go
103
app.paste.go
@@ -2,19 +2,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"go.sour.is/pkg/env"
|
"go.sour.is/pkg/env"
|
||||||
"go.sour.is/pkg/lg"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/pkg/service"
|
"go.sour.is/pkg/service"
|
||||||
|
|
||||||
"go.sour.is/paste/v2/assets"
|
|
||||||
"go.sour.is/paste/v2/paste"
|
"go.sour.is/paste/v2/paste"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -28,104 +21,12 @@ var _ = apps.Register(50, func(ctx context.Context, svc *service.Harness) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := paste.New(store)
|
srv, err := paste.NewService(store, randBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
svc.Add(&pasteSRV{
|
svc.Add(srv)
|
||||||
ui: http.FileServer(http.FS(assets.GetUI())),
|
|
||||||
paste: p,
|
|
||||||
randBytes: int(randBytes),
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
type pasteSRV struct {
|
|
||||||
ui http.Handler
|
|
||||||
paste *paste.Paste
|
|
||||||
randBytes int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *pasteSRV) RegisterHTTP(mux *http.ServeMux) {
|
|
||||||
mux.Handle("/ui/", lg.Htrace(http.StripPrefix("/ui/", a.ui), "paste-assets"))
|
|
||||||
|
|
||||||
mux.Handle("/api", http.StripPrefix("/api", a))
|
|
||||||
mux.Handle("/api/", http.StripPrefix("/api/", a))
|
|
||||||
|
|
||||||
mux.Handle("/paste", http.StripPrefix("/paste", a))
|
|
||||||
mux.Handle("/paste/", http.StripPrefix("/paste/", a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *pasteSRV) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
||||||
switch r.Method {
|
|
||||||
case http.MethodGet:
|
|
||||||
switch {
|
|
||||||
case strings.HasPrefix(r.URL.Path, "rng"):
|
|
||||||
p.getRandom(w)
|
|
||||||
|
|
||||||
case strings.HasPrefix(r.URL.Path, "get"), r.URL.Path != "":
|
|
||||||
p.getPaste(w, strings.TrimPrefix(r.URL.Path, "get/"))
|
|
||||||
|
|
||||||
default:
|
|
||||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
case http.MethodPost:
|
|
||||||
switch {
|
|
||||||
case r.URL.Path == "":
|
|
||||||
p.postPaste(w, r)
|
|
||||||
|
|
||||||
default:
|
|
||||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *pasteSRV) getRandom(w http.ResponseWriter) {
|
|
||||||
log.Println("get random")
|
|
||||||
s := make([]byte, p.randBytes)
|
|
||||||
_, _ = rand.Read(s)
|
|
||||||
|
|
||||||
w.Header().Set("content-type", "application/octet-stream")
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, _ = w.Write(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *pasteSRV) getPaste(w http.ResponseWriter, id string) {
|
|
||||||
log.Println("get paste", id)
|
|
||||||
w.Header().Set("content-type", "application/octet-stream")
|
|
||||||
|
|
||||||
err := p.paste.Get(w, id)
|
|
||||||
if err != nil {
|
|
||||||
switch {
|
|
||||||
case errors.Is(err, paste.ErrGone):
|
|
||||||
w.WriteHeader(http.StatusGone)
|
|
||||||
case errors.Is(err, paste.ErrNotFound):
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
|
||||||
case errors.Is(err, paste.ErrReadingContent):
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(w, "ERR %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *pasteSRV) postPaste(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("content-type", "application/octet-stream")
|
|
||||||
|
|
||||||
id, err := p.paste.Set(r.Body)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(w, "ERR %s", err)
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("post paste", id)
|
|
||||||
fmt.Fprint(w, "OK ", id)
|
|
||||||
}
|
|
||||||
|
|||||||
4
go.mod
4
go.mod
@@ -3,7 +3,7 @@ module go.sour.is/paste/v2
|
|||||||
go 1.21
|
go 1.21
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gomarkdown/markdown v0.0.0-20200824053859-8c8b3816f167
|
github.com/gomarkdown/markdown v0.0.0-20230922105210-14b16010c2ee
|
||||||
github.com/h2non/filetype v1.1.0
|
github.com/h2non/filetype v1.1.0
|
||||||
github.com/matryer/is v1.4.1
|
github.com/matryer/is v1.4.1
|
||||||
github.com/rs/cors v1.6.0
|
github.com/rs/cors v1.6.0
|
||||||
@@ -58,7 +58,7 @@ require (
|
|||||||
golang.org/x/text v0.13.0 // indirect
|
golang.org/x/text v0.13.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||||
google.golang.org/grpc v1.58.0 // indirect
|
google.golang.org/grpc v1.58.3 // indirect
|
||||||
google.golang.org/protobuf v1.31.0 // indirect
|
google.golang.org/protobuf v1.31.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.57.0 // indirect
|
gopkg.in/ini.v1 v1.57.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -94,6 +94,8 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg
|
|||||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/gomarkdown/markdown v0.0.0-20200824053859-8c8b3816f167 h1:LP/6EfrZ/LyCc+SXvANDrIJ4sP9u2NAtqyv6QknetNQ=
|
github.com/gomarkdown/markdown v0.0.0-20200824053859-8c8b3816f167 h1:LP/6EfrZ/LyCc+SXvANDrIJ4sP9u2NAtqyv6QknetNQ=
|
||||||
github.com/gomarkdown/markdown v0.0.0-20200824053859-8c8b3816f167/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
|
github.com/gomarkdown/markdown v0.0.0-20200824053859-8c8b3816f167/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
|
||||||
|
github.com/gomarkdown/markdown v0.0.0-20230922105210-14b16010c2ee h1:gvsnG+uIVkOue7HrYAG2ZnOdLoJTqsLyuBFJaU0kX4M=
|
||||||
|
github.com/gomarkdown/markdown v0.0.0-20230922105210-14b16010c2ee/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
@@ -443,6 +445,8 @@ google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
|
|||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
google.golang.org/grpc v1.58.0 h1:32JY8YpPMSR45K+c3o6b8VL73V+rR8k+DeMIr4vRH8o=
|
google.golang.org/grpc v1.58.0 h1:32JY8YpPMSR45K+c3o6b8VL73V+rR8k+DeMIr4vRH8o=
|
||||||
google.golang.org/grpc v1.58.0/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
google.golang.org/grpc v1.58.0/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||||
|
google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
|
||||||
|
google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ type image struct {
|
|||||||
store string
|
store string
|
||||||
maxSize int64
|
maxSize int64
|
||||||
|
|
||||||
m_image_get metric.Int64Counter
|
m_image_get metric.Int64Counter
|
||||||
m_image_post metric.Int64Counter
|
m_image_post metric.Int64Counter
|
||||||
m_image_error metric.Int64Counter
|
m_image_error metric.Int64Counter
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,6 @@ func New(ctx context.Context, store string, maxSize int64) (a *image, err error)
|
|||||||
)
|
)
|
||||||
err = errors.Join(err, merr)
|
err = errors.Join(err, merr)
|
||||||
|
|
||||||
|
|
||||||
return a, err
|
return a, err
|
||||||
}
|
}
|
||||||
func (a *image) RegisterHTTP(mux *http.ServeMux) {
|
func (a *image) RegisterHTTP(mux *http.ServeMux) {
|
||||||
@@ -119,6 +118,9 @@ func (a *image) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
var err error
|
var err error
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
// var buf bytes.Buffer
|
||||||
|
// r.Body = io.NopCloser(io.TeeReader(r.Body, &buf))
|
||||||
|
|
||||||
var fd io.ReadCloser = r.Body
|
var fd io.ReadCloser = r.Body
|
||||||
if r.URL.Path == "/3/upload" {
|
if r.URL.Path == "/3/upload" {
|
||||||
span.AddEvent("Imgur Emulation")
|
span.AddEvent("Imgur Emulation")
|
||||||
@@ -128,15 +130,19 @@ func (a *image) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
rdr = base64.NewDecoder(base64.StdEncoding, rdr)
|
rdr = base64.NewDecoder(base64.StdEncoding, rdr)
|
||||||
}
|
}
|
||||||
fd = io.NopCloser(rdr)
|
fd = io.NopCloser(rdr)
|
||||||
} else if fd, _, err = r.FormFile("image"); err != nil {
|
} else if mp, hd, err := r.FormFile("image"); err == nil {
|
||||||
if err != nil {
|
defer mp.Close()
|
||||||
span.RecordError(err)
|
span.AddEvent(fmt.Sprint(hd))
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
fd = mp
|
||||||
return
|
} else if mp, hd, err := r.FormFile("file"); err == nil {
|
||||||
}
|
defer mp.Close()
|
||||||
defer fd.Close()
|
span.AddEvent(fmt.Sprint(hd))
|
||||||
|
fd = mp
|
||||||
|
} else if err != nil {
|
||||||
|
span.RecordError(err)
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
} else {
|
} else {
|
||||||
w.WriteHeader(http.StatusCreated)
|
w.WriteHeader(http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|||||||
2
main.go
2
main.go
@@ -18,7 +18,7 @@ var apps service.Apps
|
|||||||
var appName, version = service.AppName()
|
var appName, version = service.AppName()
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
|
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
||||||
go func() {
|
go func() {
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
defer cancel() // restore interrupt function
|
defer cancel() // restore interrupt function
|
||||||
|
|||||||
19
paste/public/index.html
Normal file
19
paste/public/index.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
|
||||||
|
<meta name="theme-color" content="#000000">
|
||||||
|
|
||||||
|
<link rel="manifest" href="/ui/manifest.json">
|
||||||
|
<link rel="shortcut icon" href="/ui/favicon.ico">
|
||||||
|
|
||||||
|
<title>DN42 Paste</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||||
|
<link href="paste.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
0
paste/public/paste.css
Normal file
0
paste/public/paste.css
Normal file
114
paste/service.go
Normal file
114
paste/service.go
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
package paste
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"go.sour.is/paste/v2/assets"
|
||||||
|
"go.sour.is/pkg/lg"
|
||||||
|
)
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
ui http.Handler
|
||||||
|
paste *Paste
|
||||||
|
randBytes int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewService(store string, randBytes int64) (*service, error) {
|
||||||
|
p, err := New(store)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &service{
|
||||||
|
ui: http.FileServer(http.FS(assets.GetUI())),
|
||||||
|
paste: p,
|
||||||
|
randBytes: int(randBytes),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *service) RegisterHTTP(mux *http.ServeMux) {
|
||||||
|
mux.Handle("/ui/", lg.Htrace(http.StripPrefix("/ui/", a.ui), "paste-assets"))
|
||||||
|
|
||||||
|
mux.Handle("/api", http.StripPrefix("/api", a))
|
||||||
|
mux.Handle("/api/", http.StripPrefix("/api/", a))
|
||||||
|
|
||||||
|
mux.Handle("/paste", http.StripPrefix("/paste", a))
|
||||||
|
mux.Handle("/paste/", http.StripPrefix("/paste/", a))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch r.Method {
|
||||||
|
case http.MethodGet:
|
||||||
|
switch {
|
||||||
|
case strings.HasPrefix(r.URL.Path, "rng"):
|
||||||
|
p.getRandom(w)
|
||||||
|
|
||||||
|
case strings.HasPrefix(r.URL.Path, "get"), r.URL.Path != "":
|
||||||
|
p.getPaste(w, strings.TrimPrefix(r.URL.Path, "get/"))
|
||||||
|
|
||||||
|
default:
|
||||||
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
case http.MethodPost:
|
||||||
|
switch {
|
||||||
|
case r.URL.Path == "":
|
||||||
|
p.postPaste(w, r)
|
||||||
|
|
||||||
|
default:
|
||||||
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *service) getRandom(w http.ResponseWriter) {
|
||||||
|
log.Println("get random")
|
||||||
|
s := make([]byte, p.randBytes)
|
||||||
|
_, _ = rand.Read(s)
|
||||||
|
|
||||||
|
w.Header().Set("content-type", "application/octet-stream")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
_, _ = w.Write(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *service) getPaste(w http.ResponseWriter, id string) {
|
||||||
|
log.Println("get paste", id)
|
||||||
|
w.Header().Set("content-type", "application/octet-stream")
|
||||||
|
|
||||||
|
err := p.paste.Get(w, id)
|
||||||
|
if err != nil {
|
||||||
|
switch {
|
||||||
|
case errors.Is(err, ErrGone):
|
||||||
|
w.WriteHeader(http.StatusGone)
|
||||||
|
case errors.Is(err, ErrNotFound):
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
case errors.Is(err, ErrReadingContent):
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(w, "ERR %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *service) postPaste(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("content-type", "application/octet-stream")
|
||||||
|
|
||||||
|
id, err := p.paste.Set(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, "ERR %s", err)
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("post paste", id)
|
||||||
|
fmt.Fprint(w, "OK ", id)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user