1package webfinger
2
3import (
4	"encoding/json"
5	"errors"
6	"net/http"
7)
8
9// WebFingerPath defines the default path of the webfinger handler.
10const WebFingerPath = "/.well-known/webfinger"
11
12func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
13
14	//TODO: support host-meta as a path
15
16	path := r.URL.Path
17	switch path {
18	case WebFingerPath:
19		s.Webfinger(w, r)
20	default:
21		s.NotFoundHandler.ServeHTTP(w, r)
22	}
23}
24
25// Webfinger is the webfinger handler
26func (s *Service) Webfinger(w http.ResponseWriter, r *http.Request) {
27	s.runPrehandlers(w, r)
28
29	if r.TLS == nil && s.NoTLSHandler != nil {
30		s.NoTLSHandler.ServeHTTP(w, r)
31		return
32	}
33
34	//NOTE: should this run before or after the pre-run handlers?
35	if r.Method != "GET" {
36		s.MethodNotSupportedHandler.ServeHTTP(w, r)
37		return
38	}
39
40	if len(r.URL.Query()["resource"]) != 1 {
41		s.MalformedRequestHandler.ServeHTTP(w, addError(r, errors.New("Malformed resource parameter")))
42		return
43	}
44	resource := r.URL.Query().Get("resource")
45	var a account
46	if err := a.ParseString(resource); err != nil {
47		s.MalformedRequestHandler.ServeHTTP(w, addError(r, err))
48		return
49	}
50
51	relStrings := r.URL.Query()["rel"]
52	var rels []Rel
53	for _, r := range relStrings {
54		rels = append(rels, Rel(r))
55	}
56
57	rsc, err := s.Resolver.FindUser(a.Name, a.Hostname, r.Host, rels)
58	if err != nil {
59		if !s.Resolver.IsNotFoundError(err) {
60			s.ErrorHandler.ServeHTTP(w, addError(r, err))
61			return
62		}
63
64		rsc, err = s.Resolver.DummyUser(a.Name, a.Hostname, rels)
65		if err != nil && !s.Resolver.IsNotFoundError(err) {
66			s.ErrorHandler.ServeHTTP(w, addError(r, err))
67			return
68		} else if s.Resolver.IsNotFoundError(err) {
69			s.NotFoundHandler.ServeHTTP(w, r)
70			return
71		}
72	}
73
74	if err := json.NewEncoder(w).Encode(&rsc); err != nil {
75		s.ErrorHandler.ServeHTTP(w, addError(r, err))
76		return
77	}
78}
79
80func (s *Service) runPrehandlers(w http.ResponseWriter, r *http.Request) {
81	if s.PreHandlers == nil {
82		return
83	}
84
85	for _, val := range s.PreHandlers {
86		if val != nil {
87			val.ServeHTTP(w, r)
88		}
89	}
90}
91
92func (s *Service) defaultErrorHandler(w http.ResponseWriter, r *http.Request) {
93	w.WriteHeader(http.StatusInternalServerError)
94}
95
96func (s *Service) defaultNotFoundHandler(w http.ResponseWriter, r *http.Request) {
97	w.WriteHeader(http.StatusNotFound)
98}
99
100func (s *Service) defaultMethodNotSupportedHandler(w http.ResponseWriter, r *http.Request) {
101	w.WriteHeader(http.StatusMethodNotAllowed)
102}
103
104func (s *Service) defaultMalformedRequestHandler(w http.ResponseWriter, r *http.Request) {
105	w.WriteHeader(http.StatusBadRequest)
106}
107
108func (s *Service) defaultNoTLSHandler(w http.ResponseWriter, r *http.Request) {
109	u := *r.URL
110	u.Scheme = "https"
111	w.Header().Set("Location", u.String())
112	w.WriteHeader(http.StatusSeeOther)
113}
114