chore: fixes to paste ui
This commit is contained in:
parent
9a26239aa7
commit
83df53a655
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"files": {
|
"files": {
|
||||||
"main.css": "/ui/static/css/main.d4025777.css",
|
"main.css": "/ui/static/css/main.d4025777.css",
|
||||||
"main.js": "/ui/static/js/main.1d06557a.js",
|
"main.js": "/ui/static/js/main.939bead5.js",
|
||||||
"index.html": "/ui/index.html",
|
"index.html": "/ui/index.html",
|
||||||
"main.d4025777.css.map": "/ui/static/css/main.d4025777.css.map",
|
"main.d4025777.css.map": "/ui/static/css/main.d4025777.css.map",
|
||||||
"main.1d06557a.js.map": "/ui/static/js/main.1d06557a.js.map"
|
"main.939bead5.js.map": "/ui/static/js/main.939bead5.js.map"
|
||||||
},
|
},
|
||||||
"entrypoints": [
|
"entrypoints": [
|
||||||
"static/css/main.d4025777.css",
|
"static/css/main.d4025777.css",
|
||||||
"static/js/main.1d06557a.js"
|
"static/js/main.939bead5.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1 +1 @@
|
||||||
<!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><script defer="defer" src="/ui/static/js/main.1d06557a.js"></script><link href="/ui/static/css/main.d4025777.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
<!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><script defer="defer" src="/ui/static/js/main.939bead5.js"></script><link href="/ui/static/css/main.d4025777.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -200,17 +200,17 @@ class Paste extends Component {
|
||||||
onSubmit(event) {
|
onSubmit(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const { plain } = this.state;
|
const { plain } = this.state;
|
||||||
const { history } = this.props;
|
// const { history } = this.props;
|
||||||
|
|
||||||
this.encrypt(plain).then(([hash, decryptKey]) => { history.push('/#/' + hash + '!' + decryptKey) });
|
this.encrypt(plain).then(([hash, decryptKey]) => { history.pushState({}, '', '/ui/#/' + hash + '!' + decryptKey) });
|
||||||
}
|
}
|
||||||
onNew(event) {
|
onNew(event) {
|
||||||
const { history } = this.props;
|
// const { history } = this.props;
|
||||||
this.setState({cipher:"", plain:"", hash: "", decryptKey: "", syntax: "text", expire: 604800, burn: false}, () => history.push('/'));
|
this.setState({cipher:"", plain:"", hash: "", decryptKey: "", syntax: "text", expire: 604800, burn: false}, () => history.pushState({}, '', '/ui'));
|
||||||
}
|
}
|
||||||
onCopy(event) {
|
onCopy(event) {
|
||||||
const { history } = this.props;
|
// const { history } = this.props;
|
||||||
this.setState({hash: "", decryptKey: ""}, () => history.push('/'))
|
this.setState({hash: "", decryptKey: ""}, () => history.pushState({}, '', '/ui'))
|
||||||
}
|
}
|
||||||
|
|
||||||
decrypt(tx) {
|
decrypt(tx) {
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -5,6 +5,7 @@ go 1.21
|
||||||
require (
|
require (
|
||||||
github.com/gomarkdown/markdown v0.0.0-20200824053859-8c8b3816f167
|
github.com/gomarkdown/markdown v0.0.0-20200824053859-8c8b3816f167
|
||||||
github.com/h2non/filetype v1.1.0
|
github.com/h2non/filetype v1.1.0
|
||||||
|
github.com/matryer/is v1.4.1
|
||||||
github.com/rs/cors v1.6.0
|
github.com/rs/cors v1.6.0
|
||||||
go.opentelemetry.io/otel v1.18.0
|
go.opentelemetry.io/otel v1.18.0
|
||||||
go.opentelemetry.io/otel/trace v1.18.0
|
go.opentelemetry.io/otel/trace v1.18.0
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -64,15 +65,26 @@ func (a *image) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
a.get(ctx, w, name)
|
a.get(ctx, w, name)
|
||||||
case http.MethodPost:
|
case http.MethodPost:
|
||||||
var err error
|
var err error
|
||||||
|
defer r.Body.Close()
|
||||||
|
|
||||||
var fd io.ReadCloser = r.Body
|
var fd io.ReadCloser = r.Body
|
||||||
if r.URL.Path == "/3/upload" {
|
if r.URL.Path == "/3/upload" {
|
||||||
fd, _, err = r.FormFile("image")
|
span.AddEvent("Imgur Emulation")
|
||||||
|
var head *multipart.FileHeader
|
||||||
|
fd, head, err = r.FormFile("image")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
span.RecordError(err)
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
|
||||||
|
fmt.Println(head)
|
||||||
|
|
||||||
|
dec := base64.NewDecoder(base64.StdEncoding, fd)
|
||||||
|
fd = io.NopCloser(dec)
|
||||||
}
|
}
|
||||||
|
|
||||||
length := 0
|
length := 0
|
||||||
if h := r.Header.Get("Content-Length"); h != "" {
|
if h := r.Header.Get("Content-Length"); h != "" {
|
||||||
if i, err := strconv.Atoi(h); err != nil {
|
if i, err := strconv.Atoi(h); err != nil {
|
||||||
|
@ -80,34 +92,40 @@ func (a *image) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id, err := a.put(ctx, w, fd, length)
|
id, err := a.put(ctx, w, fd, length)
|
||||||
switch {
|
if err != nil {
|
||||||
case errors.Is(err, ErrGone):
|
switch {
|
||||||
w.WriteHeader(http.StatusGone)
|
case errors.Is(err, ErrGone):
|
||||||
case errors.Is(err, ErrNotFound):
|
w.WriteHeader(http.StatusGone)
|
||||||
w.WriteHeader(http.StatusNotFound)
|
case errors.Is(err, ErrNotFound):
|
||||||
case errors.Is(err, ErrReadingContent):
|
w.WriteHeader(http.StatusNotFound)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
case errors.Is(err, ErrReadingContent):
|
||||||
case errors.Is(err, ErrUnsupportedType):
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
w.WriteHeader(http.StatusUnsupportedMediaType)
|
case errors.Is(err, ErrUnsupportedType):
|
||||||
|
w.WriteHeader(http.StatusUnsupportedMediaType)
|
||||||
|
}
|
||||||
|
span.RecordError(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type data struct{
|
type data struct {
|
||||||
Link string `json:"link"`
|
Link string `json:"link"`
|
||||||
DeleteHash string `json:"deletehash"`
|
DeleteHash string `json:"deletehash"`
|
||||||
}
|
}
|
||||||
var resp = struct{
|
var resp = struct {
|
||||||
Data data `json:"data"`
|
Data data `json:"data"`
|
||||||
Success bool `json:"success"`
|
Success bool `json:"success"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
}{
|
}{
|
||||||
Data: data{
|
Data: data{
|
||||||
Link: fmt.Sprintf("https://%s/i/%s", r.Host, id),
|
Link: fmt.Sprintf("https://%s/i/%s", r.Host, id),
|
||||||
},
|
},
|
||||||
Success: true,
|
Success: true,
|
||||||
Status: 200,
|
Status: 200,
|
||||||
}
|
}
|
||||||
|
|
||||||
json.NewEncoder(w).Encode(resp)
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
err = json.NewEncoder(w).Encode(resp)
|
||||||
|
span.RecordError(err)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||||
|
@ -165,6 +183,7 @@ func (a *image) put(ctx context.Context, w http.ResponseWriter, r io.ReadCloser,
|
||||||
rdr := io.LimitReader(r, a.maxSize)
|
rdr := io.LimitReader(r, a.maxSize)
|
||||||
pr := readutil.NewPreviewReader(rdr)
|
pr := readutil.NewPreviewReader(rdr)
|
||||||
if !isImageOrVideo(pr) {
|
if !isImageOrVideo(pr) {
|
||||||
|
span.AddEvent("not image")
|
||||||
return "", ErrUnsupportedType
|
return "", ErrUnsupportedType
|
||||||
}
|
}
|
||||||
rdr = pr.Drain()
|
rdr = pr.Drain()
|
||||||
|
@ -172,6 +191,7 @@ func (a *image) put(ctx context.Context, w http.ResponseWriter, r io.ReadCloser,
|
||||||
s256 := sha256.New()
|
s256 := sha256.New()
|
||||||
tmp, err := os.CreateTemp(a.store, "image-")
|
tmp, err := os.CreateTemp(a.store, "image-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
span.RecordError(err)
|
||||||
return "", fmt.Errorf("%w: %w", ErrBadInput, err)
|
return "", fmt.Errorf("%w: %w", ErrBadInput, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +199,7 @@ func (a *image) put(ctx context.Context, w http.ResponseWriter, r io.ReadCloser,
|
||||||
|
|
||||||
m := io.MultiWriter(s256, tmp)
|
m := io.MultiWriter(s256, tmp)
|
||||||
if _, err := io.Copy(m, rdr); err != nil {
|
if _, err := io.Copy(m, rdr); err != nil {
|
||||||
|
span.RecordError(err)
|
||||||
return "", fmt.Errorf("%w: %w", ErrBadInput, err)
|
return "", fmt.Errorf("%w: %w", ErrBadInput, err)
|
||||||
}
|
}
|
||||||
tmp.Close()
|
tmp.Close()
|
||||||
|
|
67
image/image_test.go
Normal file
67
image/image_test.go
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package image_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
"mime/multipart"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/matryer/is"
|
||||||
|
"go.sour.is/paste/v2/image"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPostImgur(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
|
|
||||||
|
data := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg=="
|
||||||
|
|
||||||
|
dir, err := os.MkdirTemp("", "image")
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
im, err := image.New(dir, 0)
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
{
|
||||||
|
body := &bytes.Buffer{}
|
||||||
|
wr := multipart.NewWriter(body)
|
||||||
|
w, err := wr.CreateFormFile("image", "image.png")
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
fmt.Fprint(w, data)
|
||||||
|
err = wr.Close()
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
t.Log(body.String())
|
||||||
|
|
||||||
|
req := httptest.NewRequest("POST", "/3/upload", body)
|
||||||
|
req.Header.Set("Content-Type", "multipart/form-data; boundary="+wr.Boundary())
|
||||||
|
res := httptest.NewRecorder()
|
||||||
|
|
||||||
|
im.ServeHTTP(res, req)
|
||||||
|
|
||||||
|
is.Equal(res.Code, http.StatusCreated)
|
||||||
|
is.Equal(res.Body.String(), `{"data":{"link":"https://example.com/i/Igg59VTi6JNuXVriXMR3U_lzfAc","deletehash":""},"success":true,"status":200}
|
||||||
|
`)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
req := httptest.NewRequest("GET", "/Igg59VTi6JNuXVriXMR3U_lzfAc", nil)
|
||||||
|
res := httptest.NewRecorder()
|
||||||
|
|
||||||
|
im.ServeHTTP(res, req)
|
||||||
|
|
||||||
|
is.Equal(res.Code, http.StatusOK)
|
||||||
|
|
||||||
|
s := base64.StdEncoding.EncodeToString(res.Body.Bytes())
|
||||||
|
is.Equal(s, data)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.RemoveAll(dir)
|
||||||
|
is.NoErr(err)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user