diff options
| author | Chris Lu <chris.lu@gmail.com> | 2021-06-10 21:50:21 -0700 |
|---|---|---|
| committer | Chris Lu <chris.lu@gmail.com> | 2021-06-10 21:50:21 -0700 |
| commit | 8b382a82097d6fb0f6addb4095a5a090a0ba09d9 (patch) | |
| tree | 491549d7c3960dc6be7393af7bd49f59a727c41f /weed/s3api/s3err/error_handler.go | |
| parent | 33b87244ef99a9651e6564b6cd517e824e35ed70 (diff) | |
| download | seaweedfs-8b382a82097d6fb0f6addb4095a5a090a0ba09d9.tar.xz seaweedfs-8b382a82097d6fb0f6addb4095a5a090a0ba09d9.zip | |
refactor
Diffstat (limited to 'weed/s3api/s3err/error_handler.go')
| -rw-r--r-- | weed/s3api/s3err/error_handler.go | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/weed/s3api/s3err/error_handler.go b/weed/s3api/s3err/error_handler.go new file mode 100644 index 000000000..f176d4b6c --- /dev/null +++ b/weed/s3api/s3err/error_handler.go @@ -0,0 +1,81 @@ +package s3err + +import ( + "bytes" + "encoding/xml" + "fmt" + "github.com/chrislusf/seaweedfs/weed/glog" + "net/http" + "strconv" + "time" +) + +type mimeType string + +const ( + mimeNone mimeType = "" + MimeXML mimeType = "application/xml" +) + +func WriteXMLResponse(w http.ResponseWriter, statusCode int, response interface{}) { + WriteResponse(w, statusCode, EncodeXMLResponse(response), MimeXML) +} + +func WriteEmptyResponse(w http.ResponseWriter, statusCode int) { + WriteResponse(w, statusCode, []byte{}, mimeNone) +} + +func WriteErrorResponse(w http.ResponseWriter, errorCode ErrorCode, r *http.Request) { + apiError := GetAPIError(errorCode) + errorResponse := getRESTErrorResponse(apiError, r.URL.Path) + encodedErrorResponse := EncodeXMLResponse(errorResponse) + WriteResponse(w, apiError.HTTPStatusCode, encodedErrorResponse, MimeXML) +} + +func getRESTErrorResponse(err APIError, resource string) RESTErrorResponse { + return RESTErrorResponse{ + Code: err.Code, + Message: err.Description, + Resource: resource, + RequestID: fmt.Sprintf("%d", time.Now().UnixNano()), + } +} + +// Encodes the response headers into XML format. +func EncodeXMLResponse(response interface{}) []byte { + var bytesBuffer bytes.Buffer + bytesBuffer.WriteString(xml.Header) + e := xml.NewEncoder(&bytesBuffer) + e.Encode(response) + return bytesBuffer.Bytes() +} + +func setCommonHeaders(w http.ResponseWriter) { + w.Header().Set("x-amz-request-id", fmt.Sprintf("%d", time.Now().UnixNano())) + w.Header().Set("Accept-Ranges", "bytes") +} + +func WriteResponse(w http.ResponseWriter, statusCode int, response []byte, mType mimeType) { + setCommonHeaders(w) + if response != nil { + w.Header().Set("Content-Length", strconv.Itoa(len(response))) + } + if mType != mimeNone { + w.Header().Set("Content-Type", string(mType)) + } + w.WriteHeader(statusCode) + if response != nil { + glog.V(4).Infof("status %d %s: %s", statusCode, mType, string(response)) + _, err := w.Write(response) + if err != nil { + glog.V(0).Infof("write err: %v", err) + } + w.(http.Flusher).Flush() + } +} + +// If none of the http routes match respond with MethodNotAllowed +func NotFoundHandler(w http.ResponseWriter, r *http.Request) { + glog.V(0).Infof("unsupported %s %s", r.Method, r.RequestURI) + WriteErrorResponse(w, ErrMethodNotAllowed, r) +} |
