| 
									
										
										
										
											2015-02-15 16:48:15 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2017-03-19 02:28:41 +08:00
										 |  |  |  * Minio Cloud Storage, (C) 2015, 2016, 2017 Minio, Inc. | 
					
						
							| 
									
										
										
										
											2015-02-15 16:48:15 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  | package cmd | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2018-01-23 06:54:55 +08:00
										 |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 	"encoding/xml" | 
					
						
							| 
									
										
										
										
											2017-01-11 08:43:48 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2017-01-11 08:43:48 +08:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-11 08:43:48 +08:00
										 |  |  | // Returns a hexadecimal representation of time at the
 | 
					
						
							|  |  |  | // time response is sent to the client.
 | 
					
						
							|  |  |  | func mustGetRequestID(t time.Time) string { | 
					
						
							|  |  |  | 	return fmt.Sprintf("%X", t.UnixNano()) | 
					
						
							| 
									
										
										
										
											2015-07-15 05:29:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-24 08:46:48 +08:00
										 |  |  | // Write http common headers
 | 
					
						
							| 
									
										
										
										
											2016-01-08 16:40:06 +08:00
										 |  |  | func setCommonHeaders(w http.ResponseWriter) { | 
					
						
							|  |  |  | 	// Set unique request ID for each reply.
 | 
					
						
							| 
									
										
										
										
											2017-03-19 02:28:41 +08:00
										 |  |  | 	w.Header().Set(responseRequestIDKey, mustGetRequestID(UTCNow())) | 
					
						
							| 
									
										
										
										
											2017-01-10 06:22:10 +08:00
										 |  |  | 	w.Header().Set("Server", globalServerUserAgent) | 
					
						
							| 
									
										
										
										
											2017-06-24 07:05:40 +08:00
										 |  |  | 	// Set `x-amz-bucket-region` only if region is set on the server
 | 
					
						
							|  |  |  | 	// by default minio uses an empty region.
 | 
					
						
							| 
									
										
										
										
											2017-11-30 05:12:47 +08:00
										 |  |  | 	if region := globalServerConfig.GetRegion(); region != "" { | 
					
						
							| 
									
										
										
										
											2017-06-24 07:05:40 +08:00
										 |  |  | 		w.Header().Set("X-Amz-Bucket-Region", region) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-11 16:01:49 +08:00
										 |  |  | 	w.Header().Set("Accept-Ranges", "bytes") | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 04:16:22 +08:00
										 |  |  | // Encodes the response headers into XML format.
 | 
					
						
							|  |  |  | func encodeResponse(response interface{}) []byte { | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 	var bytesBuffer bytes.Buffer | 
					
						
							| 
									
										
										
										
											2015-12-10 07:38:40 +08:00
										 |  |  | 	bytesBuffer.WriteString(xml.Header) | 
					
						
							| 
									
										
										
										
											2015-10-04 15:27:49 +08:00
										 |  |  | 	e := xml.NewEncoder(&bytesBuffer) | 
					
						
							| 
									
										
										
										
											2015-09-10 06:11:37 +08:00
										 |  |  | 	e.Encode(response) | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 	return bytesBuffer.Bytes() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-23 06:54:55 +08:00
										 |  |  | // Encodes the response headers into JSON format.
 | 
					
						
							|  |  |  | func encodeResponseJSON(response interface{}) []byte { | 
					
						
							|  |  |  | 	var bytesBuffer bytes.Buffer | 
					
						
							|  |  |  | 	e := json.NewEncoder(&bytesBuffer) | 
					
						
							|  |  |  | 	e.Encode(response) | 
					
						
							|  |  |  | 	return bytesBuffer.Bytes() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-24 08:46:48 +08:00
										 |  |  | // Write object header
 | 
					
						
							| 
									
										
										
											
												objectAPI: Fix object API interface, remove unnecessary structs.
ObjectAPI changes.
```
ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, *probe.Error)
ListMultipartUploads(bucket, objectPrefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int) (ListMultipartsInfo, *probe.Error)
ListObjectParts(bucket, object, uploadID string, partNumberMarker, maxParts int) (ListPartsInfo, *probe.Error)
CompleteMultipartUpload(bucket string, object string, uploadID string, parts []completePart) (ObjectInfo, *probe.Error)
```
											
										 
											2016-04-03 16:34:20 +08:00
										 |  |  | func setObjectHeaders(w http.ResponseWriter, objInfo ObjectInfo, contentRange *httpRange) { | 
					
						
							| 
									
										
										
										
											2015-07-29 10:33:56 +08:00
										 |  |  | 	// set common headers
 | 
					
						
							| 
									
										
										
										
											2016-03-07 04:16:22 +08:00
										 |  |  | 	setCommonHeaders(w) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 11:31:45 +08:00
										 |  |  | 	// Set content length.
 | 
					
						
							|  |  |  | 	w.Header().Set("Content-Length", strconv.FormatInt(objInfo.Size, 10)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set last modified time.
 | 
					
						
							| 
									
										
										
										
											2016-04-09 01:37:38 +08:00
										 |  |  | 	lastModified := objInfo.ModTime.UTC().Format(http.TimeFormat) | 
					
						
							| 
									
										
										
										
											2016-03-07 04:16:22 +08:00
										 |  |  | 	w.Header().Set("Last-Modified", lastModified) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 11:31:45 +08:00
										 |  |  | 	// Set Etag if available.
 | 
					
						
							| 
									
										
										
										
											2017-05-15 03:05:51 +08:00
										 |  |  | 	if objInfo.ETag != "" { | 
					
						
							|  |  |  | 		w.Header().Set("ETag", "\""+objInfo.ETag+"\"") | 
					
						
							| 
									
										
										
										
											2016-01-29 11:57:23 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-07-23 11:31:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-13 18:56:16 +08:00
										 |  |  | 	if objInfo.ContentType != "" { | 
					
						
							|  |  |  | 		w.Header().Set("Content-Type", objInfo.ContentType) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if objInfo.ContentEncoding != "" { | 
					
						
							|  |  |  | 		w.Header().Set("Content-Encoding", objInfo.ContentEncoding) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 11:31:45 +08:00
										 |  |  | 	// Set all other user defined metadata.
 | 
					
						
							| 
									
										
										
										
											2016-07-13 03:45:17 +08:00
										 |  |  | 	for k, v := range objInfo.UserDefined { | 
					
						
							| 
									
										
										
										
											2018-03-02 08:15:53 +08:00
										 |  |  | 		if hasPrefix(k, ReservedMetadataPrefix) { | 
					
						
							|  |  |  | 			// Do not need to send any internal metadata
 | 
					
						
							|  |  |  | 			// values to client.
 | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-07-21 03:40:20 +08:00
										 |  |  | 		w.Header().Set(k, v) | 
					
						
							| 
									
										
										
										
											2016-07-13 03:45:17 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-07 04:16:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// for providing ranged content
 | 
					
						
							| 
									
										
										
										
											2016-07-08 22:46:49 +08:00
										 |  |  | 	if contentRange != nil && contentRange.offsetBegin > -1 { | 
					
						
							|  |  |  | 		// Override content-length
 | 
					
						
							| 
									
										
										
										
											2016-07-07 03:50:24 +08:00
										 |  |  | 		w.Header().Set("Content-Length", strconv.FormatInt(contentRange.getLength(), 10)) | 
					
						
							|  |  |  | 		w.Header().Set("Content-Range", contentRange.String()) | 
					
						
							|  |  |  | 		w.WriteHeader(http.StatusPartialContent) | 
					
						
							| 
									
										
										
										
											2015-07-29 10:33:56 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-11 16:01:49 +08:00
										 |  |  | } |