Add helper functions

This commit is contained in:
adnano 2020-09-27 20:52:24 -04:00
parent 370bcf3bb9
commit fdf6bbc62f

View File

@ -40,7 +40,6 @@ type Server struct {
// ListenAndServe listens for requests at the server's configured address. // ListenAndServe listens for requests at the server's configured address.
func (s *Server) ListenAndServe() error { func (s *Server) ListenAndServe() error {
addr := s.Addr addr := s.Addr
if addr == "" { if addr == "" {
addr = ":1965" addr = ":1965"
} }
@ -152,10 +151,10 @@ func (s *Server) respond(conn net.Conn) {
rawurl = rawurl[:len(rawurl)-1] rawurl = rawurl[:len(rawurl)-1]
// Ensure URL is valid // Ensure URL is valid
if len(rawurl) > 1024 { if len(rawurl) > 1024 {
rw.WriteHeader(StatusBadRequest, "Requested URL exceeds 1024 bytes") rw.WriteHeader(StatusBadRequest, "Bad request")
} else if url, err := url.Parse(rawurl); err != nil || url.User != nil { } 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 // Note that we return an error status if User is specified in the URL
rw.WriteHeader(StatusBadRequest, "Requested URL is invalid") rw.WriteHeader(StatusBadRequest, "Bad request")
} else { } else {
// Gather information about the request // Gather information about the request
req := &Request{ req := &Request{
@ -175,32 +174,46 @@ type Handler interface {
Serve(*ResponseWriter, *Request) Serve(*ResponseWriter, *Request)
} }
// NotFound replies to the request with a NotFound status code.
func NotFound(rw *ResponseWriter, req *Request) {
rw.WriteHeader(StatusNotFound, "Not found")
}
// NotFoundHandler returns a simple handler that responds to each request with // NotFoundHandler returns a simple handler that responds to each request with
// the status code NotFound. // the status code NotFound.
func NotFound() Handler { func NotFoundHandler() Handler {
return HandlerFunc(func(rw *ResponseWriter, req *Request) { return HandlerFunc(NotFound)
rw.WriteHeader(StatusNotFound, "Not found")
})
} }
// Redirect returns a simple handler that responds to each request with // Redirect replies to the request with a redirect to the given url.
// If permanent is true, Redirect will respond with a permanent redirect.
func Redirect(rw *ResponseWriter, req *Request, url string, permanent bool) {
if permanent {
rw.WriteHeader(StatusRedirectPermanent, url)
} else {
rw.WriteHeader(StatusRedirect, url)
}
}
// RedirectHandler returns a simple handler that responds to each request with
// a redirect to the given URL. // a redirect to the given URL.
// If permanent is true, the handler will respond with a permanent redirect. // If permanent is true, the handler will respond with a permanent redirect.
func Redirect(url string, permanent bool) Handler { func RedirectHandler(url string, permanent bool) Handler {
return HandlerFunc(func(rw *ResponseWriter, req *Request) { return HandlerFunc(func(rw *ResponseWriter, req *Request) {
if permanent { Redirect(rw, req, url, permanent)
rw.WriteHeader(StatusRedirectPermanent, url)
} else {
rw.WriteHeader(StatusRedirect, url)
}
}) })
} }
// Input returns a simple handler that responds to each request with // 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)
}
// InputHandler returns a simple handler that responds to each request with
// a request for input. // a request for input.
func Input(prompt string) Handler { func InputHandler(prompt string) Handler {
return HandlerFunc(func(rw *ResponseWriter, req *Request) { return HandlerFunc(func(rw *ResponseWriter, req *Request) {
rw.WriteHeader(StatusInput, prompt) Input(rw, req, prompt)
}) })
} }
@ -251,7 +264,7 @@ func (m *ServeMux) HandleFunc(pattern string, handlerFunc func(*ResponseWriter,
func (m *ServeMux) Serve(rw *ResponseWriter, req *Request) { func (m *ServeMux) Serve(rw *ResponseWriter, req *Request) {
h := m.match(req.URL) h := m.match(req.URL)
if h == nil { if h == nil {
rw.WriteHeader(StatusNotFound, "Not found") NotFound(rw, req)
return return
} }
h.Serve(rw, req) h.Serve(rw, req)
@ -305,16 +318,14 @@ type fsHandler struct {
} }
func (fsys fsHandler) Serve(rw *ResponseWriter, req *Request) { func (fsys fsHandler) Serve(rw *ResponseWriter, req *Request) {
// Reject requests with '..' in them
if containsDotDot(req.URL.Path) { if containsDotDot(req.URL.Path) {
// Reject requests with '..' in them NotFound(rw, req)
rw.WriteHeader(StatusBadRequest, "Invalid URL path")
return return
} }
// FIXME: Don't serve paths with .. in them
f, err := fsys.Open(req.URL.Path) f, err := fsys.Open(req.URL.Path)
if err != nil { if err != nil {
rw.WriteHeader(StatusNotFound, "Not found") NotFound(rw, req)
return return
} }
// TODO: detect mimetype // TODO: detect mimetype