summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorBen Morrison <ben@gbmor.dev>2019-05-20 22:52:50 -0400
committerBen Morrison <ben@gbmor.dev>2019-05-21 03:42:17 -0400
commitdf1d1efa19aed5bc6553c7c0a0b4b7dfe20e3bd0 (patch)
tree2a60f30829b8d1fca943aa3ca4a077cb4cb3517d
parenta3c67f1ff9ed2cff44930f6bfd17a3ec272fe2f5 (diff)
downloadgetwtxt-df1d1efa19aed5bc6553c7c0a0b4b7dfe20e3bd0.tar.gz
fleshed out POST handler, added remote registry list
-rw-r--r--handlers.go15
-rw-r--r--http.go6
-rw-r--r--init.go3
-rw-r--r--post.go62
-rw-r--r--types.go10
5 files changed, 80 insertions, 16 deletions
diff --git a/handlers.go b/handlers.go
index 4085f73..4ec511d 100644
--- a/handlers.go
+++ b/handlers.go
@@ -100,20 +100,7 @@ func apiEndpointHandler(w http.ResponseWriter, r *http.Request) {
 
 // handles POST for "/api/plain/users"
 func apiEndpointPOSTHandler(w http.ResponseWriter, r *http.Request) {
-
-	vars := mux.Vars(r)
-	format := vars["format"]
-	endpoint := vars["endpoint"]
-
-	w.Header().Set("Content-Type", htmlutf8)
-
-	_, err := w.Write([]byte(format + "/" + endpoint))
-	if err != nil {
-		log500(w, r, err)
-		return
-	}
-
-	log200(r)
+	apiPostUser(w, r)
 }
 
 // handles "/api/plain/tags"
diff --git a/http.go b/http.go
index 4b6d460..1f6126c 100644
--- a/http.go
+++ b/http.go
@@ -3,6 +3,7 @@ package main
 import (
 	"context"
 	"log"
+	"net"
 	"net/http"
 	"strings"
 )
@@ -17,14 +18,14 @@ func newCtxUserIP(ctx context.Context, r *http.Request) context.Context {
 }
 
 // Retrieves a request's IP address from the request's context
-func getIPFromCtx(ctx context.Context) string {
+func getIPFromCtx(ctx context.Context) net.IP {
 
 	uip, ok := ctx.Value(ctxKey).(string)
 	if !ok {
 		log.Printf("Couldn't retrieve IP from request\n")
 	}
 
-	return uip
+	return net.ParseIP(uip)
 }
 
 // Shim function to modify/pass context value to a handler
@@ -47,6 +48,7 @@ func log200(r *http.Request) {
 func log400(w http.ResponseWriter, r *http.Request, err error) {
 	uip := getIPFromCtx(r.Context())
 	log.Printf("*** %v :: 400 :: %v %v :: %v\n", uip, r.Method, r.URL, err)
+	http.Error(w, err.Error(), http.StatusBadRequest)
 }
 
 // log output for 404s
diff --git a/init.go b/init.go
index 60530ea..08ac5b6 100644
--- a/init.go
+++ b/init.go
@@ -32,6 +32,9 @@ var tmpls *template.Template
 // registry index
 var twtxtCache = registry.NewIndex()
 
+// remote registry listing
+var remote = &RemoteRegistries{}
+
 func init() {
 	checkFlags()
 	titleScreen()
diff --git a/post.go b/post.go
new file mode 100644
index 0000000..5091a0e
--- /dev/null
+++ b/post.go
@@ -0,0 +1,62 @@
+package main
+
+import (
+	"fmt"
+	"net/http"
+
+	"github.com/getwtxt/registry"
+)
+
+// Requests to apiEndpointPOSTHandler are passed off to this
+// function. apiPostUser then fetches the twtxt data, then if
+// it's an individual user's file, adds it. If it's registry
+// output, it scrapes the users/urls/statuses from the remote
+// registry before adding each user to the local cache.
+func apiPostUser(w http.ResponseWriter, r *http.Request) {
+	if err := r.ParseForm(); err != nil {
+		log400(w, r, err)
+		return
+	}
+	nick := r.FormValue("nickname")
+	urls := r.FormValue("url")
+	if nick == "" || urls == "" {
+		log400(w, r, fmt.Errorf("nickname or URL missing"))
+		return
+	}
+
+	uip := getIPFromCtx(r.Context())
+
+	out, remoteRegistry, err := registry.GetTwtxt(urls)
+	if err != nil {
+		log400(w, r, err)
+		return
+	}
+
+	if remoteRegistry {
+		remote.Mu.Lock()
+		remote.List = append(remote.List, urls)
+		remote.Mu.Unlock()
+
+		err := twtxtCache.ScrapeRemoteRegistry(urls)
+		if err != nil {
+			log400(w, r, err)
+			return
+		}
+		log200(r)
+		return
+	}
+
+	statuses, err := registry.ParseUserTwtxt(out)
+	if err != nil {
+		log400(w, r, err)
+		return
+	}
+
+	err = twtxtCache.AddUser(nick, urls, uip, statuses)
+	if err != nil {
+		log400(w, r, err)
+		return
+	}
+
+	log200(r)
+}
diff --git a/types.go b/types.go
index b5f27ce..018e26e 100644
--- a/types.go
+++ b/types.go
@@ -1,5 +1,7 @@
 package main
 
+import "sync"
+
 // content-type consts
 const txtutf8 = "text/plain; charset=utf-8"
 const htmlutf8 = "text/html; charset=utf-8"
@@ -23,6 +25,14 @@ type Instance struct {
 	Desc  string
 }
 
+// RemoteRegistries holds a list of remote registries to
+// periodically scrape for new users. The remote registries
+// must have been added via POST like a user.
+type RemoteRegistries struct {
+	Mu   sync.RWMutex
+	List []string
+}
+
 // ipCtxKey is the Context value key for user IP addresses
 type ipCtxKey int