114 lines
2.7 KiB
Go
114 lines
2.7 KiB
Go
package webfinger
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
)
|
|
|
|
// WebFingerPath defines the default path of the webfinger handler.
|
|
const WebFingerPath = "/.well-known/webfinger"
|
|
|
|
func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
|
//TODO: support host-meta as a path
|
|
|
|
path := r.URL.Path
|
|
switch path {
|
|
case WebFingerPath:
|
|
s.Webfinger(w, r)
|
|
default:
|
|
s.NotFoundHandler.ServeHTTP(w, r)
|
|
}
|
|
}
|
|
|
|
// Webfinger is the webfinger handler
|
|
func (s *Service) Webfinger(w http.ResponseWriter, r *http.Request) {
|
|
s.runPrehandlers(w, r)
|
|
|
|
if r.TLS == nil && s.NoTLSHandler != nil {
|
|
s.NoTLSHandler.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
//NOTE: should this run before or after the pre-run handlers?
|
|
if r.Method != "GET" {
|
|
s.MethodNotSupportedHandler.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
if len(r.URL.Query()["resource"]) != 1 {
|
|
s.MalformedRequestHandler.ServeHTTP(w, addError(r, errors.New("Malformed resource parameter")))
|
|
return
|
|
}
|
|
resource := r.URL.Query().Get("resource")
|
|
var a account
|
|
if err := a.ParseString(resource); err != nil {
|
|
s.MalformedRequestHandler.ServeHTTP(w, addError(r, err))
|
|
return
|
|
}
|
|
|
|
relStrings := r.URL.Query()["rel"]
|
|
var rels []Rel
|
|
for _, r := range relStrings {
|
|
rels = append(rels, Rel(r))
|
|
}
|
|
|
|
rsc, err := s.Resolver.FindUser(a.Name, a.Hostname, r.Host, rels)
|
|
if err != nil {
|
|
if !s.Resolver.IsNotFoundError(err) {
|
|
s.ErrorHandler.ServeHTTP(w, addError(r, err))
|
|
return
|
|
}
|
|
|
|
rsc, err = s.Resolver.DummyUser(a.Name, a.Hostname, rels)
|
|
if err != nil && !s.Resolver.IsNotFoundError(err) {
|
|
s.ErrorHandler.ServeHTTP(w, addError(r, err))
|
|
return
|
|
} else if s.Resolver.IsNotFoundError(err) {
|
|
s.NotFoundHandler.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
}
|
|
|
|
if err := json.NewEncoder(w).Encode(&rsc); err != nil {
|
|
s.ErrorHandler.ServeHTTP(w, addError(r, err))
|
|
return
|
|
}
|
|
}
|
|
|
|
func (s *Service) runPrehandlers(w http.ResponseWriter, r *http.Request) {
|
|
if s.PreHandlers == nil {
|
|
return
|
|
}
|
|
|
|
for _, val := range s.PreHandlers {
|
|
if val != nil {
|
|
val.ServeHTTP(w, r)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *Service) defaultErrorHandler(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
}
|
|
|
|
func (s *Service) defaultNotFoundHandler(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
|
|
func (s *Service) defaultMethodNotSupportedHandler(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
}
|
|
|
|
func (s *Service) defaultMalformedRequestHandler(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
}
|
|
|
|
func (s *Service) defaultNoTLSHandler(w http.ResponseWriter, r *http.Request) {
|
|
u := *r.URL
|
|
u.Scheme = "https"
|
|
w.Header().Set("Location", u.String())
|
|
w.WriteHeader(http.StatusSeeOther)
|
|
}
|