tcp.ac/txt.go

230 lines
5.9 KiB
Go
Raw Normal View History

2021-02-15 20:52:35 +00:00
package main
import (
2022-01-21 12:58:22 +00:00
"errors"
2022-07-08 20:23:20 +00:00
"net"
2022-01-21 12:58:22 +00:00
"strings"
2021-02-15 20:52:35 +00:00
valid "github.com/asaskevich/govalidator"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
"github.com/twharmon/gouid"
"golang.org/x/crypto/blake2b"
2022-01-21 12:58:22 +00:00
termbin "git.tcp.direct/kayos/putxt"
2022-07-08 20:23:20 +00:00
"git.tcp.direct/tcp.direct/tcp.ac/config"
2021-07-28 07:31:34 +00:00
)
func init() {
termbin.UseChannel = true
}
2021-02-15 20:52:35 +00:00
2021-07-28 07:31:34 +00:00
func incoming() {
var msg termbin.Message
select {
case msg = <-termbin.Msg:
switch msg.Type {
2022-01-21 12:58:22 +00:00
case termbin.Error:
2021-07-28 07:31:34 +00:00
log.Error().
Str("RemoteAddr", msg.RAddr).
Int("Size", msg.Size).
Msg(msg.Content)
2022-01-21 12:58:22 +00:00
case termbin.IncomingData:
2021-07-28 07:31:34 +00:00
log.Debug().
Str("RemoteAddr", msg.RAddr).
Int("Size", msg.Size).
Msg("termbin_data")
2022-01-21 12:58:22 +00:00
case termbin.Finish:
2021-07-28 07:31:34 +00:00
log.Debug().
Str("RemoteAddr", msg.RAddr).
Int("Size", msg.Size).
Msg(msg.Content)
2022-01-21 12:58:22 +00:00
case termbin.Debug:
2021-07-28 07:31:34 +00:00
log.Debug().
Str("RemoteAddr", msg.RAddr).
Int("Size", msg.Size).
Msg(msg.Content)
2022-01-21 12:58:22 +00:00
case termbin.Final:
2021-08-24 09:56:10 +00:00
log.Debug().
2021-07-28 07:31:34 +00:00
Str("RemoteAddr", msg.RAddr).
Int("Size", msg.Size).
Msg(msg.Content)
termPost(msg.Bytes)
}
}
2021-02-15 20:52:35 +00:00
}
2021-07-28 07:31:34 +00:00
func termPost(b []byte) {
slog := log.With().Str("caller", "termPost").Logger()
Hashr, _ := blake2b.New(64, nil)
Hashr.Write(b)
hash := Hashr.Sum(nil)
2022-01-21 12:58:22 +00:00
if ogTxt, _ := db.With("hsh").Get(hash); ogTxt != nil {
if db.With("txt").Has(ogTxt) {
2021-07-28 07:31:34 +00:00
slog.Debug().Str("ogUid", string(ogTxt)).Msg("duplicate file found! returning original URL")
post := &Post{
2022-01-21 12:58:22 +00:00
entryType: Text,
uid: string(ogTxt),
key: "",
priv: false,
2021-07-28 07:31:34 +00:00
}
2022-01-21 12:58:22 +00:00
termbin.Reply <- termbin.Message{Type: termbin.ReturnURL, Content: post.URLString()}
2021-07-28 07:31:34 +00:00
return
}
}
2021-02-15 20:52:35 +00:00
2021-07-28 07:31:34 +00:00
// generate new uid and delete key
2022-07-08 20:23:20 +00:00
uid := gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
key := gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
2021-02-15 20:52:35 +00:00
2021-07-28 07:31:34 +00:00
// lets make sure that we don't clash even though its highly unlikely
2022-01-21 12:58:22 +00:00
for uidRef, _ := db.With("txt").Get([]byte(uid)); uidRef != nil; {
2021-07-28 07:31:34 +00:00
slog.Info().Msg(" uid already exists! generating new...")
2022-07-08 20:23:20 +00:00
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
2021-02-15 20:52:35 +00:00
}
2022-01-21 12:58:22 +00:00
for keyRef, _ := db.With("key").Get([]byte(key)); keyRef != nil; {
2021-07-28 07:31:34 +00:00
slog.Info().Msg(" delete key already exists! generating new...")
2022-07-08 20:23:20 +00:00
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
2021-02-15 20:52:35 +00:00
}
2022-01-21 12:58:22 +00:00
db.With("hsh").Put(hash, []byte(uid))
2021-02-15 20:52:35 +00:00
2022-07-08 20:23:20 +00:00
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
2021-07-28 07:31:34 +00:00
2022-01-21 12:58:22 +00:00
for uidRef, _ := db.With("txt").Get([]byte(uid)); uidRef != nil; {
2021-07-28 07:31:34 +00:00
slog.Info().Msg(" uid already exists! generating new...")
2022-07-08 20:23:20 +00:00
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
2021-07-28 07:31:34 +00:00
}
2022-01-21 12:58:22 +00:00
for keyRef, _ := db.With("key").Get([]byte(key)); keyRef != nil; {
2021-07-28 07:31:34 +00:00
slog.Info().Msg(" delete key already exists! generating new...")
2022-07-08 20:23:20 +00:00
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
2021-02-15 20:52:35 +00:00
}
2022-01-21 12:58:22 +00:00
db.With("hsh").Put([]byte(hash), []byte(uid))
2021-02-15 20:52:35 +00:00
2022-01-21 12:58:22 +00:00
err := db.With("txt").Put([]byte(uid), b)
2021-02-15 20:52:35 +00:00
if err != nil {
2021-09-01 07:19:10 +00:00
slog.Error().Err(err).Msg("failed to save text!")
2022-01-21 12:58:22 +00:00
termbin.Reply <- termbin.Message{Type: termbin.ReturnURL, Content: "internal server error"}
2021-02-15 20:52:35 +00:00
return
}
2022-01-21 12:58:22 +00:00
err = db.With("key").Put([]byte(key), []byte("t."+uid))
2021-07-28 07:31:34 +00:00
if err != nil {
slog.Error().Msg("failed to save delete key!")
2022-01-21 12:58:22 +00:00
termbin.Reply <- termbin.Message{Type: termbin.ReturnError, Content: "internal server error"}
2021-02-15 20:52:35 +00:00
return
}
2021-07-28 07:31:34 +00:00
slog.Debug().Str("uid", uid).Msg("saved to database successfully, sending to Serve")
post := &Post{
2022-01-21 12:58:22 +00:00
entryType: Text,
uid: uid,
key: key,
priv: false,
2021-02-15 20:52:35 +00:00
}
2022-01-21 12:58:22 +00:00
termbin.Reply <- termbin.Message{Type: termbin.ReturnURL, Content: post.URLString()}
2021-02-15 20:52:35 +00:00
}
func txtView(c *gin.Context) {
2022-07-08 20:23:20 +00:00
raddr := net.ParseIP(c.RemoteIP())
2022-01-21 12:58:22 +00:00
if termbin.Rater.Check(&termbin.Identity{Actual: raddr}) {
errThrow(c, 429, errors.New("ratelimitted"), "too many requests")
2021-07-28 07:31:34 +00:00
return
}
2021-02-15 20:52:35 +00:00
sUid := strings.Split(c.Param("uid"), ".")
rUid := sUid[0]
2021-07-28 07:31:34 +00:00
fExt = ""
2021-02-15 20:52:35 +00:00
if len(sUid) > 1 {
fExt = strings.ToLower(sUid[1])
if fExt != "txt" {
2022-01-21 12:58:22 +00:00
errThrow(c, 400, errors.New("bad file extension"), "400")
2021-02-15 20:52:35 +00:00
return
}
}
2021-07-28 07:31:34 +00:00
// if it doesn't match the key size or it isn't alphanumeric - throw it out
2022-07-08 20:23:20 +00:00
if !valid.IsAlphanumeric(rUid) || len(rUid) != config.UIDSize {
2022-01-21 12:58:22 +00:00
errThrow(c, 400, errors.New("request discarded as invalid"), "400")
2021-02-15 20:52:35 +00:00
return
}
2021-07-28 07:31:34 +00:00
// query bitcask for the id
2022-01-21 12:58:22 +00:00
fBytes, _ := db.With("txt").Get([]byte(rUid))
2021-02-15 20:52:35 +00:00
if fBytes == nil {
2022-01-21 12:58:22 +00:00
errThrow(c, 404, errors.New("file not found"), "file not found")
2021-02-15 20:52:35 +00:00
return
}
2022-01-21 12:58:22 +00:00
file, err := termbin.Deflate(fBytes)
if err != nil {
errThrow(c, 500, err, "internal server error")
}
2021-07-28 07:31:34 +00:00
c.Data(200, "text/plain", file)
2021-02-15 20:52:35 +00:00
}
2021-07-28 07:31:34 +00:00
func txtDel(c *gin.Context) {
slog := log.With().
Str("caller", "txtDel").Logger()
2021-07-29 19:40:53 +00:00
slog.Debug().Msg("new_request")
2021-07-28 07:31:34 +00:00
if !validateKey(c.Param("key")) {
2022-01-21 12:58:22 +00:00
errThrow(c, 400, errors.New("bad key"), "400")
return
}
2021-07-28 07:31:34 +00:00
rKey := c.Param("key")
2022-01-21 12:58:22 +00:00
targetTxt, _ := db.With("key").Get([]byte(rKey))
2021-07-28 07:31:34 +00:00
if targetTxt == nil || !strings.Contains(string(targetTxt), "t.") {
2022-01-21 12:58:22 +00:00
errThrow(c, 400, errors.New("no txt delete entry found with provided key"), "400")
return
}
2021-07-28 07:31:34 +00:00
t := strings.Split(string(targetTxt), ".")[1]
2022-01-21 12:58:22 +00:00
if !db.With("txt").Has([]byte(t)) {
errThrow(c, 500, errors.New("image not found in database"), "500") // this shouldn't happen...?
2021-07-28 07:31:34 +00:00
return
}
2022-01-21 12:58:22 +00:00
if err := db.With("txt").Delete([]byte(t)); err != nil {
errThrow(c, 500, errors.New("delete failed"), "500")
return
}
2022-01-21 12:58:22 +00:00
if db.With("txt").Has([]byte(t)) {
2021-07-28 07:31:34 +00:00
slog.Error().Str("rkey", t).Msg("delete failed!?")
2022-01-21 12:58:22 +00:00
errThrow(c, 500, errors.New("delete failed, this shouldn't happen"), "500")
2021-07-28 07:31:34 +00:00
return
}
2021-02-15 20:52:35 +00:00
2021-07-29 19:40:53 +00:00
slog.Info().Str("rkey", t).Msg("Text file deleted successfully")
2021-07-28 07:31:34 +00:00
slog.Debug().Str("rkey", t).Msg("Removing delete key entry")
2022-01-21 12:58:22 +00:00
err := db.With("key").Delete([]byte(rKey))
2021-02-15 20:52:35 +00:00
if err != nil {
2021-07-28 07:31:34 +00:00
slog.Error().Str("rkey", t).Msg("Couldn't delete key")
2021-07-29 19:40:53 +00:00
}
c.JSON(200, "DELETE_SUCCESS")
2021-07-28 07:31:34 +00:00
}
2021-02-15 20:52:35 +00:00
2021-07-28 07:31:34 +00:00
func serveTermbin() {
go func() {
for {
incoming()
}
2021-07-28 07:31:34 +00:00
}()
2022-07-08 20:23:20 +00:00
split := strings.Split(config.TermbinListen, ":")
err := termbin.Listen(split[0], split[1])
2021-07-28 07:31:34 +00:00
if err != nil {
println(err.Error())
return
2021-02-15 20:52:35 +00:00
}
}