diff options
author | Ben Morrison <ben@gbmor.dev> | 2019-05-20 22:52:50 -0400 |
---|---|---|
committer | Ben Morrison <ben@gbmor.dev> | 2019-05-21 03:42:17 -0400 |
commit | df1d1efa19aed5bc6553c7c0a0b4b7dfe20e3bd0 (patch) | |
tree | 2a60f30829b8d1fca943aa3ca4a077cb4cb3517d | |
parent | a3c67f1ff9ed2cff44930f6bfd17a3ec272fe2f5 (diff) | |
download | getwtxt-df1d1efa19aed5bc6553c7c0a0b4b7dfe20e3bd0.tar.gz |
fleshed out POST handler, added remote registry list
-rw-r--r-- | handlers.go | 15 | ||||
-rw-r--r-- | http.go | 6 | ||||
-rw-r--r-- | init.go | 3 | ||||
-rw-r--r-- | post.go | 62 | ||||
-rw-r--r-- | types.go | 10 |
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 |