Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4985bf0bc8 | |||
| f6d3c47816 | |||
| 24d70951c9 | |||
| b436ec8cb5 | |||
| 54f7209f13 | |||
|
|
b0f27c6f74 | ||
|
|
8c0af18617 | ||
|
|
353416685a | ||
|
|
0ceec22705 |
14
README.md
14
README.md
@@ -1,16 +1,18 @@
|
||||
# go-gemini
|
||||
|
||||
[](https://godocs.io/git.sr.ht/~adnano/go-gemini) [](https://builds.sr.ht/~adnano/go-gemini?)
|
||||
This repository is a fork of [go-gemini](https://godocs.io/git.sr.ht/~adnano/go-gemini)
|
||||
implementing better parity with net/http and some tweaks required for use in
|
||||
[Hnakra](https://git.tebibyte.media/sashakoshka/hnakra).
|
||||
|
||||
Package gemini implements the [Gemini protocol](https://gemini.circumlunar.space)
|
||||
in Go. It provides an API similar to that of net/http to facilitate the
|
||||
development of Gemini clients and servers.
|
||||
|
||||
Compatible with version v0.14.3 of the Gemini specification.
|
||||
Compatible with version v0.16.0 of the Gemini specification.
|
||||
|
||||
## Usage
|
||||
|
||||
import "git.sr.ht/~adnano/go-gemini"
|
||||
import "git.tebibyte.media/sashakoshka/go-gemini"
|
||||
|
||||
Note that some filesystem-related functionality is only available on Go 1.16
|
||||
or later as it relies on the io/fs package.
|
||||
@@ -22,12 +24,6 @@ To run an example:
|
||||
|
||||
go run examples/server.go
|
||||
|
||||
## Contributing
|
||||
|
||||
Send patches and questions to [~adnano/go-gemini-devel](https://lists.sr.ht/~adnano/go-gemini-devel).
|
||||
|
||||
Subscribe to release announcements on [~adnano/go-gemini-announce](https://lists.sr.ht/~adnano/go-gemini-announce).
|
||||
|
||||
## License
|
||||
|
||||
go-gemini is licensed under the terms of the MIT license (see LICENSE).
|
||||
|
||||
6
doc.go
6
doc.go
@@ -30,7 +30,7 @@ Servers should be configured with certificates:
|
||||
server.GetCertificate = certificates.Get
|
||||
|
||||
Mux is a Gemini request multiplexer.
|
||||
Mux can handle requests for multiple hosts and schemes.
|
||||
Mux can handle requests for multiple hosts and paths.
|
||||
|
||||
mux := &gemini.Mux{}
|
||||
mux.HandleFunc("example.com", func(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request) {
|
||||
@@ -39,8 +39,8 @@ Mux can handle requests for multiple hosts and schemes.
|
||||
mux.HandleFunc("example.org/about.gmi", func(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request) {
|
||||
fmt.Fprint(w, "About example.org")
|
||||
})
|
||||
mux.HandleFunc("http://example.net", func(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request) {
|
||||
fmt.Fprint(w, "Proxied content from http://example.net")
|
||||
mux.HandleFunc("/images/", func(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request) {
|
||||
w.WriteHeader(gemini.StatusGone, "Gone forever")
|
||||
})
|
||||
server.Handler = mux
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"git.sr.ht/~adnano/go-gemini"
|
||||
"git.sr.ht/~adnano/go-gemini/certificate"
|
||||
"git.tebibyte.media/sashakoshka/go-gemini"
|
||||
"git.tebibyte.media/sashakoshka/go-gemini/certificate"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
@@ -52,7 +52,7 @@ func fingerprint(cert *x509.Certificate) string {
|
||||
}
|
||||
|
||||
func profile(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request) {
|
||||
tls := r.TLS()
|
||||
tls := r.TLS
|
||||
if len(tls.PeerCertificates) == 0 {
|
||||
w.WriteHeader(gemini.StatusCertificateRequired, "Certificate required")
|
||||
return
|
||||
@@ -68,7 +68,7 @@ func profile(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request) {
|
||||
}
|
||||
|
||||
func changeUsername(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request) {
|
||||
tls := r.TLS()
|
||||
tls := r.TLS
|
||||
if len(tls.PeerCertificates) == 0 {
|
||||
w.WriteHeader(gemini.StatusCertificateRequired, "Certificate required")
|
||||
return
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.sr.ht/~adnano/go-gemini/certificate"
|
||||
"git.tebibyte.media/sashakoshka/go-gemini/certificate"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -16,8 +16,8 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"git.sr.ht/~adnano/go-gemini"
|
||||
"git.sr.ht/~adnano/go-gemini/tofu"
|
||||
"git.tebibyte.media/sashakoshka/go-gemini"
|
||||
"git.tebibyte.media/sashakoshka/go-gemini/tofu"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"git.sr.ht/~adnano/go-gemini"
|
||||
"git.tebibyte.media/sashakoshka/go-gemini"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"git.sr.ht/~adnano/go-gemini"
|
||||
"git.sr.ht/~adnano/go-gemini/certificate"
|
||||
"git.tebibyte.media/sashakoshka/go-gemini"
|
||||
"git.tebibyte.media/sashakoshka/go-gemini/certificate"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"git.sr.ht/~adnano/go-gemini"
|
||||
"git.sr.ht/~adnano/go-gemini/certificate"
|
||||
"git.tebibyte.media/sashakoshka/go-gemini"
|
||||
"git.tebibyte.media/sashakoshka/go-gemini/certificate"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
2
fs.go
2
fs.go
@@ -169,7 +169,7 @@ func dirList(w ResponseWriter, f fs.File) {
|
||||
}
|
||||
link := LineLink{
|
||||
Name: name,
|
||||
URL: (&url.URL{Path: name}).EscapedPath(),
|
||||
URL: "./" + url.PathEscape(name),
|
||||
}
|
||||
fmt.Fprintln(w, link.String())
|
||||
}
|
||||
|
||||
2
go.mod
2
go.mod
@@ -1,4 +1,4 @@
|
||||
module git.sr.ht/~adnano/go-gemini
|
||||
module git.tebibyte.media/sashakoshka/go-gemini
|
||||
|
||||
go 1.15
|
||||
|
||||
|
||||
25
request.go
25
request.go
@@ -4,7 +4,6 @@ import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
@@ -28,8 +27,7 @@ type Request struct {
|
||||
// This field is ignored by the Gemini server.
|
||||
Certificate *tls.Certificate
|
||||
|
||||
conn net.Conn
|
||||
tls *tls.ConnectionState
|
||||
TLS *tls.ConnectionState
|
||||
}
|
||||
|
||||
// NewRequest returns a new request.
|
||||
@@ -98,30 +96,11 @@ func (r *Request) WriteTo(w io.Writer) (int64, error) {
|
||||
return wrote, bw.Flush()
|
||||
}
|
||||
|
||||
// Conn returns the network connection on which the request was received.
|
||||
// Conn returns nil for client requests.
|
||||
func (r *Request) Conn() net.Conn {
|
||||
return r.conn
|
||||
}
|
||||
|
||||
// TLS returns information about the TLS connection on which the
|
||||
// request was received.
|
||||
// TLS returns nil for client requests.
|
||||
func (r *Request) TLS() *tls.ConnectionState {
|
||||
if r.tls == nil {
|
||||
if tlsConn, ok := r.conn.(*tls.Conn); ok {
|
||||
state := tlsConn.ConnectionState()
|
||||
r.tls = &state
|
||||
}
|
||||
}
|
||||
return r.tls
|
||||
}
|
||||
|
||||
// ServerName returns the value of the TLS Server Name Indication extension
|
||||
// sent by the client.
|
||||
// ServerName returns an empty string for client requests.
|
||||
func (r *Request) ServerName() string {
|
||||
if tls := r.TLS(); tls != nil {
|
||||
if tls := r.TLS; tls != nil {
|
||||
return tls.ServerName
|
||||
}
|
||||
return ""
|
||||
|
||||
@@ -371,7 +371,10 @@ func (srv *Server) goServeConn(ctx context.Context, conn net.Conn) error {
|
||||
w.WriteHeader(StatusBadRequest, "Bad request")
|
||||
return w.Flush()
|
||||
}
|
||||
req.conn = conn
|
||||
if tlsConn, ok := conn.(*tls.Conn); ok {
|
||||
state := tlsConn.ConnectionState()
|
||||
req.TLS = &state
|
||||
}
|
||||
|
||||
h := srv.Handler
|
||||
if h == nil {
|
||||
|
||||
4
text.go
4
text.go
@@ -125,8 +125,8 @@ func ParseLines(r io.Reader, handler func(Line)) error {
|
||||
name = strings.TrimLeft(name, spacetab)
|
||||
line = LineLink{url, name}
|
||||
}
|
||||
} else if strings.HasPrefix(text, "*") {
|
||||
text = text[1:]
|
||||
} else if strings.HasPrefix(text, "* ") {
|
||||
text = text[2:]
|
||||
text = strings.TrimLeft(text, spacetab)
|
||||
line = LineListItem(text)
|
||||
} else if strings.HasPrefix(text, "###") {
|
||||
|
||||
Reference in New Issue
Block a user