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) }