Compare commits

...

2 commits

Author SHA1 Message Date
Felix Niederwanger 0fca18e731 Merge pull request 'Add content filename' (#1) from filename into main
Reviewed-on: https://codeberg.org/grisu48/pasta/pulls/1
2023-01-12 17:37:11 +00:00
Felix Niederwanger 5ce9043876
Add content filename
Add the ability to optionally also store the content filename.
2023-01-12 18:34:45 +01:00
3 changed files with 57 additions and 21 deletions

View file

@ -74,13 +74,27 @@ func usage() {
fmt.Println(" --ls, --list List known pasta pushes")
fmt.Println(" --gc Garbage collector (clean expired pastas)")
fmt.Println("")
fmt.Println("One or more files can be fined which will be pushed to the given server")
fmt.Println("If no file is given, the input from stdin will be pushed")
fmt.Println("One or more files can be pushed to the server.")
fmt.Println("If no file is given, the input from stdin will be pushed.")
}
func push(src io.Reader) (Pasta, error) {
func push(filename string, mime string, src io.Reader) (Pasta, error) {
pasta := Pasta{}
resp, err := http.Post(cf.RemoteHost+"?ret=json", "text/plain", src)
client := &http.Client{}
// For compatability reasons, set the return format in URL and header for some time
req, err := http.NewRequest("POST", cf.RemoteHost+"?ret=json", src)
if err != nil {
return pasta, err
}
req.Header.Set("Return-Format", "json")
if mime != "" {
req.Header.Set("Content-Type", mime)
}
if filename != "" {
req.Header.Set("Filename", filename)
}
resp, err := client.Do(req)
if err != nil {
return pasta, err
}
@ -182,6 +196,13 @@ func main() {
action = "rm"
} else if arg == "--gc" {
action = "gc"
} else if arg == "--" {
// The rest are filenames
if i+1 < len(args) {
files = append(files, args[i+1:]...)
}
i = len(args)
continue
} else {
fmt.Fprintf(os.Stderr, "Invalid argument: %s\n", arg)
os.Exit(1)
@ -252,8 +273,9 @@ func main() {
continue
}
// Push file
pasta, err := push(file)
pasta.Filename = getFilename(filename)
f_name := getFilename(filename)
pasta, err := push(f_name, "", file)
pasta.Filename = f_name
pasta.Date = time.Now().Unix()
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
@ -272,7 +294,7 @@ func main() {
} else {
fmt.Fprintln(os.Stderr, "Reading from stdin")
reader := bufio.NewReader(os.Stdin)
pasta, err := push(reader)
pasta, err := push("", "text/plain", reader)
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)

View file

@ -238,10 +238,15 @@ func SendPasta(pasta Pasta, w http.ResponseWriter) error {
return err
}
defer file.Close()
w.Header().Set("Content-Disposition", "inline")
w.Header().Set("Content-Length", strconv.FormatInt(pasta.Size, 10))
if pasta.Mime != "" {
w.Header().Set("Content-Type", pasta.Mime)
}
if pasta.ContentFilename != "" {
w.Header().Set("Filename", pasta.ContentFilename)
}
_, err = io.Copy(w, file)
return err
}
@ -286,7 +291,7 @@ ServerError:
func receive(reader io.Reader, pasta *Pasta) error {
buf := make([]byte, 4096)
file, err := os.OpenFile(pasta.Filename, os.O_RDWR|os.O_APPEND, 0640)
file, err := os.OpenFile(pasta.DiskFilename, os.O_RDWR|os.O_APPEND, 0640)
if err != nil {
file.Close()
return err
@ -419,7 +424,7 @@ func ReceivePasta(r *http.Request) (Pasta, error) {
if pasta.Size == 0 {
bowl.DeletePasta(pasta.Id)
pasta.Id = ""
pasta.Filename = ""
pasta.DiskFilename = ""
pasta.Token = ""
pasta.ExpireDate = 0
return pasta, nil
@ -527,9 +532,9 @@ func handlerPost(w http.ResponseWriter, r *http.Request) {
log.Printf("Received bin %s (%d bytes) from %s", pasta.Id, pasta.Size, r.RemoteAddr)
w.WriteHeader(http.StatusOK)
url := fmt.Sprintf("%s/%s", cf.BaseUrl, pasta.Id)
// Return format
// Return format. URL has precedence over http heder
retFormat := r.Header.Get("Return-Format")
retFormats := r.URL.Query()["ret"]
retFormat := ""
if len(retFormats) > 0 {
retFormat = retFormats[0]
}
@ -696,6 +701,7 @@ func handlerIndex(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "<h3>Text paste</h3>")
fmt.Fprintf(w, "<p>Just paste your contents in the textfield and hit the <tt>pasta</tt> button below</p>\n")
fmt.Fprintf(w, "<form method=\"post\" action=\"/?input=form&ret=html\">\n")
fmt.Fprintf(w, "Filename (optional): <input type=\"text\" name=\"filename\" value=\"\" max=\"255\"><br/>\n")
if cf.MaxPastaSize > 0 {
fmt.Fprintf(w, "<textarea name=\"content\" rows=\"10\" cols=\"80\" maxlength=\"%d\"></textarea><br/>\n", cf.MaxPastaSize)
} else {

View file

@ -14,12 +14,13 @@ import (
)
type Pasta struct {
Id string // id of the pasta
Token string // modification token
Filename string // filename for the pasta on the disk
ExpireDate int64 // Unix() date when it will expire
Size int64 // file size
Mime string // mime type
Id string // id of the pasta
Token string // modification token
DiskFilename string // filename for the pasta on the disk
ContentFilename string // Filename of the content
ExpireDate int64 // Unix() date when it will expire
Size int64 // file size
Mime string // mime type
}
func (pasta *Pasta) Expired() bool {
@ -124,7 +125,7 @@ func (bowl *PastaBowl) RemoveExpired() error {
// get pasta metadata
func (bowl *PastaBowl) GetPasta(id string) (Pasta, error) {
pasta := Pasta{Id: "", Filename: bowl.filename(id)}
pasta := Pasta{Id: "", DiskFilename: bowl.filename(id)}
stat, err := os.Stat(bowl.filename(id))
if err != nil {
// Does not exists results in empty pasta result
@ -134,7 +135,7 @@ func (bowl *PastaBowl) GetPasta(id string) (Pasta, error) {
return pasta, err
}
pasta.Size = stat.Size()
file, err := os.OpenFile(pasta.Filename, os.O_RDONLY, 0400)
file, err := os.OpenFile(pasta.DiskFilename, os.O_RDONLY, 0400)
if err != nil {
return pasta, err
}
@ -162,6 +163,8 @@ func (bowl *PastaBowl) GetPasta(id string) (Pasta, error) {
pasta.ExpireDate, _ = strconv.ParseInt(value, 10, 64)
} else if name == "mime" {
pasta.Mime = value
} else if name == "filename" {
pasta.ContentFilename = value
}
}
@ -225,8 +228,8 @@ func (bowl *PastaBowl) InsertPasta(pasta *Pasta) error {
// TODO: Use crypto rand
pasta.Token = RandomString(16)
}
pasta.Filename = bowl.filename(pasta.Id)
file, err := os.OpenFile(pasta.Filename, os.O_RDWR|os.O_CREATE, 0640)
pasta.DiskFilename = bowl.filename(pasta.Id)
file, err := os.OpenFile(pasta.DiskFilename, os.O_RDWR|os.O_CREATE, 0640)
if err != nil {
return err
}
@ -244,6 +247,11 @@ func (bowl *PastaBowl) InsertPasta(pasta *Pasta) error {
return err
}
}
if pasta.ContentFilename != "" {
if _, err := file.Write([]byte(fmt.Sprintf("filename:%s\n", pasta.ContentFilename))); err != nil {
return err
}
}
if _, err := file.Write([]byte("---\n")); err != nil {
return err