chore: added model delete related to #2
This commit is contained in:
147
utils.go
147
utils.go
@@ -1,7 +1,150 @@
|
||||
package main
|
||||
|
||||
import "net/url"
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func checkEmpty(f url.Values, path string) bool {
|
||||
return !f.Has(path) || f.Get(path) == ""
|
||||
return !f.Has(path) || f.Get(path) == ""
|
||||
}
|
||||
|
||||
func checkId(f url.Values, path string) bool {
|
||||
return !checkEmpty(f, path) && isValidUUID(f.Get(path))
|
||||
}
|
||||
|
||||
func isValidUUID(u string) bool {
|
||||
_, err := uuid.Parse(u)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func getIdFromUrl(r *http.Request, target string) (string, error) {
|
||||
if !r.URL.Query().Has(target) {
|
||||
return "", errors.New("Query does not have " + target)
|
||||
}
|
||||
|
||||
id := r.URL.Query().Get("id")
|
||||
if len(id) == 0 {
|
||||
return "", errors.New("Query is empty for " + target)
|
||||
}
|
||||
|
||||
if !isValidUUID(id) {
|
||||
return "", errors.New("Value of query is not a valid uuid for " + target)
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
type maxBytesReader struct {
|
||||
w http.ResponseWriter
|
||||
r io.ReadCloser // underlying reader
|
||||
i int64 // max bytes initially, for MaxBytesError
|
||||
n int64 // max bytes remaining
|
||||
err error // sticky error
|
||||
}
|
||||
|
||||
type MaxBytesError struct {
|
||||
Limit int64
|
||||
}
|
||||
|
||||
func (e *MaxBytesError) Error() string {
|
||||
// Due to Hyrum's law, this text cannot be changed.
|
||||
return "http: request body too large"
|
||||
}
|
||||
|
||||
func (l *maxBytesReader) Read(p []byte) (n int, err error) {
|
||||
if l.err != nil {
|
||||
return 0, l.err
|
||||
}
|
||||
if len(p) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
// If they asked for a 32KB byte read but only 5 bytes are
|
||||
// remaining, no need to read 32KB. 6 bytes will answer the
|
||||
// question of the whether we hit the limit or go past it.
|
||||
// 0 < len(p) < 2^63
|
||||
if int64(len(p))-1 > l.n {
|
||||
p = p[:l.n+1]
|
||||
}
|
||||
n, err = l.r.Read(p)
|
||||
|
||||
if int64(n) <= l.n {
|
||||
l.n -= int64(n)
|
||||
l.err = err
|
||||
return n, err
|
||||
}
|
||||
|
||||
n = int(l.n)
|
||||
l.n = 0
|
||||
|
||||
// The server code and client code both use
|
||||
// maxBytesReader. This "requestTooLarge" check is
|
||||
// only used by the server code. To prevent binaries
|
||||
// which only using the HTTP Client code (such as
|
||||
// cmd/go) from also linking in the HTTP server, don't
|
||||
// use a static type assertion to the server
|
||||
// "*response" type. Check this interface instead:
|
||||
type requestTooLarger interface {
|
||||
requestTooLarge()
|
||||
}
|
||||
if res, ok := l.w.(requestTooLarger); ok {
|
||||
res.requestTooLarge()
|
||||
}
|
||||
l.err = &MaxBytesError{l.i}
|
||||
return n, l.err
|
||||
}
|
||||
|
||||
func (l *maxBytesReader) Close() error {
|
||||
return l.r.Close()
|
||||
}
|
||||
|
||||
func MyParseForm(r *http.Request) (vs url.Values, err error) {
|
||||
if r.Body == nil {
|
||||
err = errors.New("missing form body")
|
||||
return
|
||||
}
|
||||
ct := r.Header.Get("Content-Type")
|
||||
// RFC 7231, section 3.1.1.5 - empty type
|
||||
// MAY be treated as application/octet-stream
|
||||
if ct == "" {
|
||||
ct = "application/octet-stream"
|
||||
}
|
||||
ct, _, err = mime.ParseMediaType(ct)
|
||||
switch {
|
||||
case ct == "application/x-www-form-urlencoded":
|
||||
var reader io.Reader = r.Body
|
||||
maxFormSize := int64(1<<63 - 1)
|
||||
if _, ok := r.Body.(*maxBytesReader); !ok {
|
||||
maxFormSize = int64(10 << 20) // 10 MB is a lot of text.
|
||||
reader = io.LimitReader(r.Body, maxFormSize+1)
|
||||
}
|
||||
b, e := io.ReadAll(reader)
|
||||
if e != nil {
|
||||
if err == nil {
|
||||
err = e
|
||||
}
|
||||
break
|
||||
}
|
||||
if int64(len(b)) > maxFormSize {
|
||||
err = errors.New("http: POST too large")
|
||||
return
|
||||
}
|
||||
vs, e = url.ParseQuery(string(b))
|
||||
if err == nil {
|
||||
err = e
|
||||
}
|
||||
case ct == "multipart/form-data":
|
||||
// handled by ParseMultipartForm (which is calling us, or should be)
|
||||
// TODO(bradfitz): there are too many possible
|
||||
// orders to call too many functions here.
|
||||
// Clean this up and write more tests.
|
||||
// request_test.go contains the start of this,
|
||||
// in TestParseMultipartFormOrder and others.
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user