2017-10-06 07:19:02 +00:00
|
|
|
package contented
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2017-10-08 02:53:00 +00:00
|
|
|
"errors"
|
2023-05-17 06:54:30 +00:00
|
|
|
"fmt"
|
2017-10-08 03:01:41 +00:00
|
|
|
"log"
|
|
|
|
"net/http"
|
2017-10-06 07:19:02 +00:00
|
|
|
"os"
|
|
|
|
"time"
|
|
|
|
|
2017-10-08 02:53:00 +00:00
|
|
|
"github.com/speps/go-hashids"
|
2023-05-17 05:24:00 +00:00
|
|
|
bolt "go.etcd.io/bbolt"
|
2017-10-08 02:53:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
hashIdSalt = "contented"
|
|
|
|
hashIdMinLength = 2
|
2017-10-06 07:19:02 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Metadata struct {
|
2017-10-08 02:53:00 +00:00
|
|
|
FileHash string
|
2017-10-06 07:19:02 +00:00
|
|
|
FileSize int64
|
|
|
|
UploadTime time.Time
|
|
|
|
UploadIP string
|
|
|
|
Filename string
|
|
|
|
MimeType string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *Server) Metadata(fileID string) (*Metadata, error) {
|
|
|
|
var m Metadata
|
|
|
|
err := this.db.View(func(tx *bolt.Tx) error {
|
|
|
|
content := tx.Bucket(this.metadataBucket).Get([]byte(fileID))
|
|
|
|
if len(content) == 0 {
|
|
|
|
return os.ErrNotExist
|
|
|
|
}
|
|
|
|
|
|
|
|
return json.Unmarshal(content, &m)
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &m, nil
|
|
|
|
}
|
|
|
|
|
2017-10-08 02:53:00 +00:00
|
|
|
func idToString(v uint64) string {
|
|
|
|
hd := hashids.NewData()
|
|
|
|
hd.Salt = hashIdSalt
|
|
|
|
hd.MinLength = hashIdMinLength
|
2018-06-09 06:10:49 +00:00
|
|
|
h := hashids.NewWithData(hd)
|
2017-10-08 02:53:00 +00:00
|
|
|
s, _ := h.EncodeInt64([]int64{int64(v)})
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *Server) AddMetadata(m Metadata) (string, error) {
|
2017-10-06 07:19:02 +00:00
|
|
|
jb, err := json.Marshal(m)
|
|
|
|
if err != nil {
|
2017-10-08 02:53:00 +00:00
|
|
|
return "", err
|
2017-10-06 07:19:02 +00:00
|
|
|
}
|
|
|
|
|
2017-10-08 02:53:00 +00:00
|
|
|
var shortRef string = ""
|
|
|
|
|
|
|
|
err = this.db.Update(func(tx *bolt.Tx) error {
|
|
|
|
b := tx.Bucket(this.metadataBucket)
|
2023-05-17 06:54:30 +00:00
|
|
|
seq, err := b.NextSequence()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("NextSequence: %w", err)
|
|
|
|
}
|
2017-10-08 02:53:00 +00:00
|
|
|
shortRef = idToString(seq)
|
2023-05-17 06:54:30 +00:00
|
|
|
|
|
|
|
if b.Get([]byte(shortRef)) != nil {
|
|
|
|
return fmt.Errorf("Next bucket sequence %d creates colliding ID %s", seq, shortRef)
|
|
|
|
}
|
|
|
|
|
|
|
|
return b.Put([]byte(shortRef), jb)
|
2017-10-06 07:19:02 +00:00
|
|
|
})
|
2017-10-08 02:53:00 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
if shortRef == "" {
|
|
|
|
return "", errors.New("Invalid URL generated")
|
|
|
|
}
|
|
|
|
|
|
|
|
return shortRef, nil
|
2017-10-06 07:19:02 +00:00
|
|
|
}
|
2017-10-08 03:01:41 +00:00
|
|
|
|
|
|
|
func (this *Server) handleInformation(w http.ResponseWriter, fileID string) {
|
|
|
|
m, err := this.Metadata(fileID)
|
|
|
|
if err != nil {
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
http.Error(w, "Not found", 404)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Println(err.Error())
|
|
|
|
http.Error(w, "Internal error", 500)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
this.serveJsonObject(w, m)
|
|
|
|
}
|