aboutsummaryrefslogtreecommitdiff
path: root/request.go
diff options
context:
space:
mode:
authorAdnan Maolood <[email protected]>2020-10-21 17:07:28 -0400
committerAdnan Maolood <[email protected]>2020-10-21 17:07:28 -0400
commit9506f69f1aef8722f06bb47d65f99ff0bffb7347 (patch)
tree35fec7ce8ecb79c758f01d9d48550945b845e2e8 /request.go
parentRename Handler to Responder (diff)
downloadgo-gemini-9506f69f1aef8722f06bb47d65f99ff0bffb7347.tar.xz
go-gemini-9506f69f1aef8722f06bb47d65f99ff0bffb7347.zip
Refactor
Diffstat (limited to 'request.go')
-rw-r--r--request.go92
1 files changed, 92 insertions, 0 deletions
diff --git a/request.go b/request.go
new file mode 100644
index 0000000..7b2d209
--- /dev/null
+++ b/request.go
@@ -0,0 +1,92 @@
+package gmi
+
+import (
+ "bufio"
+ "crypto/tls"
+ "net"
+ "net/url"
+)
+
+// Request represents a Gemini request.
+type Request struct {
+ // URL specifies the URL being requested.
+ URL *url.URL
+
+ // For client requests, Host specifies the host on which the URL is sought.
+ // Host must contain a port.
+ // This field is ignored by the server.
+ Host string
+
+ // Certificate specifies the TLS certificate to use for the request.
+ // Request certificates take precedence over client certificates.
+ // This field is ignored by the server.
+ Certificate *tls.Certificate
+
+ // RemoteAddr allows servers and other software to record the network
+ // address that sent the request.
+ // This field is ignored by the client.
+ RemoteAddr net.Addr
+
+ // TLS allows servers and other software to record information about the TLS
+ // connection on which the request was received.
+ // This field is ignored by the client.
+ TLS tls.ConnectionState
+}
+
+// hostname returns the host without the port.
+func hostname(host string) string {
+ hostname, _, err := net.SplitHostPort(host)
+ if err != nil {
+ return host
+ }
+ return hostname
+}
+
+// NewRequest returns a new request. The host is inferred from the provided URL.
+func NewRequest(rawurl string) (*Request, error) {
+ u, err := url.Parse(rawurl)
+ if err != nil {
+ return nil, err
+ }
+
+ // If there is no port, use the default port of 1965
+ host := u.Host
+ if u.Port() == "" {
+ host += ":1965"
+ }
+
+ return &Request{
+ Host: host,
+ URL: u,
+ }, nil
+}
+
+// NewRequestTo returns a new request for the provided URL to the provided host.
+// The host must contain a port.
+func NewRequestTo(rawurl, host string) (*Request, error) {
+ u, err := url.Parse(rawurl)
+ if err != nil {
+ return nil, err
+ }
+
+ return &Request{
+ Host: host,
+ URL: u,
+ }, nil
+}
+
+// write writes the Gemini request to the provided buffered writer.
+func (r *Request) write(w *bufio.Writer) error {
+ url := r.URL.String()
+ // User is invalid
+ if r.URL.User != nil || len(url) > 1024 {
+ return ErrInvalidURL
+ }
+ if _, err := w.WriteString(url); err != nil {
+ return err
+ }
+ if _, err := w.Write(crlf); err != nil {
+ return err
+ }
+ return nil
+}