backend for xcvr appview
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

remove port

+17 -30
+16 -29
server/cmd/main.go
··· 3 3 import ( 4 4 "encoding/json" 5 5 "fmt" 6 - "net" 7 6 "net/http" 8 7 "os" 9 8 "slices" ··· 23 22 type channel struct { 24 23 Band string `json:"band"` 25 24 Sign string `json:"sign"` 26 - Port int `json:"port"` 27 25 } 28 26 29 27 func main() { 30 28 bandToServer = make(map[string]*lrcd.Server) 31 29 channels = make([]channel, 0) 32 - createChannel(channel{Band: "general", Sign: "Please Keep Memes Out Of #general"}, false) 33 - createChannel(channel{Band: "sneep", Sign: "snirp"}, true) 30 + createChannel(channel{Band: "general", Sign: "hi"}, false) 31 + createChannel(channel{Band: "sneep", Sign: "snirp"}, false) 34 32 fmt.Println("hello world") 35 33 mux := http.NewServeMux() 34 + mux.HandleFunc("GET /{band}/ws", acceptWebsocket) 36 35 mux.HandleFunc("GET /xrpc/getChannels", getChannels) 37 36 mux.HandleFunc("POST /xrpc/initChannel", initChannel) 38 37 39 38 http.ListenAndServe(":8080", withCORSAll(mux)) 40 39 } 41 40 41 + func acceptWebsocket(w http.ResponseWriter, r *http.Request) { 42 + band := r.PathValue("band") 43 + server, ok := bandToServer[band] 44 + if !ok { 45 + http.NotFound(w, r) 46 + return 47 + } 48 + h := server.WSHandler() 49 + h(w, r) 50 + } 51 + 42 52 func initChannel(w http.ResponseWriter, r *http.Request) { 43 53 decoder := json.NewDecoder(r.Body) 44 54 var c channel ··· 59 69 case ieLongSign: 60 70 http.Error(w, "sign must be shorter than 51 code points", http.StatusBadRequest) 61 71 return 62 - case iePort: 63 - http.Error(w, "should not provide a port", http.StatusBadRequest) 64 - return 65 72 case ieOK: 66 - c, err = createChannel(c, true) 73 + c, err = createChannel(c, false) 67 74 } 68 75 if err != nil { 69 76 http.Error(w, "uh oh", http.StatusTeapot) ··· 81 88 ieLongBand 82 89 ieCollision 83 90 ieLongSign 84 - iePort 85 91 ) 86 92 87 93 // TODO: can changes to bandToServer after unlock create data race? ··· 101 107 if utf8.RuneCountInString(c.Sign) > 50 { 102 108 return ieLongSign 103 109 } 104 - if c.Port != 0 { 105 - return iePort 106 - } 107 110 return ieOK 108 111 } 109 112 ··· 116 119 } 117 120 118 121 func createChannel(c channel, withDelete bool) (channel, error) { 119 - port, err := getFreePort() 120 - if err != nil { 121 - fmt.Println(err.Error()) 122 - return channel{}, err 123 - } 124 - c.Port = port 125 - 126 - options := []lrcd.Option{lrcd.WithWSPort(c.Port), 122 + options := []lrcd.Option{ 127 123 lrcd.WithWelcome(c.Sign), 128 124 lrcd.WithLogging(os.Stdout, true), 129 125 } ··· 169 165 }() 170 166 } 171 167 return c, nil 172 - } 173 - 174 - func getFreePort() (int, error) { 175 - nl, err := net.Listen("tcp", ":0") 176 - if err != nil { 177 - return -1, err 178 - } 179 - defer nl.Close() 180 - return (nl.Addr().(*net.TCPAddr)).Port, nil 181 168 } 182 169 183 170 func withCORSAll(h http.Handler) http.Handler {
+1 -1
server/go.mod
··· 2 2 3 3 go 1.22.1 4 4 5 - require github.com/rachel-mp4/lrc/lrcd v0.0.0-20250410002721-ca6a18431212 5 + require github.com/rachel-mp4/lrc/lrcd v0.0.0-20250410194244-d1bffda40b72 6 6 7 7 require ( 8 8 github.com/gorilla/websocket v1.5.3 // indirect