summaryrefslogtreecommitdiffstats
path: root/internal/handler
diff options
context:
space:
mode:
authorGab Virebent <gabriel1@virebent.art>2026-06-20 01:07:45 +0000
committerGab Virebent <gabriel1@virebent.art>2026-06-20 01:07:45 +0000
commitaa459e3b84cc4c5d908f3781c9253848c18640c3 (patch)
tree8454b956cc0fa027034c8291f39d58ece469e10c /internal/handler
downloadnymdrop-aa459e3b84cc4c5d908f3781c9253848c18640c3.tar.gz
nymdrop-aa459e3b84cc4c5d908f3781c9253848c18640c3.tar.xz
nymdrop-aa459e3b84cc4c5d908f3781c9253848c18640c3.zip
Initial public release: Nym-native anonymous submission system
End-to-end verified pipeline (browser -> HTTP relay -> Nym mixnet -> reader). Client-side X25519+HKDF+AES-GCM-256, no-log blind relay, AGPL-3.0.
Diffstat (limited to 'internal/handler')
-rw-r--r--internal/handler/static.go19
-rw-r--r--internal/handler/submit.go33
2 files changed, 52 insertions, 0 deletions
diff --git a/internal/handler/static.go b/internal/handler/static.go
new file mode 100644
index 0000000..bf2aaec
--- /dev/null
+++ b/internal/handler/static.go
@@ -0,0 +1,19 @@
+package handler
+
+import (
+ "net/http"
+)
+
+func Static(dir string) http.Handler {
+ fs := http.FileServer(http.Dir(dir))
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // Security headers on every response.
+ w.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self'; style-src 'self'")
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+ w.Header().Set("Referrer-Policy", "no-referrer")
+ w.Header().Set("Permissions-Policy", "geolocation=(), microphone=(), camera=()")
+ w.Header().Set("X-Frame-Options", "DENY")
+ w.Header().Set("Cache-Control", "no-store")
+ fs.ServeHTTP(w, r)
+ })
+}
diff --git a/internal/handler/submit.go b/internal/handler/submit.go
new file mode 100644
index 0000000..15251cf
--- /dev/null
+++ b/internal/handler/submit.go
@@ -0,0 +1,33 @@
+package handler
+
+import (
+ "net/http"
+ "nymdrop/internal/relay"
+)
+
+type Submit struct {
+ relay *relay.Relay
+}
+
+func NewSubmit(r *relay.Relay) *Submit {
+ return &Submit{relay: r}
+}
+
+func (s *Submit) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ if r.Method != http.MethodPost {
+ http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
+ return
+ }
+
+ r.Body = http.MaxBytesReader(w, r.Body, 10*1024*1024)
+ defer r.Body.Close()
+
+ if err := s.relay.Forward(r.Body); err != nil {
+ // Generic error — reveal nothing about internals.
+ http.Error(w, "error", http.StatusInternalServerError)
+ return
+ }
+
+ w.WriteHeader(http.StatusOK)
+ w.Write([]byte("ok"))
+}