Rename rw, req to w, r
This commit is contained in:
parent
67842c6425
commit
faf94d8ba5
12
doc.go
12
doc.go
@ -64,14 +64,14 @@ Servers must be configured with certificates:
|
||||
|
||||
Servers can accept requests for multiple hosts and schemes:
|
||||
|
||||
server.HandleFunc("example.com", func(rw *gmi.ResponseWriter, req *gmi.Request) {
|
||||
fmt.Fprint(rw, "Welcome to example.com")
|
||||
server.HandleFunc("example.com", func(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||
fmt.Fprint(w, "Welcome to example.com")
|
||||
})
|
||||
server.HandleFunc("example.org", func(rw *gmi.ResponseWriter, req *gmi.Request) {
|
||||
fmt.Fprint(rw, "Welcome to example.org")
|
||||
server.HandleFunc("example.org", func(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||
fmt.Fprint(w, "Welcome to example.org")
|
||||
})
|
||||
server.HandleSchemeFunc("http", "example.net", func(rw *gmi.ResponseWriter, req *gmi.Request) {
|
||||
fmt.Fprint(rw, "Proxied content from example.net")
|
||||
server.HandleSchemeFunc("http", "example.net", func(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||
fmt.Fprint(w, "Proxied content from example.net")
|
||||
})
|
||||
|
||||
To start the server, call ListenAndServe:
|
||||
|
@ -58,75 +58,75 @@ func getSession(crt *x509.Certificate) (*session, bool) {
|
||||
return session, ok
|
||||
}
|
||||
|
||||
func welcome(rw *gmi.ResponseWriter, req *gmi.Request) {
|
||||
rw.Write([]byte("Welcome to this example.\n=> /login Login\n"))
|
||||
func welcome(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||
w.Write([]byte("Welcome to this example.\n=> /login Login\n"))
|
||||
}
|
||||
|
||||
func login(rw *gmi.ResponseWriter, req *gmi.Request) {
|
||||
gmi.WithCertificate(rw, req, func(cert *x509.Certificate) {
|
||||
gmi.WithInput(rw, req, "Username", func(username string) {
|
||||
func login(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||
gmi.WithCertificate(w, r, func(cert *x509.Certificate) {
|
||||
gmi.WithInput(w, r, "Username", func(username string) {
|
||||
fingerprint := gmi.Fingerprint(cert)
|
||||
sessions[fingerprint] = &session{
|
||||
username: username,
|
||||
}
|
||||
gmi.Redirect(rw, req, "/login/password")
|
||||
gmi.Redirect(w, r, "/login/password")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func loginPassword(rw *gmi.ResponseWriter, req *gmi.Request) {
|
||||
gmi.WithCertificate(rw, req, func(cert *x509.Certificate) {
|
||||
func loginPassword(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||
gmi.WithCertificate(w, r, func(cert *x509.Certificate) {
|
||||
session, ok := getSession(cert)
|
||||
if !ok {
|
||||
gmi.CertificateNotAuthorized(rw, req)
|
||||
gmi.CertificateNotAuthorized(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
gmi.WithSensitiveInput(rw, req, "Password", func(password string) {
|
||||
gmi.WithSensitiveInput(w, r, "Password", func(password string) {
|
||||
expected := logins[session.username].password
|
||||
if password == expected {
|
||||
session.authorized = true
|
||||
gmi.Redirect(rw, req, "/profile")
|
||||
gmi.Redirect(w, r, "/profile")
|
||||
} else {
|
||||
gmi.SensitiveInput(rw, req, "Wrong password. Try again")
|
||||
gmi.SensitiveInput(w, r, "Wrong password. Try again")
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func logout(rw *gmi.ResponseWriter, req *gmi.Request) {
|
||||
gmi.WithCertificate(rw, req, func(cert *x509.Certificate) {
|
||||
func logout(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||
gmi.WithCertificate(w, r, func(cert *x509.Certificate) {
|
||||
fingerprint := gmi.Fingerprint(cert)
|
||||
delete(sessions, fingerprint)
|
||||
})
|
||||
rw.Write([]byte("Successfully logged out.\n"))
|
||||
w.Write([]byte("Successfully logged out.\n"))
|
||||
}
|
||||
|
||||
func profile(rw *gmi.ResponseWriter, req *gmi.Request) {
|
||||
gmi.WithCertificate(rw, req, func(cert *x509.Certificate) {
|
||||
func profile(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||
gmi.WithCertificate(w, r, func(cert *x509.Certificate) {
|
||||
session, ok := getSession(cert)
|
||||
if !ok {
|
||||
gmi.CertificateNotAuthorized(rw, req)
|
||||
gmi.CertificateNotAuthorized(w, r)
|
||||
return
|
||||
}
|
||||
user := logins[session.username]
|
||||
profile := fmt.Sprintf("Username: %s\nAdmin: %t\n=> /logout Logout", session.username, user.admin)
|
||||
rw.Write([]byte(profile))
|
||||
w.Write([]byte(profile))
|
||||
})
|
||||
}
|
||||
|
||||
func admin(rw *gmi.ResponseWriter, req *gmi.Request) {
|
||||
gmi.WithCertificate(rw, req, func(cert *x509.Certificate) {
|
||||
func admin(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||
gmi.WithCertificate(w, r, func(cert *x509.Certificate) {
|
||||
session, ok := getSession(cert)
|
||||
if !ok {
|
||||
gmi.CertificateNotAuthorized(rw, req)
|
||||
gmi.CertificateNotAuthorized(w, r)
|
||||
return
|
||||
}
|
||||
user := logins[session.username]
|
||||
if !user.admin {
|
||||
gmi.CertificateNotAuthorized(rw, req)
|
||||
gmi.CertificateNotAuthorized(w, r)
|
||||
return
|
||||
}
|
||||
rw.Write([]byte("Welcome to the admin portal.\n"))
|
||||
w.Write([]byte("Welcome to the admin portal.\n"))
|
||||
})
|
||||
}
|
||||
|
10
fs.go
10
fs.go
@ -24,19 +24,19 @@ type fsHandler struct {
|
||||
FS
|
||||
}
|
||||
|
||||
func (fsh fsHandler) Serve(rw *ResponseWriter, req *Request) {
|
||||
path := path.Clean(req.URL.Path)
|
||||
func (fsh fsHandler) Serve(w *ResponseWriter, r *Request) {
|
||||
path := path.Clean(r.URL.Path)
|
||||
f, err := fsh.Open(path)
|
||||
if err != nil {
|
||||
NotFound(rw, req)
|
||||
NotFound(w, r)
|
||||
return
|
||||
}
|
||||
// Detect mimetype
|
||||
ext := filepath.Ext(path)
|
||||
mimetype := mime.TypeByExtension(ext)
|
||||
rw.SetMimetype(mimetype)
|
||||
w.SetMimetype(mimetype)
|
||||
// Copy file to response writer
|
||||
io.Copy(rw, f)
|
||||
io.Copy(w, f)
|
||||
}
|
||||
|
||||
// TODO: replace with io/fs.FS when available
|
||||
|
92
server.go
92
server.go
@ -199,7 +199,7 @@ func (r *ResponseWriter) Write(b []byte) (int, error) {
|
||||
// respond responds to a connection.
|
||||
func (s *Server) respond(conn net.Conn) {
|
||||
r := bufio.NewReader(conn)
|
||||
rw := newResponseWriter(conn)
|
||||
w := newResponseWriter(conn)
|
||||
// Read requested URL
|
||||
rawurl, err := r.ReadString('\r')
|
||||
if err != nil {
|
||||
@ -209,16 +209,16 @@ func (s *Server) respond(conn net.Conn) {
|
||||
if b, err := r.ReadByte(); err != nil {
|
||||
return
|
||||
} else if b != '\n' {
|
||||
rw.WriteHeader(StatusBadRequest, "Bad request")
|
||||
w.WriteHeader(StatusBadRequest, "Bad request")
|
||||
}
|
||||
// Trim carriage return
|
||||
rawurl = rawurl[:len(rawurl)-1]
|
||||
// Ensure URL is valid
|
||||
if len(rawurl) > 1024 {
|
||||
rw.WriteHeader(StatusBadRequest, "Bad request")
|
||||
w.WriteHeader(StatusBadRequest, "Bad request")
|
||||
} else if url, err := url.Parse(rawurl); err != nil || url.User != nil {
|
||||
// Note that we return an error status if User is specified in the URL
|
||||
rw.WriteHeader(StatusBadRequest, "Bad request")
|
||||
w.WriteHeader(StatusBadRequest, "Bad request")
|
||||
} else {
|
||||
// Gather information about the request
|
||||
req := &Request{
|
||||
@ -226,14 +226,14 @@ func (s *Server) respond(conn net.Conn) {
|
||||
RemoteAddr: conn.RemoteAddr(),
|
||||
TLS: conn.(*tls.Conn).ConnectionState(),
|
||||
}
|
||||
s.handler(req).Serve(rw, req)
|
||||
s.handler(req).Serve(w, req)
|
||||
}
|
||||
rw.w.Flush()
|
||||
w.w.Flush()
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
func (s *Server) handler(req *Request) Handler {
|
||||
if h, ok := s.handlers[handlerKey{req.URL.Scheme, req.URL.Hostname()}]; ok {
|
||||
func (s *Server) handler(r *Request) Handler {
|
||||
if h, ok := s.handlers[handlerKey{r.URL.Scheme, r.URL.Hostname()}]; ok {
|
||||
return h
|
||||
}
|
||||
return NotFoundHandler()
|
||||
@ -246,24 +246,24 @@ type Handler interface {
|
||||
}
|
||||
|
||||
// Input responds to the request with a request for input using the given prompt.
|
||||
func Input(rw *ResponseWriter, req *Request, prompt string) {
|
||||
rw.WriteHeader(StatusInput, prompt)
|
||||
func Input(w *ResponseWriter, r *Request, prompt string) {
|
||||
w.WriteHeader(StatusInput, prompt)
|
||||
}
|
||||
|
||||
// InputHandler returns a simple handler that responds to each request with
|
||||
// a request for input.
|
||||
func InputHandler(prompt string) Handler {
|
||||
return HandlerFunc(func(rw *ResponseWriter, req *Request) {
|
||||
Input(rw, req, prompt)
|
||||
return HandlerFunc(func(w *ResponseWriter, r *Request) {
|
||||
Input(w, r, prompt)
|
||||
})
|
||||
}
|
||||
|
||||
// WithInput either responds to the request with StatusInput if no input
|
||||
// is provided, or calls f with the input when provided.
|
||||
func WithInput(rw *ResponseWriter, req *Request, prompt string, f func(string)) {
|
||||
input := req.URL.RawQuery
|
||||
func WithInput(w *ResponseWriter, r *Request, prompt string, f func(string)) {
|
||||
input := r.URL.RawQuery
|
||||
if input == "" {
|
||||
Input(rw, req, prompt)
|
||||
Input(w, r, prompt)
|
||||
return
|
||||
}
|
||||
f(input)
|
||||
@ -271,58 +271,58 @@ func WithInput(rw *ResponseWriter, req *Request, prompt string, f func(string))
|
||||
|
||||
// Sensitive responds to the request with a request for sensitive input
|
||||
// using the given prompt.
|
||||
func SensitiveInput(rw *ResponseWriter, req *Request, prompt string) {
|
||||
rw.WriteHeader(StatusSensitiveInput, prompt)
|
||||
func SensitiveInput(w *ResponseWriter, r *Request, prompt string) {
|
||||
w.WriteHeader(StatusSensitiveInput, prompt)
|
||||
}
|
||||
|
||||
// SensitiveInputHandler returns a simpler handler that responds to each request
|
||||
// with a request for sensitive input.
|
||||
func SensitiveInputHandler(prompt string) Handler {
|
||||
return HandlerFunc(func(rw *ResponseWriter, req *Request) {
|
||||
SensitiveInput(rw, req, prompt)
|
||||
return HandlerFunc(func(w *ResponseWriter, r *Request) {
|
||||
SensitiveInput(w, r, prompt)
|
||||
})
|
||||
}
|
||||
|
||||
// WithSensitiveInput either responds to the request with StatusSensitiveInput
|
||||
// if no input is provided, or calls f with the input when provided.
|
||||
func WithSensitiveInput(rw *ResponseWriter, req *Request, prompt string, f func(string)) {
|
||||
input := req.URL.RawQuery
|
||||
func WithSensitiveInput(w *ResponseWriter, r *Request, prompt string, f func(string)) {
|
||||
input := r.URL.RawQuery
|
||||
if input == "" {
|
||||
SensitiveInput(rw, req, prompt)
|
||||
SensitiveInput(w, r, prompt)
|
||||
return
|
||||
}
|
||||
f(input)
|
||||
}
|
||||
|
||||
// Redirect replies to the request with a redirect to the given URL.
|
||||
func Redirect(rw *ResponseWriter, req *Request, url string) {
|
||||
rw.WriteHeader(StatusRedirect, url)
|
||||
func Redirect(w *ResponseWriter, r *Request, url string) {
|
||||
w.WriteHeader(StatusRedirect, url)
|
||||
}
|
||||
|
||||
// RedirectHandler returns a simple handler that responds to each request with
|
||||
// a redirect to the given URL.
|
||||
func RedirectHandler(url string) Handler {
|
||||
return HandlerFunc(func(rw *ResponseWriter, req *Request) {
|
||||
Redirect(rw, req, url)
|
||||
return HandlerFunc(func(w *ResponseWriter, r *Request) {
|
||||
Redirect(w, r, url)
|
||||
})
|
||||
}
|
||||
|
||||
// PermanentRedirect replies to the request with a permanent redirect to the given URL.
|
||||
func PermanentRedirect(rw *ResponseWriter, req *Request, url string) {
|
||||
rw.WriteHeader(StatusRedirectPermanent, url)
|
||||
func PermanentRedirect(w *ResponseWriter, r *Request, url string) {
|
||||
w.WriteHeader(StatusRedirectPermanent, url)
|
||||
}
|
||||
|
||||
// PermanentRedirectHandler returns a simple handler that responds to each request with
|
||||
// a redirect to the given URL.
|
||||
func PermanentRedirectHandler(url string) Handler {
|
||||
return HandlerFunc(func(rw *ResponseWriter, req *Request) {
|
||||
PermanentRedirect(rw, req, url)
|
||||
return HandlerFunc(func(w *ResponseWriter, r *Request) {
|
||||
PermanentRedirect(w, r, url)
|
||||
})
|
||||
}
|
||||
|
||||
// NotFound replies to the request with the NotFound status code.
|
||||
func NotFound(rw *ResponseWriter, req *Request) {
|
||||
rw.WriteHeader(StatusNotFound, "Not found")
|
||||
func NotFound(w *ResponseWriter, r *Request) {
|
||||
w.WriteHeader(StatusNotFound, "Not found")
|
||||
}
|
||||
|
||||
// NotFoundHandler returns a simple handler that responds to each request with
|
||||
@ -332,8 +332,8 @@ func NotFoundHandler() Handler {
|
||||
}
|
||||
|
||||
// Gone replies to the request with the Gone status code.
|
||||
func Gone(rw *ResponseWriter, req *Request) {
|
||||
rw.WriteHeader(StatusGone, "Gone")
|
||||
func Gone(w *ResponseWriter, r *Request) {
|
||||
w.WriteHeader(StatusGone, "Gone")
|
||||
}
|
||||
|
||||
// GoneHandler returns a simple handler that responds to each request with
|
||||
@ -344,24 +344,24 @@ func GoneHandler() Handler {
|
||||
|
||||
// CertificateRequired responds to the request with the CertificateRequired
|
||||
// status code.
|
||||
func CertificateRequired(rw *ResponseWriter, req *Request) {
|
||||
rw.WriteHeader(StatusCertificateRequired, "Certificate required")
|
||||
func CertificateRequired(w *ResponseWriter, r *Request) {
|
||||
w.WriteHeader(StatusCertificateRequired, "Certificate required")
|
||||
}
|
||||
|
||||
// CertificateNotAuthorized responds to the request with
|
||||
// the CertificateNotAuthorized status code.
|
||||
func CertificateNotAuthorized(rw *ResponseWriter, req *Request) {
|
||||
rw.WriteHeader(StatusCertificateNotAuthorized, "Certificate not authorized")
|
||||
func CertificateNotAuthorized(w *ResponseWriter, r *Request) {
|
||||
w.WriteHeader(StatusCertificateNotAuthorized, "Certificate not authorized")
|
||||
}
|
||||
|
||||
// WithCertificate either responds with CertificateRequired if the client did
|
||||
// not provide a certificate, or calls f with the first ceritificate provided.
|
||||
func WithCertificate(rw *ResponseWriter, req *Request, f func(*x509.Certificate)) {
|
||||
if len(req.TLS.PeerCertificates) == 0 {
|
||||
CertificateRequired(rw, req)
|
||||
func WithCertificate(w *ResponseWriter, r *Request, f func(*x509.Certificate)) {
|
||||
if len(r.TLS.PeerCertificates) == 0 {
|
||||
CertificateRequired(w, r)
|
||||
return
|
||||
}
|
||||
cert := req.TLS.PeerCertificates[0]
|
||||
cert := r.TLS.PeerCertificates[0]
|
||||
f(cert)
|
||||
}
|
||||
|
||||
@ -369,16 +369,16 @@ func WithCertificate(rw *ResponseWriter, req *Request, f func(*x509.Certificate)
|
||||
// clients if they did not provide one, and calls f with the first certificate
|
||||
// if they did.
|
||||
func CertificateHandler(f func(*x509.Certificate)) Handler {
|
||||
return HandlerFunc(func(rw *ResponseWriter, req *Request) {
|
||||
WithCertificate(rw, req, f)
|
||||
return HandlerFunc(func(w *ResponseWriter, r *Request) {
|
||||
WithCertificate(w, r, f)
|
||||
})
|
||||
}
|
||||
|
||||
// HandlerFunc is a wrapper around a bare function that implements Handler.
|
||||
type HandlerFunc func(*ResponseWriter, *Request)
|
||||
|
||||
func (f HandlerFunc) Serve(rw *ResponseWriter, req *Request) {
|
||||
f(rw, req)
|
||||
func (f HandlerFunc) Serve(w *ResponseWriter, r *Request) {
|
||||
f(w, r)
|
||||
}
|
||||
|
||||
// The following code is modified from the net/http package.
|
||||
|
Loading…
Reference in New Issue
Block a user