Add more helper functions
This commit is contained in:
parent
fdf6bbc62f
commit
3c9821d812
@ -85,7 +85,7 @@ func login(rw *gmi.ResponseWriter, req *gmi.Request) {
|
|||||||
rw.WriteHeader(gmi.StatusRedirect, "/login/password")
|
rw.WriteHeader(gmi.StatusRedirect, "/login/password")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rw.WriteHeader(gmi.StatusClientCertificateRequired, "Certificate required")
|
rw.WriteHeader(gmi.StatusCertificateRequired, "Certificate required")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ func loginPassword(rw *gmi.ResponseWriter, req *gmi.Request) {
|
|||||||
if len(req.TLS.PeerCertificates) > 0 {
|
if len(req.TLS.PeerCertificates) > 0 {
|
||||||
session, ok := getSession(req.TLS.PeerCertificates[0])
|
session, ok := getSession(req.TLS.PeerCertificates[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
rw.WriteHeader(gmi.StatusCertificateNotAuthorised, "Not authorized")
|
rw.WriteHeader(gmi.StatusCertificateNotAuthorized, "Not authorized")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ func loginPassword(rw *gmi.ResponseWriter, req *gmi.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rw.WriteHeader(gmi.StatusClientCertificateRequired, "Certificate required")
|
rw.WriteHeader(gmi.StatusCertificateRequired, "Certificate required")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ func profile(rw *gmi.ResponseWriter, req *gmi.Request) {
|
|||||||
if len(req.TLS.PeerCertificates) > 0 {
|
if len(req.TLS.PeerCertificates) > 0 {
|
||||||
session, ok := getSession(req.TLS.PeerCertificates[0])
|
session, ok := getSession(req.TLS.PeerCertificates[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
rw.WriteHeader(gmi.StatusCertificateNotAuthorised, "Certificate not authorized")
|
rw.WriteHeader(gmi.StatusCertificateNotAuthorized, "Certificate not authorized")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := logins[session.username]
|
user := logins[session.username]
|
||||||
@ -134,7 +134,7 @@ func profile(rw *gmi.ResponseWriter, req *gmi.Request) {
|
|||||||
rw.WriteHeader(gmi.StatusSuccess, "text/gemini")
|
rw.WriteHeader(gmi.StatusSuccess, "text/gemini")
|
||||||
rw.Write([]byte(profile))
|
rw.Write([]byte(profile))
|
||||||
} else {
|
} else {
|
||||||
rw.WriteHeader(gmi.StatusClientCertificateRequired, "Certificate required")
|
rw.WriteHeader(gmi.StatusCertificateRequired, "Certificate required")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,17 +142,17 @@ func admin(rw *gmi.ResponseWriter, req *gmi.Request) {
|
|||||||
if len(req.TLS.PeerCertificates) > 0 {
|
if len(req.TLS.PeerCertificates) > 0 {
|
||||||
session, ok := getSession(req.TLS.PeerCertificates[0])
|
session, ok := getSession(req.TLS.PeerCertificates[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
rw.WriteHeader(gmi.StatusCertificateNotAuthorised, "Certificate not authorized")
|
rw.WriteHeader(gmi.StatusCertificateNotAuthorized, "Certificate not authorized")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := logins[session.username]
|
user := logins[session.username]
|
||||||
if !user.admin {
|
if !user.admin {
|
||||||
rw.WriteHeader(gmi.StatusCertificateNotAuthorised, "Admins only!")
|
rw.WriteHeader(gmi.StatusCertificateNotAuthorized, "Admins only!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rw.WriteHeader(gmi.StatusSuccess, "text/gemini")
|
rw.WriteHeader(gmi.StatusSuccess, "text/gemini")
|
||||||
rw.Write([]byte("Welcome to the admin portal.\n"))
|
rw.Write([]byte("Welcome to the admin portal.\n"))
|
||||||
} else {
|
} else {
|
||||||
rw.WriteHeader(gmi.StatusClientCertificateRequired, "Certificate required")
|
rw.WriteHeader(gmi.StatusCertificateRequired, "Certificate required")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ func sendRequest(req *gmi.Request) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: More fine-grained analysis of the status code.
|
||||||
switch resp.Status / 10 {
|
switch resp.Status / 10 {
|
||||||
case gmi.StatusClassInput:
|
case gmi.StatusClassInput:
|
||||||
fmt.Printf("%s: ", resp.Meta)
|
fmt.Printf("%s: ", resp.Meta)
|
||||||
@ -78,7 +79,7 @@ func sendRequest(req *gmi.Request) error {
|
|||||||
return fmt.Errorf("Temporary failure: %s", resp.Meta)
|
return fmt.Errorf("Temporary failure: %s", resp.Meta)
|
||||||
case gmi.StatusClassPermanentFailure:
|
case gmi.StatusClassPermanentFailure:
|
||||||
return fmt.Errorf("Permanent failure: %s", resp.Meta)
|
return fmt.Errorf("Permanent failure: %s", resp.Meta)
|
||||||
case gmi.StatusClassClientCertificateRequired:
|
case gmi.StatusClassCertificateRequired:
|
||||||
fmt.Println("Generating client certificate for", req.Hostname())
|
fmt.Println("Generating client certificate for", req.Hostname())
|
||||||
return nil // TODO: Generate and store client certificate
|
return nil // TODO: Generate and store client certificate
|
||||||
}
|
}
|
||||||
|
48
gemini.go
48
gemini.go
@ -7,34 +7,34 @@ import (
|
|||||||
|
|
||||||
// Status codes.
|
// Status codes.
|
||||||
const (
|
const (
|
||||||
StatusInput = 10
|
StatusInput = 10
|
||||||
StatusSensitiveInput = 11
|
StatusSensitiveInput = 11
|
||||||
StatusSuccess = 20
|
StatusSuccess = 20
|
||||||
StatusRedirect = 30
|
StatusRedirect = 30
|
||||||
StatusRedirectPermanent = 31
|
StatusRedirectPermanent = 31
|
||||||
StatusTemporaryFailure = 40
|
StatusTemporaryFailure = 40
|
||||||
StatusServerUnavailable = 41
|
StatusServerUnavailable = 41
|
||||||
StatusCGIError = 42
|
StatusCGIError = 42
|
||||||
StatusProxyError = 43
|
StatusProxyError = 43
|
||||||
StatusSlowDown = 44
|
StatusSlowDown = 44
|
||||||
StatusPermanentFailure = 50
|
StatusPermanentFailure = 50
|
||||||
StatusNotFound = 51
|
StatusNotFound = 51
|
||||||
StatusGone = 52
|
StatusGone = 52
|
||||||
StatusProxyRequestRefused = 53
|
StatusProxyRequestRefused = 53
|
||||||
StatusBadRequest = 59
|
StatusBadRequest = 59
|
||||||
StatusClientCertificateRequired = 60
|
StatusCertificateRequired = 60
|
||||||
StatusCertificateNotAuthorised = 61
|
StatusCertificateNotAuthorized = 61
|
||||||
StatusCertificateNotValid = 62
|
StatusCertificateNotValid = 62
|
||||||
)
|
)
|
||||||
|
|
||||||
// Status code categories.
|
// Status code categories.
|
||||||
const (
|
const (
|
||||||
StatusClassInput = 1
|
StatusClassInput = 1
|
||||||
StatusClassSuccess = 2
|
StatusClassSuccess = 2
|
||||||
StatusClassRedirect = 3
|
StatusClassRedirect = 3
|
||||||
StatusClassTemporaryFailure = 4
|
StatusClassTemporaryFailure = 4
|
||||||
StatusClassPermanentFailure = 5
|
StatusClassPermanentFailure = 5
|
||||||
StatusClassClientCertificateRequired = 6
|
StatusClassCertificateRequired = 6
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
39
server.go
39
server.go
@ -174,7 +174,7 @@ type Handler interface {
|
|||||||
Serve(*ResponseWriter, *Request)
|
Serve(*ResponseWriter, *Request)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotFound replies to the request with a NotFound status code.
|
// NotFound replies to the request with the NotFound status code.
|
||||||
func NotFound(rw *ResponseWriter, req *Request) {
|
func NotFound(rw *ResponseWriter, req *Request) {
|
||||||
rw.WriteHeader(StatusNotFound, "Not found")
|
rw.WriteHeader(StatusNotFound, "Not found")
|
||||||
}
|
}
|
||||||
@ -185,6 +185,17 @@ func NotFoundHandler() Handler {
|
|||||||
return HandlerFunc(NotFound)
|
return HandlerFunc(NotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gone replies to the request with the Gone status code.
|
||||||
|
func Gone(rw *ResponseWriter, req *Request) {
|
||||||
|
rw.WriteHeader(StatusGone, "Gone")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GoneHandler returns a simple handler that responds to each request with
|
||||||
|
// the status code Gone.
|
||||||
|
func GoneHandler() Handler {
|
||||||
|
return HandlerFunc(Gone)
|
||||||
|
}
|
||||||
|
|
||||||
// Redirect replies to the request with a redirect to the given url.
|
// Redirect replies to the request with a redirect to the given url.
|
||||||
// If permanent is true, Redirect will respond with a permanent redirect.
|
// If permanent is true, Redirect will respond with a permanent redirect.
|
||||||
func Redirect(rw *ResponseWriter, req *Request, url string, permanent bool) {
|
func Redirect(rw *ResponseWriter, req *Request, url string, permanent bool) {
|
||||||
@ -217,6 +228,32 @@ func InputHandler(prompt string) Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CertificateRequired responds to the request with the CertificateRequired
|
||||||
|
// status code.
|
||||||
|
func CertificateRequired(rw *ResponseWriter, req *Request) {
|
||||||
|
rw.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")
|
||||||
|
}
|
||||||
|
|
||||||
// ServeMux is a Gemini request multiplexer.
|
// ServeMux is a Gemini request multiplexer.
|
||||||
// It matches the URL of each incoming request against a list of registered
|
// It matches the URL of each incoming request against a list of registered
|
||||||
// patterns and calls the handler for the pattern that most closesly matches
|
// patterns and calls the handler for the pattern that most closesly matches
|
||||||
|
Loading…
Reference in New Issue
Block a user