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.

90 lines
2.1 KiB

9 years ago
9 years ago
9 years ago
7 years ago
9 years ago
9 years ago
  1. package weed_server
  2. import (
  3. "io"
  4. "net/http"
  5. "net/url"
  6. "strings"
  7. "github.com/chrislusf/seaweedfs/weed/filer2"
  8. "github.com/chrislusf/seaweedfs/weed/glog"
  9. "github.com/chrislusf/seaweedfs/weed/operation"
  10. "github.com/chrislusf/seaweedfs/weed/util"
  11. )
  12. func (fs *FilerServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request, isGetMethod bool) {
  13. path := r.URL.Path
  14. if strings.HasSuffix(path, "/") && len(path) > 1 {
  15. path = path[:len(path)-1]
  16. }
  17. entry, err := fs.filer.FindEntry(filer2.FullPath(path))
  18. if err != nil {
  19. glog.V(1).Infof("Not found %s: %v", path, err)
  20. w.WriteHeader(http.StatusNotFound)
  21. return
  22. }
  23. if entry.IsDirectory() {
  24. if fs.disableDirListing {
  25. w.WriteHeader(http.StatusMethodNotAllowed)
  26. return
  27. }
  28. fs.listDirectoryHandler(w, r)
  29. return
  30. }
  31. if len(entry.Chunks) == 0 {
  32. glog.V(1).Infof("no file chunks for %s, attr=%+v", path, entry.Attr)
  33. w.WriteHeader(http.StatusNoContent)
  34. return
  35. }
  36. // FIXME pick the right fid
  37. fileId := entry.Chunks[0].FileId
  38. urlLocation, err := operation.LookupFileId(fs.getMasterNode(), fileId)
  39. if err != nil {
  40. glog.V(1).Infoln("operation LookupFileId %s failed, err is %s", fileId, err.Error())
  41. w.WriteHeader(http.StatusNotFound)
  42. return
  43. }
  44. urlString := urlLocation
  45. if fs.redirectOnRead {
  46. http.Redirect(w, r, urlString, http.StatusFound)
  47. return
  48. }
  49. u, _ := url.Parse(urlString)
  50. q := u.Query()
  51. for key, values := range r.URL.Query() {
  52. for _, value := range values {
  53. q.Add(key, value)
  54. }
  55. }
  56. u.RawQuery = q.Encode()
  57. request := &http.Request{
  58. Method: r.Method,
  59. URL: u,
  60. Proto: r.Proto,
  61. ProtoMajor: r.ProtoMajor,
  62. ProtoMinor: r.ProtoMinor,
  63. Header: r.Header,
  64. Body: r.Body,
  65. Host: r.Host,
  66. ContentLength: r.ContentLength,
  67. }
  68. glog.V(3).Infoln("retrieving from", u)
  69. resp, do_err := util.Do(request)
  70. if do_err != nil {
  71. glog.V(0).Infoln("failing to connect to volume server", do_err.Error())
  72. writeJsonError(w, r, http.StatusInternalServerError, do_err)
  73. return
  74. }
  75. defer resp.Body.Close()
  76. for k, v := range resp.Header {
  77. w.Header()[k] = v
  78. }
  79. w.WriteHeader(resp.StatusCode)
  80. io.Copy(w, resp.Body)
  81. }