Browse Source

Keep original file names

pull/123/head
xtrafrancyz 6 years ago
parent
commit
a31648586a
  1. 16
      backends/localfs/localfs.go
  2. 1
      backends/meta.go
  3. 34
      backends/s3/s3.go
  4. 2
      backends/storage.go
  5. 2
      delete.go
  6. 36
      display.go
  7. 3
      fileserve.go
  8. 9
      static/css/linx.css
  9. 8
      templates/base.html
  10. 4
      templates/display/base.html
  11. 2
      templates/display/file.html
  12. 2
      templates/index.html
  13. 79
      upload.go

16
backends/localfs/localfs.go

@ -18,6 +18,7 @@ type LocalfsBackend struct {
} }
type MetadataJSON struct { type MetadataJSON struct {
OriginalName string `json:"original_name"`
DeleteKey string `json:"delete_key"` DeleteKey string `json:"delete_key"`
Sha256sum string `json:"sha256sum"` Sha256sum string `json:"sha256sum"`
Mimetype string `json:"mimetype"` Mimetype string `json:"mimetype"`
@ -56,6 +57,7 @@ func (b LocalfsBackend) Head(key string) (metadata backends.Metadata, err error)
return metadata, backends.BadMetadata return metadata, backends.BadMetadata
} }
metadata.OriginalName = mjson.OriginalName
metadata.DeleteKey = mjson.DeleteKey metadata.DeleteKey = mjson.DeleteKey
metadata.Mimetype = mjson.Mimetype metadata.Mimetype = mjson.Mimetype
metadata.ArchiveFiles = mjson.ArchiveFiles metadata.ArchiveFiles = mjson.ArchiveFiles
@ -84,12 +86,13 @@ func (b LocalfsBackend) writeMetadata(key string, metadata backends.Metadata) er
metaPath := path.Join(b.metaPath, key) metaPath := path.Join(b.metaPath, key)
mjson := MetadataJSON{ mjson := MetadataJSON{
DeleteKey: metadata.DeleteKey,
Mimetype: metadata.Mimetype,
OriginalName: metadata.OriginalName,
DeleteKey: metadata.DeleteKey,
Mimetype: metadata.Mimetype,
ArchiveFiles: metadata.ArchiveFiles, ArchiveFiles: metadata.ArchiveFiles,
Sha256sum: metadata.Sha256sum,
Expiry: metadata.Expiry.Unix(),
Size: metadata.Size,
Sha256sum: metadata.Sha256sum,
Expiry: metadata.Expiry.Unix(),
Size: metadata.Size,
} }
dst, err := os.Create(metaPath) dst, err := os.Create(metaPath)
@ -108,7 +111,7 @@ func (b LocalfsBackend) writeMetadata(key string, metadata backends.Metadata) er
return nil return nil
} }
func (b LocalfsBackend) Put(key string, r io.Reader, expiry time.Time, deleteKey string) (m backends.Metadata, err error) {
func (b LocalfsBackend) Put(key string, originalName string, r io.Reader, expiry time.Time, deleteKey string) (m backends.Metadata, err error) {
filePath := path.Join(b.filesPath, key) filePath := path.Join(b.filesPath, key)
dst, err := os.Create(filePath) dst, err := os.Create(filePath)
@ -126,6 +129,7 @@ func (b LocalfsBackend) Put(key string, r io.Reader, expiry time.Time, deleteKey
return m, err return m, err
} }
m.OriginalName = originalName
m.Expiry = expiry m.Expiry = expiry
m.DeleteKey = deleteKey m.DeleteKey = deleteKey
m.Size = bytes m.Size = bytes

1
backends/meta.go

@ -6,6 +6,7 @@ import (
) )
type Metadata struct { type Metadata struct {
OriginalName string
DeleteKey string DeleteKey string
Sha256sum string Sha256sum string
Mimetype string Mimetype string

34
backends/s3/s3.go

@ -18,13 +18,13 @@ import (
type S3Backend struct { type S3Backend struct {
bucket string bucket string
svc *s3.S3
svc *s3.S3
} }
func (b S3Backend) Delete(key string) error { func (b S3Backend) Delete(key string) error {
_, err := b.svc.DeleteObject(&s3.DeleteObjectInput{ _, err := b.svc.DeleteObject(&s3.DeleteObjectInput{
Bucket: aws.String(b.bucket), Bucket: aws.String(b.bucket),
Key: aws.String(key),
Key: aws.String(key),
}) })
if err != nil { if err != nil {
return err return err
@ -35,7 +35,7 @@ func (b S3Backend) Delete(key string) error {
func (b S3Backend) Exists(key string) (bool, error) { func (b S3Backend) Exists(key string) (bool, error) {
_, err := b.svc.HeadObject(&s3.HeadObjectInput{ _, err := b.svc.HeadObject(&s3.HeadObjectInput{
Bucket: aws.String(b.bucket), Bucket: aws.String(b.bucket),
Key: aws.String(key),
Key: aws.String(key),
}) })
return err == nil, err return err == nil, err
} }
@ -44,7 +44,7 @@ func (b S3Backend) Head(key string) (metadata backends.Metadata, err error) {
var result *s3.HeadObjectOutput var result *s3.HeadObjectOutput
result, err = b.svc.HeadObject(&s3.HeadObjectInput{ result, err = b.svc.HeadObject(&s3.HeadObjectInput{
Bucket: aws.String(b.bucket), Bucket: aws.String(b.bucket),
Key: aws.String(key),
Key: aws.String(key),
}) })
if err != nil { if err != nil {
if aerr, ok := err.(awserr.Error); ok { if aerr, ok := err.(awserr.Error); ok {
@ -63,7 +63,7 @@ func (b S3Backend) Get(key string) (metadata backends.Metadata, r io.ReadCloser,
var result *s3.GetObjectOutput var result *s3.GetObjectOutput
result, err = b.svc.GetObject(&s3.GetObjectInput{ result, err = b.svc.GetObject(&s3.GetObjectInput{
Bucket: aws.String(b.bucket), Bucket: aws.String(b.bucket),
Key: aws.String(key),
Key: aws.String(key),
}) })
if err != nil { if err != nil {
if aerr, ok := err.(awserr.Error); ok { if aerr, ok := err.(awserr.Error); ok {
@ -81,11 +81,12 @@ func (b S3Backend) Get(key string) (metadata backends.Metadata, r io.ReadCloser,
func mapMetadata(m backends.Metadata) map[string]*string { func mapMetadata(m backends.Metadata) map[string]*string {
return map[string]*string{ return map[string]*string{
"Expiry": aws.String(strconv.FormatInt(m.Expiry.Unix(), 10)),
"Delete_key": aws.String(m.DeleteKey),
"Size": aws.String(strconv.FormatInt(m.Size, 10)),
"Mimetype": aws.String(m.Mimetype),
"Sha256sum": aws.String(m.Sha256sum),
"Original_name": aws.String(m.OriginalName),
"Expiry": aws.String(strconv.FormatInt(m.Expiry.Unix(), 10)),
"Delete_key": aws.String(m.DeleteKey),
"Size": aws.String(strconv.FormatInt(m.Size, 10)),
"Mimetype": aws.String(m.Mimetype),
"Sha256sum": aws.String(m.Sha256sum),
} }
} }
@ -101,13 +102,14 @@ func unmapMetadata(input map[string]*string) (m backends.Metadata, err error) {
return return
} }
m.OriginalName = aws.StringValue(input["Original_name"])
m.DeleteKey = aws.StringValue(input["Delete_key"]) m.DeleteKey = aws.StringValue(input["Delete_key"])
m.Mimetype = aws.StringValue(input["Mimetype"]) m.Mimetype = aws.StringValue(input["Mimetype"])
m.Sha256sum = aws.StringValue(input["Sha256sum"]) m.Sha256sum = aws.StringValue(input["Sha256sum"])
return return
} }
func (b S3Backend) Put(key string, r io.Reader, expiry time.Time, deleteKey string) (m backends.Metadata, err error) {
func (b S3Backend) Put(key string, originalName string, r io.Reader, expiry time.Time, deleteKey string) (m backends.Metadata, err error) {
tmpDst, err := ioutil.TempFile("", "linx-server-upload") tmpDst, err := ioutil.TempFile("", "linx-server-upload")
if err != nil { if err != nil {
return m, err return m, err
@ -122,6 +124,7 @@ func (b S3Backend) Put(key string, r io.Reader, expiry time.Time, deleteKey stri
return m, err return m, err
} }
m.OriginalName = originalName
m.Expiry = expiry m.Expiry = expiry
m.DeleteKey = deleteKey m.DeleteKey = deleteKey
m.Size = bytes m.Size = bytes
@ -132,9 +135,9 @@ func (b S3Backend) Put(key string, r io.Reader, expiry time.Time, deleteKey stri
uploader := s3manager.NewUploaderWithClient(b.svc) uploader := s3manager.NewUploaderWithClient(b.svc)
input := &s3manager.UploadInput{ input := &s3manager.UploadInput{
Bucket: aws.String(b.bucket),
Key: aws.String(key),
Body: tmpDst,
Bucket: aws.String(b.bucket),
Key: aws.String(key),
Body: tmpDst,
Metadata: mapMetadata(m), Metadata: mapMetadata(m),
} }
_, err = uploader.Upload(input) _, err = uploader.Upload(input)
@ -148,7 +151,7 @@ func (b S3Backend) Put(key string, r io.Reader, expiry time.Time, deleteKey stri
func (b S3Backend) Size(key string) (int64, error) { func (b S3Backend) Size(key string) (int64, error) {
input := &s3.HeadObjectInput{ input := &s3.HeadObjectInput{
Bucket: aws.String(b.bucket), Bucket: aws.String(b.bucket),
Key: aws.String(key),
Key: aws.String(key),
} }
result, err := b.svc.HeadObject(input) result, err := b.svc.HeadObject(input)
if err != nil { if err != nil {
@ -169,7 +172,6 @@ func (b S3Backend) List() ([]string, error) {
return nil, err return nil, err
} }
for _, object := range results.Contents { for _, object := range results.Contents {
output = append(output, *object.Key) output = append(output, *object.Key)
} }

2
backends/storage.go

@ -11,7 +11,7 @@ type StorageBackend interface {
Exists(key string) (bool, error) Exists(key string) (bool, error)
Head(key string) (Metadata, error) Head(key string) (Metadata, error)
Get(key string) (Metadata, io.ReadCloser, error) Get(key string) (Metadata, io.ReadCloser, error)
Put(key string, r io.Reader, expiry time.Time, deleteKey string) (Metadata, error)
Put(key string, originalName string, r io.Reader, expiry time.Time, deleteKey string) (Metadata, error)
Size(key string) (int64, error) Size(key string) (int64, error)
} }

2
delete.go

@ -30,7 +30,7 @@ func deleteHandler(c web.C, w http.ResponseWriter, r *http.Request) {
return return
} }
fmt.Fprintf(w, "DELETED")
_, _ = fmt.Fprintf(w, "DELETED")
return return
} else { } else {

36
display.go

@ -51,12 +51,13 @@ func fileDisplayHandler(c web.C, w http.ResponseWriter, r *http.Request) {
if strings.EqualFold("application/json", r.Header.Get("Accept")) { if strings.EqualFold("application/json", r.Header.Get("Accept")) {
js, _ := json.Marshal(map[string]string{ js, _ := json.Marshal(map[string]string{
"filename": fileName,
"direct_url": getSiteURL(r) + Config.selifPath + fileName,
"expiry": strconv.FormatInt(metadata.Expiry.Unix(), 10),
"size": strconv.FormatInt(metadata.Size, 10),
"mimetype": metadata.Mimetype,
"sha256sum": metadata.Sha256sum,
"original_name": metadata.OriginalName,
"filename": fileName,
"direct_url": getSiteURL(r) + Config.selifPath + fileName,
"expiry": strconv.FormatInt(metadata.Expiry.Unix(), 10),
"size": strconv.FormatInt(metadata.Size, 10),
"mimetype": metadata.Mimetype,
"sha256sum": metadata.Sha256sum,
}) })
w.Write(js) w.Write(js)
return return
@ -130,16 +131,21 @@ func fileDisplayHandler(c web.C, w http.ResponseWriter, r *http.Request) {
tpl = Templates["display/file.html"] tpl = Templates["display/file.html"]
} }
if metadata.OriginalName == "" {
metadata.OriginalName = fileName
}
err = renderTemplate(tpl, pongo2.Context{ err = renderTemplate(tpl, pongo2.Context{
"mime": metadata.Mimetype,
"filename": fileName,
"size": sizeHuman,
"expiry": expiryHuman,
"expirylist": listExpirationTimes(),
"extra": extra,
"forcerandom": Config.forceRandomFilename,
"lines": lines,
"files": metadata.ArchiveFiles,
"mime": metadata.Mimetype,
"original_name": metadata.OriginalName,
"filename": fileName,
"size": sizeHuman,
"expiry": expiryHuman,
"expirylist": listExpirationTimes(),
"extra": extra,
"forcerandom": Config.forceRandomFilename,
"lines": lines,
"files": metadata.ArchiveFiles,
}, r, w) }, r, w)
if err != nil { if err != nil {

3
fileserve.go

@ -40,6 +40,9 @@ func fileServeHandler(c web.C, w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Security-Policy", Config.fileContentSecurityPolicy) w.Header().Set("Content-Security-Policy", Config.fileContentSecurityPolicy)
w.Header().Set("Referrer-Policy", Config.fileReferrerPolicy) w.Header().Set("Referrer-Policy", Config.fileReferrerPolicy)
if metadata.OriginalName != "" {
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", metadata.OriginalName))
}
w.Header().Set("Content-Type", metadata.Mimetype) w.Header().Set("Content-Type", metadata.Mimetype)
w.Header().Set("Content-Length", strconv.FormatInt(metadata.Size, 10)) w.Header().Set("Content-Length", strconv.FormatInt(metadata.Size, 10))
w.Header().Set("Etag", fmt.Sprintf("\"%s\"", metadata.Sha256sum)) w.Header().Set("Etag", fmt.Sprintf("\"%s\"", metadata.Sha256sum))

9
static/css/linx.css

@ -74,6 +74,13 @@ body {
padding: 5px; padding: 5px;
} }
#filename {
max-width: 500px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.info-flex { .info-flex {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
@ -326,6 +333,8 @@ body {
.display-audio, .display-audio,
.display-file { .display-file {
width: 100%; width: 100%;
max-width: 1000px;
word-break: break-word;
} }
.display-image { .display-image {

8
templates/base.html

@ -4,7 +4,7 @@
<title>{% block title %}{{ sitename }}{% endblock %}</title> <title>{% block title %}{{ sitename }}{% endblock %}</title>
<meta charset='utf-8' content='text/html' http-equiv='content-type'> <meta charset='utf-8' content='text/html' http-equiv='content-type'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'> <meta name='viewport' content='width=device-width, initial-scale=1.0'>
<link href='{{ sitepath }}static/css/linx.css?v=1' media='screen, projection' rel='stylesheet' type='text/css'>
<link href='{{ sitepath }}static/css/linx.css?v=2' media='screen, projection' rel='stylesheet' type='text/css'>
<link href='{{ sitepath }}static/css/hint.css' rel='stylesheet' type='text/css'> <link href='{{ sitepath }}static/css/hint.css' rel='stylesheet' type='text/css'>
<link href='{{ sitepath }}static/images/favicon.gif' rel='icon' type='image/gif'> <link href='{{ sitepath }}static/images/favicon.gif' rel='icon' type='image/gif'>
{% block head %}{% endblock %} {% block head %}{% endblock %}
@ -16,8 +16,8 @@
<div id="header"> <div id="header">
<div id="navigation" class="right"> <div id="navigation" class="right">
{% if !using_auth %} {% if !using_auth %}
<a href="{{ sitepath }}">Upload</a> |
<a href="{{ sitepath }}paste/">Paste</a> |
<a href="{{ sitepath }}">Upload</a> |
<a href="{{ sitepath }}paste/">Paste</a> |
{% endif %} {% endif %}
<a href="{{ sitepath }}API/">API</a> <a href="{{ sitepath }}API/">API</a>
</div> </div>
@ -27,7 +27,7 @@
{% block content %}{% endblock %} {% block content %}{% endblock %}
<div id="footer"> <div id="footer">
<a href="https://github.com/andreimarcu/linx-server">linx</a>
<a href="https://github.com/xtrafrancyz/linx-server">linx</a>
</div> </div>
</div> </div>

4
templates/display/base.html

@ -1,6 +1,6 @@
{% extends "../base.html" %} {% extends "../base.html" %}
{% block title %}{{ filename }}{% endblock %}
{% block title %}{{ original_name }}{% endblock %}
{% block bodymore %}{% endblock %} {% block bodymore %}{% endblock %}
@ -8,7 +8,7 @@
<div id="info" class="dinfo info-flex"> <div id="info" class="dinfo info-flex">
<div id="filename"> <div id="filename">
{{ filename }}
{{ original_name }}
</div> </div>
<div class="info-actions"> <div class="info-actions">

2
templates/display/file.html

@ -2,7 +2,7 @@
{% block main %} {% block main %}
<div class="normal display-file"> <div class="normal display-file">
<p class="center">You are requesting <a href="{{ sitepath }}{{ selifpath }}{{ filename }}">{{ filename }}</a>, click below to download.</p>
<p class="center">You are requesting <a href="{{ sitepath }}{{ selifpath }}{{ filename }}">{{ original_name }}</a>, click below to download.</p>
<a href="{{ sitepath }}{{ selifpath }}{{ filename }}" class="download-btn">Download</a> <a href="{{ sitepath }}{{ selifpath }}{{ filename }}" class="download-btn">Download</a>
{% if files|length > 0 %} {% if files|length > 0 %}

2
templates/index.html

@ -17,7 +17,7 @@
</div> </div>
<div id="choices"> <div id="choices">
<label>{% if not forcerandom %}<input name="randomize" id="randomize" type="checkbox" checked /> Randomize filename{% endif %}</label>
<label>{% if not forcerandom %}<input name="randomize" id="randomize" type="checkbox" /> Randomize filename{% endif %}</label>
<div id="expiry"> <div id="expiry">
<label>File expiry: <label>File expiry:
<select name="expires" id="expires"> <select name="expires" id="expires">

79
upload.go

@ -34,12 +34,12 @@ var fileBlacklist = map[string]bool{
// Describes metadata directly from the user request // Describes metadata directly from the user request
type UploadRequest struct { type UploadRequest struct {
src io.Reader
size int64
filename string
expiry time.Duration // Seconds until expiry, 0 = never
deleteKey string // Empty string if not defined
randomBarename bool
src io.Reader
size int64
filename string
expiry time.Duration // Seconds until expiry, 0 = never
deleteKey string // Empty string if not defined
randomize bool
} }
// Metadata associated with a file as it would actually be stored // Metadata associated with a file as it would actually be stored
@ -90,7 +90,7 @@ func uploadPostHandler(c web.C, w http.ResponseWriter, r *http.Request) {
upReq.expiry = parseExpiry(r.PostFormValue("expires")) upReq.expiry = parseExpiry(r.PostFormValue("expires"))
if r.PostFormValue("randomize") == "true" { if r.PostFormValue("randomize") == "true" {
upReq.randomBarename = true
upReq.randomize = true
} }
upload, err := processUpload(upReq) upload, err := processUpload(upReq)
@ -181,7 +181,7 @@ func uploadRemote(c web.C, w http.ResponseWriter, r *http.Request) {
upReq.filename = filepath.Base(grabUrl.Path) upReq.filename = filepath.Base(grabUrl.Path)
upReq.src = http.MaxBytesReader(w, resp.Body, Config.maxSize) upReq.src = http.MaxBytesReader(w, resp.Body, Config.maxSize)
upReq.deleteKey = r.FormValue("deletekey") upReq.deleteKey = r.FormValue("deletekey")
upReq.randomBarename = r.FormValue("randomize") == "yes"
upReq.randomize = r.FormValue("randomize") == "yes"
upReq.expiry = parseExpiry(r.FormValue("expiry")) upReq.expiry = parseExpiry(r.FormValue("expiry"))
upload, err := processUpload(upReq) upload, err := processUpload(upReq)
@ -207,7 +207,7 @@ func uploadRemote(c web.C, w http.ResponseWriter, r *http.Request) {
func uploadHeaderProcess(r *http.Request, upReq *UploadRequest) { func uploadHeaderProcess(r *http.Request, upReq *UploadRequest) {
if r.Header.Get("Linx-Randomize") == "yes" { if r.Header.Get("Linx-Randomize") == "yes" {
upReq.randomBarename = true
upReq.randomize = true
} }
upReq.deleteKey = r.Header.Get("Linx-Delete-Key") upReq.deleteKey = r.Header.Get("Linx-Delete-Key")
@ -223,14 +223,8 @@ func processUpload(upReq UploadRequest) (upload Upload, err error) {
} }
// Determine the appropriate filename // Determine the appropriate filename
barename, extension := barePlusExt(upReq.filename)
randomize := false
// Randomize the "barename" (filename without extension) if needed
if upReq.randomBarename || len(barename) == 0 {
barename = generateBarename()
randomize = true
}
_, extension := barePlusExt(upReq.filename)
slug := generateBarename()
var header []byte var header []byte
if len(extension) == 0 { if len(extension) == 0 {
@ -251,7 +245,7 @@ func processUpload(upReq UploadRequest) (upload Upload, err error) {
} }
} }
upload.Filename = strings.Join([]string{barename, extension}, ".")
upload.Filename = strings.Join([]string{slug, extension}, ".")
upload.Filename = strings.Replace(upload.Filename, " ", "", -1) upload.Filename = strings.Replace(upload.Filename, " ", "", -1)
fileexists, _ := storageBackend.Exists(upload.Filename) fileexists, _ := storageBackend.Exists(upload.Filename)
@ -262,35 +256,13 @@ func processUpload(upReq UploadRequest) (upload Upload, err error) {
if merr == nil { if merr == nil {
if upReq.deleteKey == metad.DeleteKey { if upReq.deleteKey == metad.DeleteKey {
fileexists = false fileexists = false
} else if Config.forceRandomFilename == true {
// the file exists
// the delete key doesn't match
// force random filenames is enabled
randomize = true
} }
} }
} else if Config.forceRandomFilename == true {
// the file doesn't exist
// force random filenames is enabled
randomize = true
// set fileexists to true to generate a new barename
fileexists = true
} }
for fileexists { for fileexists {
if randomize {
barename = generateBarename()
} else {
counter, err := strconv.Atoi(string(barename[len(barename)-1]))
if err != nil {
barename = barename + "1"
} else {
barename = barename[:len(barename)-1] + strconv.Itoa(counter+1)
}
}
upload.Filename = strings.Join([]string{barename, extension}, ".")
slug = generateBarename()
upload.Filename = strings.Join([]string{slug, extension}, ".")
fileexists, err = storageBackend.Exists(upload.Filename) fileexists, err = storageBackend.Exists(upload.Filename)
} }
@ -310,7 +282,11 @@ func processUpload(upReq UploadRequest) (upload Upload, err error) {
upReq.deleteKey = uniuri.NewLen(30) upReq.deleteKey = uniuri.NewLen(30)
} }
upload.Metadata, err = storageBackend.Put(upload.Filename, io.MultiReader(bytes.NewReader(header), upReq.src), fileExpiry, upReq.deleteKey)
if Config.forceRandomFilename || upReq.randomize || len(slug) == 0 {
upReq.filename = upload.Filename
}
upload.Metadata, err = storageBackend.Put(upload.Filename, upReq.filename, io.MultiReader(bytes.NewReader(header), upReq.src), fileExpiry, upReq.deleteKey)
if err != nil { if err != nil {
return upload, err return upload, err
} }
@ -324,14 +300,15 @@ func generateBarename() string {
func generateJSONresponse(upload Upload, r *http.Request) []byte { func generateJSONresponse(upload Upload, r *http.Request) []byte {
js, _ := json.Marshal(map[string]string{ js, _ := json.Marshal(map[string]string{
"url": getSiteURL(r) + upload.Filename,
"direct_url": getSiteURL(r) + Config.selifPath + upload.Filename,
"filename": upload.Filename,
"delete_key": upload.Metadata.DeleteKey,
"expiry": strconv.FormatInt(upload.Metadata.Expiry.Unix(), 10),
"size": strconv.FormatInt(upload.Metadata.Size, 10),
"mimetype": upload.Metadata.Mimetype,
"sha256sum": upload.Metadata.Sha256sum,
"url": getSiteURL(r) + upload.Filename,
"direct_url": getSiteURL(r) + Config.selifPath + upload.Filename,
"filename": upload.Filename,
"original_name": upload.Metadata.OriginalName,
"delete_key": upload.Metadata.DeleteKey,
"expiry": strconv.FormatInt(upload.Metadata.Expiry.Unix(), 10),
"size": strconv.FormatInt(upload.Metadata.Size, 10),
"mimetype": upload.Metadata.Mimetype,
"sha256sum": upload.Metadata.Sha256sum,
}) })
return js return js

Loading…
Cancel
Save