diff --git a/cmd/titan2-client/main.go b/cmd/titan2-client/main.go new file mode 100644 index 0000000..5100de5 --- /dev/null +++ b/cmd/titan2-client/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "crypto/tls" + "log" +) + +func main() { + config := &tls.Config{ + MinVersion: tls.VersionTLS12, + InsecureSkipVerify: true, + } + conn, err := tls.Dial("tcp4", "localhost:1965", config) + if err != nil { + log.Fatal(err) + } + n, err := conn.Write([]byte("Test message")) + if err != nil { + log.Fatal(err) + } + log.Println(n) +} diff --git a/cmd/titan2-server/main.go b/cmd/titan2-server/main.go new file mode 100644 index 0000000..1d887a5 --- /dev/null +++ b/cmd/titan2-server/main.go @@ -0,0 +1,52 @@ +package main + +import ( + "crypto/tls" + "flag" + "fmt" + "log" + "net" +) + +var port = flag.Int("p", 1965, "Port to bind the server to. Defaults to 1965") +var certFile = flag.String("cert", "cert.pem", "TLS certificate to run the server with. Can be self signed.") +var keyFile = flag.String("key", "key.pem", "TLS private key to run the server with.") + +func main() { + cert, err := tls.LoadX509KeyPair(*certFile, *keyFile) + if err != nil { + log.Fatalf("Could not load certificate: %s\n", err) + } + config := tls.Config{ + Certificates: []tls.Certificate{cert}, + MinVersion: tls.VersionTLS12, + } + // Listen on the port passed in (default 1965) for IPv4 connections + // on any IP address of the local machine + listener, err := tls.Listen("tcp4", fmt.Sprintf(":%d", *port), &config) + if err != nil { + log.Fatalf("Error opening listener: %s\n", err) + } + defer listener.Close() + for { + // Wait for a connection + conn, err := listener.Accept() + if err != nil { + log.Printf("Error opening connection: %s\n", err) + break + } + log.Printf("Connection established from %s\n", conn.RemoteAddr()) + // Handle the connection in a new goroutine so the loop can go back to + // accepting connections + go func(c net.Conn) { + bytes := make([]byte, 1024, 1024) + n, err := c.Read(bytes) + if err != nil { + log.Println(err) + } + log.Printf("Bytes Read: %d\n", n) + log.Println(string(bytes)) + c.Close() + }(conn) + } +} diff --git a/pkg/gemini/headers.go b/pkg/gemini/headers.go new file mode 100644 index 0000000..6231ec5 --- /dev/null +++ b/pkg/gemini/headers.go @@ -0,0 +1,22 @@ +package gemini + +import "strings" + +type Request struct { + Host string + Port string + Path string + Schema string +} + +func NewRequest(url string) Request { + r := Request{} + var parts []string + if strings.Contains(url, "://") { + parts = strings.Split(url, "://") + r.Schema = parts[0] + } else { + r.Schema = "gemini" + } + return r +} diff --git a/pkg/gemini/parser.go b/pkg/gemini/parser.go new file mode 100644 index 0000000..5e03e35 --- /dev/null +++ b/pkg/gemini/parser.go @@ -0,0 +1 @@ +package gemini diff --git a/pkg/gemini/status_codes.go b/pkg/gemini/status_codes.go new file mode 100644 index 0000000..410b1f9 --- /dev/null +++ b/pkg/gemini/status_codes.go @@ -0,0 +1,22 @@ +package gemini + +const ( + INPUT int = 10 + SENSITIVE_INPUT int = 11 + SUCCESS int = 20 + TEMPORARY_REDIRECT int = 30 + PERMANENT_REDIRECT int = 31 + TEMPORARY_FAILURE int = 40 + SERVER_UNAVAILABLE int = 41 + CGI_ERROR int = 42 + PROXY_ERROR int = 43 + SLOW_DOWN int = 44 + PERMANENT_FALIURE int = 50 + NOT_FOUND int = 51 + GONE int = 52 + PROXY_REQUEST_REFUSED int = 53 + BAD_REQUEST int = 59 + CLIENT_CERTIFICATE_REQUIRED int = 60 + CERTIFICATE_NOT_AUTHORIZED int = 61 + CERTIFICATE_NOT_VALID int = 62 +)