Compare commits
No commits in common. "master" and "v1.0.1" have entirely different histories.
24
README.md
24
README.md
@ -38,28 +38,6 @@ You can also use HTTP.
|
|||||||
curl http://localhost:4080
|
curl http://localhost:4080
|
||||||
```
|
```
|
||||||
|
|
||||||
## Testing Beyond Localhost
|
|
||||||
|
|
||||||
You can use [Telebit](https://telebit.cloud) to share the experience with friends and loved ones:
|
|
||||||
|
|
||||||
Completely userspace installation:
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -fsSL https://get.telebit.cloud | bash
|
|
||||||
```
|
|
||||||
|
|
||||||
Easy configuration:
|
|
||||||
|
|
||||||
```
|
|
||||||
~/telebit http 4080
|
|
||||||
> Forwarding https://lucky-duck-42.telebit.fun => localhost:4080
|
|
||||||
|
|
||||||
~/telebit tcp 4080
|
|
||||||
> Forwarding telebit.cloud:1234 => localhost:4080
|
|
||||||
```
|
|
||||||
|
|
||||||
Caveat: Due to a bug in telebit you must send 'hello' in telnet to establish a connection.
|
|
||||||
|
|
||||||
# API Docs
|
# API Docs
|
||||||
|
|
||||||
The API docs and examples can be seen at <http://localhost:4080>
|
The API docs and examples can be seen at <http://localhost:4080>
|
||||||
@ -115,7 +93,7 @@ Not Implemented
|
|||||||
|
|
||||||
I don't think these things would be difficult to add,
|
I don't think these things would be difficult to add,
|
||||||
but I was having fun learning lots of other things
|
but I was having fun learning lots of other things
|
||||||
and I figured they're not that important.
|
and I figured Some of these things I didn't implement
|
||||||
|
|
||||||
* [ ] local log file
|
* [ ] local log file
|
||||||
* [ ] Rooms
|
* [ ] Rooms
|
||||||
|
@ -83,7 +83,6 @@ func handleTelnetConn(bufConn bufferedConn) {
|
|||||||
email = strings.TrimSpace(msg)
|
email = strings.TrimSpace(msg)
|
||||||
emailParts := strings.Split(email, "@")
|
emailParts := strings.Split(email, "@")
|
||||||
if 2 != len(emailParts) {
|
if 2 != len(emailParts) {
|
||||||
email = ""
|
|
||||||
fmt.Fprintf(bufConn, "Email: ")
|
fmt.Fprintf(bufConn, "Email: ")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -42,12 +43,12 @@ type ConfMailer struct {
|
|||||||
// https://stackoverflow.com/questions/51472020/how-to-get-the-size-of-available-tcp-data
|
// https://stackoverflow.com/questions/51472020/how-to-get-the-size-of-available-tcp-data
|
||||||
type bufferedConn struct {
|
type bufferedConn struct {
|
||||||
r *bufio.Reader
|
r *bufio.Reader
|
||||||
//rout *io.Reader // See https://github.com/polvi/sni/blob/master/sni.go#L135
|
rout io.Reader // See https://github.com/polvi/sni/blob/master/sni.go#L135
|
||||||
net.Conn
|
net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBufferedConn(c net.Conn) bufferedConn {
|
func newBufferedConn(c net.Conn) bufferedConn {
|
||||||
return bufferedConn{bufio.NewReader(c), c}
|
return bufferedConn{bufio.NewReader(c), nil, c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b bufferedConn) Peek(n int) ([]byte, error) {
|
func (b bufferedConn) Peek(n int) ([]byte, error) {
|
||||||
@ -59,11 +60,9 @@ func (b bufferedConn) Buffered() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b bufferedConn) Read(p []byte) (int, error) {
|
func (b bufferedConn) Read(p []byte) (int, error) {
|
||||||
/*
|
|
||||||
if b.rout != nil {
|
if b.rout != nil {
|
||||||
return b.rout.Read(p)
|
return b.rout.Read(p)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
return b.r.Read(p)
|
return b.r.Read(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +91,7 @@ var broadcastMsg chan chatMsg
|
|||||||
// Telnet
|
// Telnet
|
||||||
var wantsServerHello chan bufferedConn
|
var wantsServerHello chan bufferedConn
|
||||||
var authTelnet chan telnetUser
|
var authTelnet chan telnetUser
|
||||||
var cleanTelnet chan telnetUser // intentionally blocking
|
var cleanTelnet chan telnetUser
|
||||||
|
|
||||||
// HTTP
|
// HTTP
|
||||||
var demuxHttpClient chan bufferedConn
|
var demuxHttpClient chan bufferedConn
|
||||||
@ -101,7 +100,7 @@ var valAuthReqs chan authReq
|
|||||||
var delAuthReqs chan authReq
|
var delAuthReqs chan authReq
|
||||||
|
|
||||||
func usage() {
|
func usage() {
|
||||||
fmt.Fprintf(os.Stderr, "\nusage: go run chatserver*.go\n")
|
fmt.Fprintf(os.Stderr, "\nusage: go run chatserver.go\n")
|
||||||
flag.PrintDefaults()
|
flag.PrintDefaults()
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
@ -167,9 +166,6 @@ func muxTcp(conn bufferedConn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if "" == protocol {
|
if "" == protocol {
|
||||||
// Throw away the first bytes
|
|
||||||
b := make([]byte, 4096)
|
|
||||||
conn.Read(b)
|
|
||||||
fmt.Fprintf(conn, "\n\nWelcome to Sample Chat! You're not an HTTP client, assuming Telnet.\nYou must authenticate via email to participate\n\nEmail: ")
|
fmt.Fprintf(conn, "\n\nWelcome to Sample Chat! You're not an HTTP client, assuming Telnet.\nYou must authenticate via email to participate\n\nEmail: ")
|
||||||
wantsServerHello <- conn
|
wantsServerHello <- conn
|
||||||
return
|
return
|
||||||
@ -301,7 +297,7 @@ func main() {
|
|||||||
virginConns = make(chan net.Conn, 128)
|
virginConns = make(chan net.Conn, 128)
|
||||||
|
|
||||||
// TCP & Authentication
|
// TCP & Authentication
|
||||||
telnetConns := make(map[string]telnetUser)
|
telnetConns := make(map[bufferedConn]telnetUser)
|
||||||
wantsServerHello = make(chan bufferedConn, 128)
|
wantsServerHello = make(chan bufferedConn, 128)
|
||||||
authTelnet = make(chan telnetUser, 128)
|
authTelnet = make(chan telnetUser, 128)
|
||||||
|
|
||||||
@ -389,12 +385,7 @@ func main() {
|
|||||||
case u := <-authTelnet:
|
case u := <-authTelnet:
|
||||||
// allow to receive messages
|
// allow to receive messages
|
||||||
// (and be counted among the users)
|
// (and be counted among the users)
|
||||||
_, ok := telnetConns[u.email]
|
telnetConns[u.bufConn] = u
|
||||||
if ok {
|
|
||||||
// this is a blocking channel, and that's important
|
|
||||||
cleanTelnet <- telnetConns[u.email]
|
|
||||||
}
|
|
||||||
telnetConns[u.email] = u
|
|
||||||
// is chan chan the right way to handle this?
|
// is chan chan the right way to handle this?
|
||||||
u.userCount <- len(telnetConns)
|
u.userCount <- len(telnetConns)
|
||||||
broadcastMsg <- chatMsg{
|
broadcastMsg <- chatMsg{
|
||||||
@ -427,7 +418,7 @@ func main() {
|
|||||||
close(u.newMsg)
|
close(u.newMsg)
|
||||||
// we can safely ignore this error, if any
|
// we can safely ignore this error, if any
|
||||||
u.bufConn.Close()
|
u.bufConn.Close()
|
||||||
delete(telnetConns, u.email)
|
delete(telnetConns, u.bufConn)
|
||||||
case bufConn := <-gotClientHello:
|
case bufConn := <-gotClientHello:
|
||||||
go muxTcp(bufConn)
|
go muxTcp(bufConn)
|
||||||
case bufConn := <-demuxHttpClient:
|
case bufConn := <-demuxHttpClient:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user