A golang webfinger server implementation
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
2.7 KiB

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