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

7 years ago
7 years ago
7 years ago
  1. package s3api
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/chrislusf/seaweedfs/weed/glog"
  6. "github.com/gorilla/mux"
  7. "io/ioutil"
  8. "net/http"
  9. )
  10. var (
  11. client *http.Client
  12. )
  13. func init() {
  14. client = &http.Client{Transport: &http.Transport{
  15. MaxIdleConnsPerHost: 1024,
  16. }}
  17. }
  18. type UploadResult struct {
  19. Name string `json:"name,omitempty"`
  20. Size uint32 `json:"size,omitempty"`
  21. Error string `json:"error,omitempty"`
  22. }
  23. func (s3a *S3ApiServer) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
  24. // http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadingObjects.html
  25. vars := mux.Vars(r)
  26. bucket := vars["bucket"]
  27. object := vars["object"]
  28. _, err := validateContentMd5(r.Header)
  29. if err != nil {
  30. writeErrorResponse(w, ErrInvalidDigest, r.URL)
  31. return
  32. }
  33. uploadUrl := fmt.Sprintf("http://%s%s/%s/%s?collection=%s",
  34. s3a.option.Filer, s3a.option.BucketsPath, bucket, object, bucket)
  35. proxyReq, err := http.NewRequest("PUT", uploadUrl, r.Body)
  36. if err != nil {
  37. glog.Errorf("NewRequest %s: %v", uploadUrl, err)
  38. writeErrorResponse(w, ErrInternalError, r.URL)
  39. return
  40. }
  41. proxyReq.Header.Set("Host", s3a.option.Filer)
  42. proxyReq.Header.Set("X-Forwarded-For", r.RemoteAddr)
  43. for header, values := range r.Header {
  44. for _, value := range values {
  45. proxyReq.Header.Add(header, value)
  46. }
  47. }
  48. resp, postErr := client.Do(proxyReq)
  49. if postErr != nil {
  50. glog.Errorf("post to filer: %v", postErr)
  51. writeErrorResponse(w, ErrInternalError, r.URL)
  52. return
  53. }
  54. defer resp.Body.Close()
  55. resp_body, ra_err := ioutil.ReadAll(resp.Body)
  56. if ra_err != nil {
  57. glog.Errorf("upload to filer response read: %v", ra_err)
  58. writeErrorResponse(w, ErrInternalError, r.URL)
  59. return
  60. }
  61. var ret UploadResult
  62. unmarshal_err := json.Unmarshal(resp_body, &ret)
  63. if unmarshal_err != nil {
  64. glog.Errorf("failing to read upload to %s : %v", uploadUrl, string(resp_body))
  65. writeErrorResponse(w, ErrInternalError, r.URL)
  66. return
  67. }
  68. if ret.Error != "" {
  69. glog.Errorf("upload to filer error: %v", ret.Error)
  70. writeErrorResponse(w, ErrInternalError, r.URL)
  71. return
  72. }
  73. writeSuccessResponseEmpty(w)
  74. }