aboutsummaryrefslogtreecommitdiff
path: root/server/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'server/server.go')
-rw-r--r--server/server.go108
1 files changed, 103 insertions, 5 deletions
diff --git a/server/server.go b/server/server.go
index 709888b..e84b4e0 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1,17 +1,115 @@
package main
import (
+ "crypto/sha256"
+ "encoding/hex"
+ "flag"
"fmt"
- "html"
+ "io"
"log"
"net/http"
+ "sort"
+ "strings"
+ "sync"
)
-func handler(w http.ResponseWriter, r *http.Request) {
- fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
+var mu sync.Mutex
+var me string
+var hashToDomain map[string]string
+var peerHashes []string
+var kvstore map[string]string
+
+func sha256sum(s string) string {
+ // Get the sha256sum of string as a hex string
+ b := sha256.Sum256([]byte(s))
+ return hex.EncodeToString(b[:])
+}
+
+func addPeer(peer string) error {
+ // Try to peer with another server
+ peerHash := sha256sum(peer)
+ // Check if already peered
+ mu.Lock()
+ _, ok := hashToDomain[peerHash]
+ mu.Unlock()
+ if ok {
+ return nil
+ }
+ mu.Lock()
+ hashToDomain[peerHash] = peer
+ mu.Unlock()
+
+ // Try request to peer
+ log.Printf("%s trying to peer with %s", me, peer)
+ resp, err := http.Get(peer + "/peer?peer=" + me)
+ if err != nil {
+ // Request failed, delete peer
+ mu.Lock()
+ delete(hashToDomain, peerHash)
+ mu.Unlock()
+ return err
+ }
+
+ log.Printf("%s successfully peered with %s", me, peer)
+ mu.Lock()
+ peerHashes = append(peerHashes, peerHash)
+ sort.Sort(sort.StringSlice(peerHashes))
+ mu.Unlock()
+ // Read response body
+ defer resp.Body.Close()
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+ // Try adding all peers of this peer
+ newPeers := strings.Split(string(body), "\n")
+ for _, newPeer := range newPeers[:len(newPeers)-1] {
+ go addPeer(newPeer)
+ }
+ return nil
+}
+
+func peerHandler(w http.ResponseWriter, r *http.Request) {
+ // Handle incoming peer requests
+ r.ParseForm()
+ peer := r.Form.Get("peer")
+ if peer == "" {
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ go addPeer(peer)
+ for _, p := range hashToDomain {
+ fmt.Fprintf(w, "%s\n", p)
+ }
+}
+
+func getHandler(w http.ResponseWriter, r *http.Request) {
+
+}
+
+func setHandler(w http.ResponseWriter, r *http.Request) {
+
}
func main() {
- http.HandleFunc("/", handler)
- log.Fatal(http.ListenAndServe(":8080", nil))
+ bindAddr := flag.String("b", ":4200", "bind address")
+ domain := flag.String("d", "http://localhost:4200", "full domain name")
+ peer := flag.String("i", "", "initial peer")
+ flag.Parse()
+
+ log.Printf("Starting %s %s %s", *bindAddr, *domain, *peer)
+
+ // Record myself
+ me = *domain
+ peerHashes = append(peerHashes, sha256sum(me))
+ hashToDomain = map[string]string{peerHashes[0]: me}
+
+ if *peer != "" {
+ go addPeer(*peer)
+ }
+
+ http.HandleFunc("/peer", peerHandler)
+ http.HandleFunc("/get", getHandler)
+ http.HandleFunc("/set", setHandler)
+ log.Fatal(http.ListenAndServe(*bindAddr, nil))
}