| 
									
										
										
										
											2015-02-15 16:48:15 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2015-07-25 08:51:40 +08:00
										 |  |  |  * Minio Cloud Storage, (C) 2015 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-19 15:52:01 +08:00
										 |  |  | package main | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2015-07-15 05:29:56 +08:00
										 |  |  | 	"crypto/rand" | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 	"encoding/xml" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2015-09-19 15:52:01 +08:00
										 |  |  | 	"runtime" | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 	"strconv" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-24 08:46:48 +08:00
										 |  |  | //// helpers
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-15 05:29:56 +08:00
										 |  |  | // Static alphaNumeric table used for generating unique request ids
 | 
					
						
							|  |  |  | var alphaNumericTable = []byte("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-08 16:40:06 +08:00
										 |  |  | // generateRequestID - Generate request id
 | 
					
						
							| 
									
										
										
										
											2015-07-15 05:29:56 +08:00
										 |  |  | func generateRequestID() []byte { | 
					
						
							|  |  |  | 	alpha := make([]byte, 16) | 
					
						
							|  |  |  | 	rand.Read(alpha) | 
					
						
							|  |  |  | 	for i := 0; i < 16; i++ { | 
					
						
							|  |  |  | 		alpha[i] = alphaNumericTable[alpha[i]%byte(len(alphaNumericTable))] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return alpha | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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.
 | 
					
						
							| 
									
										
										
										
											2015-07-15 05:29:56 +08:00
										 |  |  | 	w.Header().Set("X-Amz-Request-Id", string(generateRequestID())) | 
					
						
							| 
									
										
										
										
											2015-10-17 11:02:37 +08:00
										 |  |  | 	w.Header().Set("Server", ("Minio/" + minioReleaseTag + " (" + runtime.GOOS + "; " + runtime.GOARCH + ")")) | 
					
						
							| 
									
										
										
										
											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() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// set object-related metadata headers
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												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
										 |  |  | 	w.Header().Set("Content-Type", objInfo.ContentType) | 
					
						
							|  |  |  | 	if objInfo.MD5Sum != "" { | 
					
						
							|  |  |  | 		w.Header().Set("ETag", "\""+objInfo.MD5Sum+"\"") | 
					
						
							| 
									
										
										
										
											2016-01-29 11:57:23 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												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
										 |  |  | 	w.Header().Set("Content-Length", strconv.FormatInt(objInfo.Size, 10)) | 
					
						
							| 
									
										
										
										
											2016-03-07 04:16:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// for providing ranged content
 | 
					
						
							| 
									
										
										
										
											2015-07-29 10:33:56 +08:00
										 |  |  | 	if contentRange != nil { | 
					
						
							|  |  |  | 		if contentRange.start > 0 || contentRange.length > 0 { | 
					
						
							| 
									
										
										
										
											2016-03-07 04:16:22 +08:00
										 |  |  | 			// override content-length
 | 
					
						
							|  |  |  | 			w.Header().Set("Content-Length", strconv.FormatInt(contentRange.length, 10)) | 
					
						
							| 
									
										
										
										
											2015-07-29 10:33:56 +08:00
										 |  |  | 			w.Header().Set("Content-Range", contentRange.String()) | 
					
						
							|  |  |  | 			w.WriteHeader(http.StatusPartialContent) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-11 16:01:49 +08:00
										 |  |  | } |