summaryrefslogtreecommitdiff
path: root/srv
diff options
context:
space:
mode:
Diffstat (limited to 'srv')
-rw-r--r--srv/cmd/mediocre-blog/mailinglist.go8
-rw-r--r--srv/cmd/mediocre-blog/main.go37
-rw-r--r--srv/cmd/mediocre-blog/pow.go2
-rw-r--r--srv/pow/pow.go9
4 files changed, 46 insertions, 10 deletions
diff --git a/srv/cmd/mediocre-blog/mailinglist.go b/srv/cmd/mediocre-blog/mailinglist.go
index 75e5b6d..4a1ddce 100644
--- a/srv/cmd/mediocre-blog/mailinglist.go
+++ b/srv/cmd/mediocre-blog/mailinglist.go
@@ -16,6 +16,7 @@ func mailingListSubscribeHandler(ml mailinglist.MailingList) http.Handler {
parts[1] == "" ||
len(email) >= 512 {
badRequest(rw, r, errors.New("invalid email"))
+ return
}
if err := ml.BeginSubscription(email); errors.Is(err, mailinglist.ErrAlreadyVerified) {
@@ -23,7 +24,10 @@ func mailingListSubscribeHandler(ml mailinglist.MailingList) http.Handler {
// verification email was sent.
} else if err != nil {
internalServerError(rw, r, err)
+ return
}
+
+ jsonResult(rw, r, struct{}{})
})
}
@@ -44,6 +48,8 @@ func mailingListFinalizeHandler(ml mailinglist.MailingList) http.Handler {
internalServerError(rw, r, err)
return
}
+
+ jsonResult(rw, r, struct{}{})
})
}
@@ -63,5 +69,7 @@ func mailingListUnsubscribeHandler(ml mailinglist.MailingList) http.Handler {
internalServerError(rw, r, err)
return
}
+
+ jsonResult(rw, r, struct{}{})
})
}
diff --git a/srv/cmd/mediocre-blog/main.go b/srv/cmd/mediocre-blog/main.go
index 5a00a48..748e10b 100644
--- a/srv/cmd/mediocre-blog/main.go
+++ b/srv/cmd/mediocre-blog/main.go
@@ -5,6 +5,8 @@ import (
"flag"
"fmt"
"net/http"
+ "net/http/httputil"
+ "net/url"
"path"
"strconv"
"strings"
@@ -26,11 +28,13 @@ func main() {
logger := mlog.NewLogger(nil)
hostname := flag.String("hostname", "localhost:4000", "Hostname to advertise this server as")
- staticDir := flag.String("static-dir", "", "Directory from which static files are served")
listenAddr := flag.String("listen-addr", ":4000", "Address to listen for HTTP requests on")
dataDir := flag.String("data-dir", ".", "Directory to use for long term storage")
- powTargetStr := flag.String("pow-target", "0x000FFFF", "Proof-of-work target, lower is more difficult")
+ staticDir := flag.String("static-dir", "", "Directory from which static files are served (mutually exclusive with -static-proxy-url)")
+ staticProxyURLStr := flag.String("static-proxy-url", "", "HTTP address from which static files are served (mutually exclusive with -static-dir)")
+
+ powTargetStr := flag.String("pow-target", "0x0000FFFF", "Proof-of-work target, lower is more difficult")
powSecret := flag.String("pow-secret", "", "Secret used to sign proof-of-work challenge seeds")
smtpAddr := flag.String("ml-smtp-addr", "", "Address of SMTP server to use for sending emails for the mailing list")
@@ -41,8 +45,8 @@ func main() {
flag.Parse()
switch {
- case *staticDir == "":
- logger.Fatal(context.Background(), "-static-dir is required")
+ case *staticDir == "" && *staticProxyURLStr == "":
+ logger.Fatal(context.Background(), "-static-dir or -static-proxy-url is required")
case *powSecret == "":
logger.Fatal(context.Background(), "-pow-secret is required")
case *smtpAddr == "":
@@ -51,6 +55,14 @@ func main() {
logger.Fatal(context.Background(), "-ml-smtp-auth is required")
}
+ var staticProxyURL *url.URL
+ if *staticProxyURLStr != "" {
+ var err error
+ if staticProxyURL, err = url.Parse(*staticProxyURLStr); err != nil {
+ loggerFatalErr(context.Background(), logger, "parsing -static-proxy-url", err)
+ }
+ }
+
powTargetUint, err := strconv.ParseUint(*powTargetStr, 0, 32)
if err != nil {
loggerFatalErr(context.Background(), logger, "parsing -pow-target", err)
@@ -68,7 +80,6 @@ func main() {
ctx := mctx.Annotate(context.Background(),
"hostname", *hostname,
- "staticDir", *staticDir,
"listenAddr", *listenAddr,
"dataDir", *dataDir,
"powTarget", fmt.Sprintf("%x", powTarget),
@@ -76,6 +87,12 @@ func main() {
"smtpSendAs", smtpSendAs,
)
+ if *staticDir != "" {
+ ctx = mctx.Annotate(ctx, "staticDir", *staticDir)
+ } else {
+ ctx = mctx.Annotate(ctx, "staticProxyURL", *staticProxyURLStr)
+ }
+
clock := clock.Realtime()
powStore := pow.NewMemoryStore(clock)
@@ -112,7 +129,15 @@ func main() {
})
mux := http.NewServeMux()
- mux.Handle("/", http.FileServer(http.Dir(*staticDir)))
+
+ var staticHandler http.Handler
+ if *staticDir != "" {
+ staticHandler = http.FileServer(http.Dir(*staticDir))
+ } else {
+ staticHandler = httputil.NewSingleHostReverseProxy(staticProxyURL)
+ }
+
+ mux.Handle("/", staticHandler)
apiMux := http.NewServeMux()
apiMux.Handle("/pow/challenge", newPowChallengeHandler(powMgr))
diff --git a/srv/cmd/mediocre-blog/pow.go b/srv/cmd/mediocre-blog/pow.go
index 8e64739..a505a64 100644
--- a/srv/cmd/mediocre-blog/pow.go
+++ b/srv/cmd/mediocre-blog/pow.go
@@ -11,6 +11,7 @@ import (
func newPowChallengeHandler(mgr pow.Manager) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+
challenge := mgr.NewChallenge()
jsonResult(rw, r, struct {
@@ -25,6 +26,7 @@ func newPowChallengeHandler(mgr pow.Manager) http.Handler {
func requirePowMiddleware(mgr pow.Manager, h http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+
seedHex := r.PostFormValue("powSeed")
seed, err := hex.DecodeString(seedHex)
if err != nil || len(seed) == 0 {
diff --git a/srv/pow/pow.go b/srv/pow/pow.go
index 3de1450..8075103 100644
--- a/srv/pow/pow.go
+++ b/srv/pow/pow.go
@@ -141,7 +141,7 @@ type Challenge struct {
// Errors which may be produced by a Manager.
var (
ErrInvalidSolution = errors.New("invalid solution")
- ErrExpiredSolution = errors.New("expired solution")
+ ErrExpiredSeed = errors.New("expired seed")
)
// Manager is used to both produce proof-of-work challenges and check their
@@ -150,7 +150,7 @@ type Manager interface {
NewChallenge() Challenge
// Will produce ErrInvalidSolution if the solution is invalid, or
- // ErrExpiredSolution if the solution has expired.
+ // ErrExpiredSeed if the seed has expired.
CheckSolution(seed, solution []byte) error
}
@@ -193,6 +193,7 @@ type manager struct {
// NewManager initializes and returns a Manager instance using the given
// parameters.
func NewManager(params ManagerParams) Manager {
+ params = params.withDefaults()
return &manager{
params: params,
}
@@ -252,8 +253,8 @@ func (m *manager) CheckSolution(seed, solution []byte) error {
if err != nil {
return fmt.Errorf("parsing challenge parameters from seed: %w", err)
- } else if c.ExpiresAt <= m.params.Clock.Now().Unix() {
- return ErrExpiredSolution
+ } else if now := m.params.Clock.Now().Unix(); c.ExpiresAt <= now {
+ return ErrExpiredSeed
}
ok := (SolutionChecker{}).Check(