mirror of
https://github.com/fiatjaf/khatru.git
synced 2026-04-08 14:36:47 +02:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b4d81dde4 | ||
|
|
7bfdbb557c | ||
|
|
3f26a1f727 | ||
|
|
76ecf4f791 | ||
|
|
1498da09c8 | ||
|
|
3d4dd71510 | ||
|
|
582a74c000 | ||
|
|
bbcf948dd6 | ||
|
|
553d848362 | ||
|
|
2a80d4099d | ||
|
|
ad6635d86c | ||
|
|
c93441cd63 | ||
|
|
dc34dd7e90 | ||
|
|
a004f59187 | ||
|
|
a931a83370 | ||
|
|
1c15db2ca1 |
@@ -9,6 +9,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/liamg/magic"
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
@@ -190,8 +191,14 @@ func (bs BlossomServer) handleGetBlob(w http.ResponseWriter, r *http.Request) {
|
||||
for _, lb := range bs.LoadBlob {
|
||||
reader, _ := lb(r.Context(), hhash)
|
||||
if reader != nil {
|
||||
w.Header().Add("Content-Type", mime.TypeByExtension(ext))
|
||||
io.Copy(w, reader)
|
||||
// use unix epoch as the time if we can't find the descriptor
|
||||
// as described in the http.ServeContent documentation
|
||||
t := time.Unix(0, 0)
|
||||
descriptor, err := bs.Store.Get(r.Context(), hhash)
|
||||
if err == nil && descriptor != nil {
|
||||
t = descriptor.Uploaded.Time()
|
||||
}
|
||||
http.ServeContent(w, r, hhash+ext, t, reader)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -257,7 +264,13 @@ func (bs BlossomServer) handleList(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.Write([]byte{'['})
|
||||
enc := json.NewEncoder(w)
|
||||
first := true
|
||||
for bd := range ch {
|
||||
if !first {
|
||||
w.Write([]byte{','})
|
||||
} else {
|
||||
first = false
|
||||
}
|
||||
enc.Encode(bd)
|
||||
}
|
||||
w.Write([]byte{']'})
|
||||
|
||||
@@ -15,7 +15,7 @@ type BlossomServer struct {
|
||||
Store BlobIndex
|
||||
|
||||
StoreBlob []func(ctx context.Context, sha256 string, body []byte) error
|
||||
LoadBlob []func(ctx context.Context, sha256 string) (io.Reader, error)
|
||||
LoadBlob []func(ctx context.Context, sha256 string) (io.ReadSeeker, error)
|
||||
DeleteBlob []func(ctx context.Context, sha256 string) error
|
||||
|
||||
RejectUpload []func(ctx context.Context, auth *nostr.Event, size int, ext string) (bool, string, int)
|
||||
@@ -35,33 +35,27 @@ func New(rl *khatru.Relay, serviceURL string) *BlossomServer {
|
||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path == "/upload" {
|
||||
if r.Method == "PUT" {
|
||||
setCors(w)
|
||||
bs.handleUpload(w, r)
|
||||
return
|
||||
} else if r.Method == "HEAD" {
|
||||
setCors(w)
|
||||
bs.handleUploadCheck(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(r.URL.Path, "/list/") && r.Method == "GET" {
|
||||
setCors(w)
|
||||
bs.handleList(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if len(strings.SplitN(r.URL.Path, ".", 2)[0]) == 65 {
|
||||
if r.Method == "HEAD" {
|
||||
setCors(w)
|
||||
bs.handleHasBlob(w, r)
|
||||
return
|
||||
} else if r.Method == "GET" {
|
||||
setCors(w)
|
||||
bs.handleGetBlob(w, r)
|
||||
return
|
||||
} else if r.Method == "DELETE" {
|
||||
setCors(w)
|
||||
bs.handleDelete(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -5,12 +5,6 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func setCors(w http.ResponseWriter) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("Access-Control-Allow-Headers", "Authorization")
|
||||
w.Header().Set("Access-Control-Allow-Methods", "GET PUT DELETE")
|
||||
}
|
||||
|
||||
func blossomError(w http.ResponseWriter, msg string, code int) {
|
||||
w.Header().Add("X-Reason", msg)
|
||||
w.WriteHeader(code)
|
||||
|
||||
@@ -3,7 +3,9 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/fiatjaf/eventstore/badger"
|
||||
"github.com/fiatjaf/khatru"
|
||||
@@ -29,9 +31,10 @@ func main() {
|
||||
fmt.Println("storing", sha256, len(body))
|
||||
return nil
|
||||
})
|
||||
bl.LoadBlob = append(bl.LoadBlob, func(ctx context.Context, sha256 string) ([]byte, error) {
|
||||
bl.LoadBlob = append(bl.LoadBlob, func(ctx context.Context, sha256 string) (io.ReadSeeker, error) {
|
||||
fmt.Println("loading", sha256)
|
||||
return []byte("aaaaa"), nil
|
||||
blob := strings.NewReader("aaaaa")
|
||||
return blob, nil
|
||||
})
|
||||
|
||||
fmt.Println("running on :3334")
|
||||
|
||||
6
go.mod
6
go.mod
@@ -5,11 +5,11 @@ go 1.23.1
|
||||
require (
|
||||
github.com/bep/debounce v1.2.1
|
||||
github.com/fasthttp/websocket v1.5.7
|
||||
github.com/fiatjaf/eventstore v0.12.0
|
||||
github.com/fiatjaf/eventstore v0.13.0
|
||||
github.com/liamg/magic v0.0.1
|
||||
github.com/nbd-wtf/go-nostr v0.40.0
|
||||
github.com/nbd-wtf/go-nostr v0.42.0
|
||||
github.com/puzpuzpuz/xsync/v3 v3.4.0
|
||||
github.com/rs/cors v1.7.0
|
||||
github.com/rs/cors v1.11.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
)
|
||||
|
||||
|
||||
10
go.sum
10
go.sum
@@ -53,8 +53,8 @@ github.com/fasthttp/websocket v1.5.7 h1:0a6o2OfeATvtGgoMKleURhLT6JqWPg7fYfWnH4KH
|
||||
github.com/fasthttp/websocket v1.5.7/go.mod h1:bC4fxSono9czeXHQUVKxsC0sNjbm7lPJR04GDFqClfU=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fiatjaf/eventstore v0.12.0 h1:ZdL+dZkIgBgIp5A3+3XLdPg/uucv5Tiws6DHzNfZG4M=
|
||||
github.com/fiatjaf/eventstore v0.12.0/go.mod h1:PxeYbZ3MsH0XLobANsp6c0cJjJYkfmBJ3TwrplFy/08=
|
||||
github.com/fiatjaf/eventstore v0.13.0 h1:60cE/oIUdVHoE6aOayjIyubiQIhMW6jezLjdvcl29Y4=
|
||||
github.com/fiatjaf/eventstore v0.13.0/go.mod h1:XOl5B6WGBX1a0ww6s3WT94QVOmye/6zDTtyWHVtHQ5U=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
@@ -121,8 +121,8 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI=
|
||||
github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/nbd-wtf/go-nostr v0.40.0 h1:ea7FlOsm4kO1071Tm4OT0lXTcyleiZCT9Ll4XERjTZw=
|
||||
github.com/nbd-wtf/go-nostr v0.40.0/go.mod h1:FBa4FBJO7NuANvkeKSlrf0BIyxGufmrUbuelr6Q4Ick=
|
||||
github.com/nbd-wtf/go-nostr v0.42.0 h1:EofWfXEhKic9AYVf4RHuXZr+kKUZE2jVyJtJByNe1rE=
|
||||
github.com/nbd-wtf/go-nostr v0.42.0/go.mod h1:FBa4FBJO7NuANvkeKSlrf0BIyxGufmrUbuelr6Q4Ick=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@@ -134,6 +134,8 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
||||
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk=
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||
|
||||
20
handlers.go
20
handlers.go
@@ -26,14 +26,28 @@ func (rl *Relay) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
rl.ServiceURL = getServiceBaseURL(r)
|
||||
}
|
||||
|
||||
corsMiddleware := cors.New(cors.Options{
|
||||
AllowedOrigins: []string{"*"},
|
||||
AllowedMethods: []string{
|
||||
http.MethodHead,
|
||||
http.MethodGet,
|
||||
http.MethodPost,
|
||||
http.MethodPut,
|
||||
http.MethodPatch,
|
||||
http.MethodDelete,
|
||||
},
|
||||
AllowedHeaders: []string{"Authorization", "*"},
|
||||
MaxAge: 86400,
|
||||
})
|
||||
|
||||
if r.Header.Get("Upgrade") == "websocket" {
|
||||
rl.HandleWebsocket(w, r)
|
||||
} else if r.Header.Get("Accept") == "application/nostr+json" {
|
||||
cors.AllowAll().Handler(http.HandlerFunc(rl.HandleNIP11)).ServeHTTP(w, r)
|
||||
corsMiddleware.Handler(http.HandlerFunc(rl.HandleNIP11)).ServeHTTP(w, r)
|
||||
} else if r.Header.Get("Content-Type") == "application/nostr+json+rpc" {
|
||||
cors.AllowAll().Handler(http.HandlerFunc(rl.HandleNIP86)).ServeHTTP(w, r)
|
||||
corsMiddleware.Handler(http.HandlerFunc(rl.HandleNIP86)).ServeHTTP(w, r)
|
||||
} else {
|
||||
rl.serveMux.ServeHTTP(w, r)
|
||||
corsMiddleware.Handler(rl.serveMux).ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/fiatjaf/eventstore"
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"github.com/nbd-wtf/go-nostr/nip77/negentropy"
|
||||
"github.com/nbd-wtf/go-nostr/nip77/negentropy/storage/vector"
|
||||
@@ -16,6 +17,8 @@ type NegentropySession struct {
|
||||
}
|
||||
|
||||
func (rl *Relay) startNegentropySession(ctx context.Context, filter nostr.Filter) (*vector.Vector, error) {
|
||||
ctx = eventstore.SetNegentropy(ctx)
|
||||
|
||||
// do the same overwrite/reject flow we do in normal REQs
|
||||
for _, ovw := range rl.OverwriteFilter {
|
||||
ovw(ctx, &filter)
|
||||
|
||||
@@ -72,7 +72,7 @@ func RestrictToSpecifiedKinds(allowEphemeral bool, kinds ...uint16) func(context
|
||||
slices.Sort(kinds)
|
||||
|
||||
return func(ctx context.Context, event *nostr.Event) (reject bool, msg string) {
|
||||
if allowEphemeral && event.IsEphemeral() {
|
||||
if allowEphemeral && nostr.IsEphemeralKind(event.Kind) {
|
||||
return false, ""
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user