diff --git a/src/pkg/promise/promise.go b/src/pkg/promise/promise.go index 6b607b3..34531ad 100644 --- a/src/pkg/promise/promise.go +++ b/src/pkg/promise/promise.go @@ -120,7 +120,9 @@ func (tr *Runner) Run(key Key, fn Fn, opts ...Option) *qTask { tr.queue[key.Key()] = task tr.mu.Unlock() + log.Debug("Waiting for limiter") tr.limiter.Take() + log.Debug("Got tag from limiter") go func() { defer func() { @@ -156,7 +158,7 @@ func NewRunner(ctx context.Context, defaultOpts ...Option) *Runner { ctx: ctx, cancel: cancel, pause: make(chan struct{}), - limiter: ratelimit.New(1), + limiter: ratelimit.New(10), } return tr diff --git a/src/routes/preview-reader.go b/src/pkg/readutil/preview-reader.go similarity index 98% rename from src/routes/preview-reader.go rename to src/pkg/readutil/preview-reader.go index 2e6a7ce..ae45f39 100644 --- a/src/routes/preview-reader.go +++ b/src/pkg/readutil/preview-reader.go @@ -1,4 +1,4 @@ -package routes +package readutil import ( "bytes" diff --git a/src/routes/artifact.go b/src/routes/artifact.go index 15af559..ccb8aa0 100644 --- a/src/routes/artifact.go +++ b/src/routes/artifact.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/gorilla/mux" + "sour.is/x/paste/src/pkg/readutil" "sour.is/x/toolbox/httpsrv" "sour.is/x/toolbox/log" @@ -87,7 +88,7 @@ func (a *Artifact) get(w http.ResponseWriter, r *http.Request) { defer f.Close() if !hasPath { - pr := NewPreviewReader(f) + pr := readutil.NewPreviewReader(f) mime, err := ReadMIME(pr, name) if err != nil { @@ -165,7 +166,7 @@ func (a *Artifact) get(w http.ResponseWriter, r *http.Request) { return } - pr := NewPreviewReader(tr) + pr := readutil.NewPreviewReader(tr) mime, err := ReadMIME(pr, hdr.Name) if err != nil { @@ -197,7 +198,7 @@ func (a *Artifact) put(w http.ResponseWriter, r *http.Request) { } rdr := io.LimitReader(r.Body, 500*1024*1024) - pr := NewPreviewReader(rdr) + pr := readutil.NewPreviewReader(rdr) rdr = pr.Drain() s256 := sha256.New() diff --git a/src/routes/decompress.go b/src/routes/decompress.go index 2bb2481..1151b73 100644 --- a/src/routes/decompress.go +++ b/src/routes/decompress.go @@ -7,11 +7,12 @@ import ( "github.com/andybalholm/brotli" xz "github.com/remyoudompheng/go-liblzma" + "sour.is/x/paste/src/pkg/readutil" "sour.is/x/toolbox/log" ) func Decompress(in io.Reader) (io.Reader, error) { - rdr := NewPreviewReader(in) + rdr := readutil.NewPreviewReader(in) mime, err := ReadMIMEWithSize(rdr, "", 32768) if err != nil { return rdr.Drain(), err diff --git a/src/routes/identity.go b/src/routes/identity.go index 75224ed..49da65d 100644 --- a/src/routes/identity.go +++ b/src/routes/identity.go @@ -97,6 +97,7 @@ func (s *identity) get(w http.ResponseWriter, r *http.Request) { return } + log.Infos("Scheduling Style", "email", entity.Primary.Address) q.Run(StyleKey(entity.Primary.Address), func(q promise.Q) { ctx := q.Context() key := q.Key().(StyleKey) @@ -108,18 +109,26 @@ func (s *identity) get(w http.ResponseWriter, r *http.Request) { return } + log.Notice("Resolving Style") q.Resolve(style) }) - for i := range entity.Proofs { - q.Run(ProofKey(entity.Proofs[i]), func(q promise.Q) { - key := q.Key().(ProofKey) - proof := NewProof(string(key)) + go func() { - q.Resolve(proof) - }) - } + log.Infos("Scheduling Proofs", "num", len(entity.Proofs)) + for i := range entity.Proofs { + q.Run(ProofKey(entity.Proofs[i]), func(q promise.Q) { + key := q.Key().(ProofKey) + proof := NewProof(string(key)) + proof.Checked = true + proof.Verified = true + log.Notice("Resolving Proof") + q.Resolve(proof) + }) + } + }() + log.Notice("Resolving Entity") q.Resolve(entity) }) @@ -388,7 +397,7 @@ func (s *identity) getStyle(ctx context.Context, email string) (*Style, error) { style.Palette = getPalette(fmt.Sprintf("#%x", id[:3])) style.Avatar = fmt.Sprintf("https://%s/avatar/%x", avatarHost, id) style.Cover = pixl - style.Background = pixl + style.Background = "https://lavana.sour.is/bg/52548b3dcb032882675afe1e4bcba0e9" if styleHost != "" { style.Cover = fmt.Sprintf("https://%s/cover/%x", styleHost, id) @@ -402,7 +411,7 @@ func styleSRV(ctx context.Context, email string) (avatar string, style string, e // Defaults style = "" - avatar = "cdn.libravatar.org" + avatar = "www.gravatar.com" parts := strings.SplitN(email, "@", 2) if _, srv, err := net.DefaultResolver.LookupSRV(ctx, "style-sec", "tcp", parts[1]); err == nil { @@ -503,18 +512,48 @@ func NewProof(uri string) *Proof { switch u.Scheme { case "dns": - p.Icon = "link" + p.Icon = "fas fa-globe" p.Name = u.Opaque p.Link = fmt.Sprintf("https://%s", u.Hostname()) + case "xmpp": + p.Icon = "fas fa-comments" + p.Name = u.Opaque + case "https": - p.Icon = "link" + p.Icon = "fas fa-atlas" p.Name = u.Hostname() p.Link = fmt.Sprintf("https://%s", u.Hostname()) - case "xmpp": - p.Icon = "comments" - p.Name = u.Hostname() + switch { + case strings.HasPrefix(u.Host, "twitter.com"): + p.Icon = "fab fa-twitter" + p.Service = "Twitter" + case strings.HasPrefix(u.Host, "news.ycombinator.com"): + p.Icon = "fab fa-hacker-news" + p.Service = "HackerNews" + case strings.HasPrefix(u.Host, "dev.to"): + p.Icon = "fab fa-dev" + p.Service = "dev.to" + case strings.HasPrefix(u.Host, "reddit.com"), strings.HasPrefix(u.Host, "www.reddit.com"): + p.Icon = "fab fa-reddit" + p.Service = "Reddit" + case strings.HasPrefix(u.Host, "gist.github.com"): + p.Icon = "fab fa-github" + p.Service = "GitHub" + case strings.HasPrefix(u.Host, "lobste.rs"): + p.Icon = "fas fa-list-ul" + p.Service = "Lobsters" + case strings.HasSuffix(u.Host, "/gitlab_proof/"): + p.Icon = "fab fa-gitlab" + p.Service = "GetLab" + case strings.HasSuffix(u.Host, "/gitea_proof/"): + p.Icon = "fas fa-mug-hot" + p.Service = "Gitea" + default: + p.Icon = "fas fa-project-diagram" + p.Service = "fediverse" + } } return p @@ -600,6 +639,11 @@ var identityTPL = `

{{.Primary.Name}}

{{.Fingerprint}}

+ {{else}} +
+

Loading...

+

Reading key from remote service.

+
{{end}} {{end}} @@ -619,13 +663,28 @@ var identityTPL = ` {{end}} {{with .Proofs}} -
+
Proofs

+ {{else}} +
+
Proofs
+
Loading...
+
+
{{end}}
diff --git a/src/routes/image.go b/src/routes/image.go index 4e44277..9f8fa2a 100644 --- a/src/routes/image.go +++ b/src/routes/image.go @@ -15,6 +15,8 @@ import ( "github.com/h2non/filetype" "sour.is/x/toolbox/httpsrv" "sour.is/x/toolbox/log" + + "sour.is/x/paste/src/pkg/readutil" ) func init() { @@ -81,7 +83,7 @@ func (a *Image) get(w http.ResponseWriter, r *http.Request) { } defer f.Close() - pr := NewPreviewReader(f) + pr := readutil.NewPreviewReader(f) mime, err := ReadMIME(pr, name) w.Header().Set("Content-Type", mime) @@ -105,7 +107,7 @@ func (a *Image) put(w http.ResponseWriter, r *http.Request) { } rdr := io.LimitReader(r.Body, a.maxSize) - pr := NewPreviewReader(rdr) + pr := readutil.NewPreviewReader(rdr) if !isImageOrVideo(pr) { httpsrv.WriteError(w, http.StatusUnsupportedMediaType, "ERR Not Image") return diff --git a/src/routes/paste.go b/src/routes/paste.go index 6749314..b3a583b 100644 --- a/src/routes/paste.go +++ b/src/routes/paste.go @@ -16,6 +16,7 @@ import ( "github.com/gorilla/mux" "golang.org/x/sys/unix" + "sour.is/x/paste/src/pkg/readutil" "sour.is/x/toolbox/httpsrv" "sour.is/x/toolbox/log" ) @@ -150,7 +151,7 @@ func (p *Paste) getPaste(w http.ResponseWriter, r *http.Request) { } defer f.Close() - pr := NewPreviewReader(f) + pr := readutil.NewPreviewReader(f) keep := true scanner := bufio.NewScanner(pr) diff --git a/src/routes/paste.go.db b/src/routes/paste.go.db deleted file mode 100644 index 826c99c..0000000 --- a/src/routes/paste.go.db +++ /dev/null @@ -1,195 +0,0 @@ -package routes - -import ( - "sour.is/x/httpsrv" - "os" - "golang.org/x/sys/unix" - "log" - "net/http" - "sour.is/x/ident" - "crypto/rand" - "encoding/base64" - "crypto/sha256" - "io/ioutil" - "io" - "bufio" - "github.com/gorilla/mux" - "strings" - "time" - "strconv" -) - -var store string -var randBytes int - -func init() { - httpsrv.RegisterModule("paste", SetConfig) - - httpsrv.IdentRegister("paste", httpsrv.IdentRoutes{ - { "Paste", "GET", "/paste/rng", GetRandom, }, - { "Paste", "GET", "/paste/{id}", GetPaste, }, - { "Paste", "GET", "/paste/get/{id}", GetPaste, }, - { "Paste", "POST", "/paste", PostPaste, }, - { "Paste", "DELETE", "/paste/{id}", DeletePaste, }, - - { "Paste", "GET", "/api/rng", GetRandom, }, - { "Paste", "GET", "/api/{id}", GetPaste, }, - { "Paste", "GET", "/api/get/{id}", GetPaste, }, - { "Paste", "POST", "/api", PostPaste, }, - { "Paste", "DELETE", "/api/{id}", DeletePaste, }, - }) -} - -func SetConfig (config map[string]string) { - - store = "data/" - if config["store"] != "" { - store = config["store"] - } - - if !chkStore(store) { - log.Fatalf("[routes::Paste] Store location [%s] does not exist or is not writable.", store) - } - - randBytes = 1024 - if config["random"] != "" { - randBytes, _ = strconv.Atoi(config["random"]) - } -} - -func chkStore(path string) bool { - file, err := os.Stat(path) - if err == nil { return true } - if os.IsNotExist(err) { return false } - if !file.IsDir() { return false } - if unix.Access(path, unix.W_OK & unix.R_OK) != nil { return false } - - return true -} - -func chkFile(path string) bool { - file, err := os.Stat(path) - if err == nil { return true } - if os.IsNotExist(err) { return false } - if file.IsDir() { return false } - if unix.Access(path, unix.W_OK & unix.R_OK) != nil { return false } - - return true -} - -func chkGone(path string) bool { - file, err := os.Stat(path) - if err != nil { return true } - if file.Size() == 0 { return true } - return false -} - -func GetRandom(w http.ResponseWriter, r *http.Request, i ident.Ident) { - w.WriteHeader(http.StatusOK) - w.Header().Set("content-type","application/octet-stream") - s := make([]byte, randBytes) - rand.Read(s) - - w.Write(s) -} - -func GetPaste(w http.ResponseWriter, r *http.Request, i ident.Ident) { - vars := mux.Vars(r) - id := vars["id"] - - if !chkFile(store + id) { - w.WriteHeader(http.StatusNotFound) - w.Write([]byte("ERR Not Found")) - return - } - - if chkGone(store + id) { - w.WriteHeader(http.StatusGone) - w.Write([]byte("ERR Gone")) - return - } - - head, err := os.Open(store + id) - if err != nil { - log.Fatal(err) - } - defer head.Close() - - keep := true - - scanner := bufio.NewScanner(head) - for scanner.Scan() { - txt := scanner.Text() - log.Println(txt) - if (txt == "") { - break - } - - if strings.HasPrefix(txt, "exp:") { - now := time.Now().Unix() - exp, err := strconv.ParseInt(strings.TrimSpace(strings.TrimPrefix(txt, "exp:")), 10, 64) - if err != nil { - log.Print(err) - } - - if now > exp { - log.Printf("%d > %d", now, exp) - w.WriteHeader(http.StatusGone) - w.Write([]byte("ERR Gone")) - - Delete(store + id) - - return - } - } - - if strings.HasPrefix(txt, "burn:") { - burn := strings.TrimSpace(strings.TrimPrefix(txt, "burn:")) - - if burn == "true" { - keep = false - } - } - } - - file, _ := os.Open(store + id) - defer file.Close() - - w.WriteHeader(http.StatusOK) - - scanner = bufio.NewScanner(file) - for scanner.Scan() { - w.Write(scanner.Bytes()) - w.Write([]byte("\n")) - } - - if !keep { - Delete(store + id) - } -} - -func PostPaste(w http.ResponseWriter, r *http.Request, i ident.Ident) { - body, _ := ioutil.ReadAll(io.LimitReader(r.Body, 1048576)) - - s256 := sha256.Sum256(body) - id := base64.RawURLEncoding.EncodeToString(s256[12:]) - - ioutil.WriteFile(store + id, body, 0644) - - w.WriteHeader(http.StatusCreated) - w.Write([]byte("OK " + id)) -} - -func DeletePaste(w http.ResponseWriter, r *http.Request, i ident.Ident) { - vars := mux.Vars(r) - id := vars["id"] - - Delete(store + id) - - w.WriteHeader(http.StatusNoContent) - w.Write([]byte("OK")) -} - -func Delete(path string) { - ioutil.WriteFile(path, []byte(""), 0644) -} \ No newline at end of file diff --git a/src/routes/read-mime.go b/src/routes/read-mime.go index f1005a7..17357bb 100644 --- a/src/routes/read-mime.go +++ b/src/routes/read-mime.go @@ -9,6 +9,7 @@ import ( "github.com/andybalholm/brotli" "github.com/h2non/filetype" "github.com/h2non/filetype/types" + "sour.is/x/paste/src/pkg/readutil" "sour.is/x/toolbox/log" ) @@ -24,7 +25,7 @@ func init() { func br(buf []byte) bool { var r io.Reader = bytes.NewReader(buf) - r = NewPreviewReader(r) + r = readutil.NewPreviewReader(r) br := brotli.NewReader(r) i, err := br.Read(make([]byte, 1)) log.Debugs("BR:", "i", i, "err", err)