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.

81 lines
2.2 KiB

4 years ago
  1. package s3err
  2. import (
  3. "bytes"
  4. "encoding/xml"
  5. "fmt"
  6. "github.com/chrislusf/seaweedfs/weed/glog"
  7. "net/http"
  8. "strconv"
  9. "time"
  10. )
  11. type mimeType string
  12. const (
  13. mimeNone mimeType = ""
  14. MimeXML mimeType = "application/xml"
  15. )
  16. func WriteXMLResponse(w http.ResponseWriter, statusCode int, response interface{}) {
  17. WriteResponse(w, statusCode, EncodeXMLResponse(response), MimeXML)
  18. }
  19. func WriteEmptyResponse(w http.ResponseWriter, statusCode int) {
  20. WriteResponse(w, statusCode, []byte{}, mimeNone)
  21. }
  22. func WriteErrorResponse(w http.ResponseWriter, errorCode ErrorCode, r *http.Request) {
  23. apiError := GetAPIError(errorCode)
  24. errorResponse := getRESTErrorResponse(apiError, r.URL.Path)
  25. encodedErrorResponse := EncodeXMLResponse(errorResponse)
  26. WriteResponse(w, apiError.HTTPStatusCode, encodedErrorResponse, MimeXML)
  27. }
  28. func getRESTErrorResponse(err APIError, resource string) RESTErrorResponse {
  29. return RESTErrorResponse{
  30. Code: err.Code,
  31. Message: err.Description,
  32. Resource: resource,
  33. RequestID: fmt.Sprintf("%d", time.Now().UnixNano()),
  34. }
  35. }
  36. // Encodes the response headers into XML format.
  37. func EncodeXMLResponse(response interface{}) []byte {
  38. var bytesBuffer bytes.Buffer
  39. bytesBuffer.WriteString(xml.Header)
  40. e := xml.NewEncoder(&bytesBuffer)
  41. e.Encode(response)
  42. return bytesBuffer.Bytes()
  43. }
  44. func setCommonHeaders(w http.ResponseWriter) {
  45. w.Header().Set("x-amz-request-id", fmt.Sprintf("%d", time.Now().UnixNano()))
  46. w.Header().Set("Accept-Ranges", "bytes")
  47. }
  48. func WriteResponse(w http.ResponseWriter, statusCode int, response []byte, mType mimeType) {
  49. setCommonHeaders(w)
  50. if response != nil {
  51. w.Header().Set("Content-Length", strconv.Itoa(len(response)))
  52. }
  53. if mType != mimeNone {
  54. w.Header().Set("Content-Type", string(mType))
  55. }
  56. w.WriteHeader(statusCode)
  57. if response != nil {
  58. glog.V(4).Infof("status %d %s: %s", statusCode, mType, string(response))
  59. _, err := w.Write(response)
  60. if err != nil {
  61. glog.V(0).Infof("write err: %v", err)
  62. }
  63. w.(http.Flusher).Flush()
  64. }
  65. }
  66. // If none of the http routes match respond with MethodNotAllowed
  67. func NotFoundHandler(w http.ResponseWriter, r *http.Request) {
  68. glog.V(0).Infof("unsupported %s %s", r.Method, r.RequestURI)
  69. WriteErrorResponse(w, ErrMethodNotAllowed, r)
  70. }