Browse Source

Add SaneEOL configuration option

master
Trevor Slocum 2 years ago
parent
commit
e3aeb18053
  1. 23
      CONFIGURATION.md
  2. 2
      README.md
  3. 8
      config.go
  4. 12
      serve_file.go
  5. 2
      serve_proxy.go
  6. 8
      server.go

23
CONFIGURATION.md

@ -119,16 +119,31 @@ specified address or path.
A `Root` attribute must also be specified to use `FastCGI`.
## End-of-line indicator
The Gemini protocol requires `\r\n` (CRLF) as the end-of-line indicator. This
convention is carried over from protocol specifications **first written in the
1970s**. This requirement is antithetic to the spirit of Gemini (to improve
upon the Finger and Gopher protocols) because it unnecessarily tacks on ancient
baggage. This baggage has caused (and continues to cause) increased complexity in
client and server implementations, which naturally gives rise to more bugs.
In anticipation of an improvement to the Gemini specification, administrators
may configure twins to send standard `\n` (LF) line endings by setting
`SaneEOL` to `true`.
References:
[1](https://lists.orbitalfox.eu/archives/gemini/2019/000131.html)
[2](https://lists.orbitalfox.eu/archives/gemini/2020/000756.html)
[3](https://lists.orbitalfox.eu/archives/gemini/2020/001339.html)
[4](https://lists.orbitalfox.eu/archives/gemini/2020/003065.html)
# Example config.yaml
```yaml
# Address to listen on
listen: :1965
# TLS certificates
certificates:
-
# Hosts and paths to serve
hosts:
gemini.rocks:

2
README.md

@ -12,7 +12,7 @@ This page is also available at [gemini://twins.rocketnine.space](gemini://twins.
## Features
- Serve static files
- Directory listing (when enabled)
- List files and directories (when enabled)
- Reverse proxy requests
- TCP
- [FastCGI](https://en.wikipedia.org/wiki/FastCGI)

8
config.go

@ -59,6 +59,8 @@ type serverConfig struct {
DisableSize bool
SaneEOL bool
hostname string
port int
fcgiPools map[string]gofast.ConnFactory
@ -91,6 +93,12 @@ func readconfig(configPath string) error {
log.Fatal("listen address must be specified")
}
if config.SaneEOL {
newLine = "\n"
} else {
newLine = "\r\n"
}
split := strings.Split(config.Listen, ":")
if len(split) != 2 {
config.hostname = config.Listen

12
serve_file.go

@ -52,7 +52,7 @@ func serveDirList(c net.Conn, request *url.URL, dirPath string) {
writeHeader(c, statusSuccess, "text/gemini; charset=utf-8")
fmt.Fprintf(c, "# %s\r\n", request.Path)
fmt.Fprintf(c, "# %s%s", request.Path, newLine)
if numDirs == 1 {
c.Write([]byte("1 directory"))
} else {
@ -64,10 +64,10 @@ func serveDirList(c net.Conn, request *url.URL, dirPath string) {
} else {
fmt.Fprintf(c, "%d files", numFiles)
}
c.Write([]byte("\r\n\n"))
c.Write([]byte(newLine + newLine))
if request.Path != "/" {
c.Write([]byte("=> ../ ../\r\n\r\n"))
c.Write([]byte("=> ../ ../" + newLine + newLine))
}
for _, info := range files {
@ -78,10 +78,10 @@ func serveDirList(c net.Conn, request *url.URL, dirPath string) {
filePath += "/"
}
c.Write([]byte("=> " + fileName + " " + filePath + "\r\n"))
c.Write([]byte("=> " + fileName + " " + filePath + newLine))
if info.IsDir() || info.Mode()&os.ModeSymlink != 0 {
c.Write([]byte("\r\n"))
c.Write([]byte(newLine))
continue
}
@ -89,7 +89,7 @@ func serveDirList(c net.Conn, request *url.URL, dirPath string) {
if !info.ModTime().IsZero() {
modified = info.ModTime().Format("2006-01-02 3:04 PM")
}
c.Write([]byte(modified + " - " + formatFileSize(info.Size()) + "\r\n\r\n"))
c.Write([]byte(modified + " - " + formatFileSize(info.Size()) + newLine + newLine))
}
}

2
serve_proxy.go

@ -28,7 +28,7 @@ func serveProxy(c net.Conn, request *url.URL, proxyURL string) {
// Forward request
proxy.Write([]byte(request.String()))
proxy.Write([]byte("\r\n"))
proxy.Write([]byte(newLine))
// Forward response
io.Copy(c, proxy)

8
server.go

@ -47,8 +47,10 @@ const (
var slashesRegexp = regexp.MustCompile(`[^\\]\/`)
var newLine = "\r\n"
func writeHeader(c net.Conn, code int, meta string) {
fmt.Fprintf(c, "%d %s\r\n", code, meta)
fmt.Fprintf(c, "%d %s%s", code, meta, newLine)
if verbose {
log.Printf("< %d %s\n", code, meta)
@ -203,7 +205,9 @@ func servePath(c *tls.Conn, request *url.URL, serve *pathConfig) {
func serveConn(c *tls.Conn) {
var requestData string
scanner := bufio.NewScanner(c)
scanner.Split(scanCRLF)
if !config.SaneEOL {
scanner.Split(scanCRLF)
}
if scanner.Scan() {
requestData = scanner.Text()
}

Loading…
Cancel
Save