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.
		
		
		
		
		
			
		
			
				
					
					
						
							118 lines
						
					
					
						
							2.6 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							118 lines
						
					
					
						
							2.6 KiB
						
					
					
				| package needle | |
| 
 | |
| import ( | |
| 	"fmt" | |
| 	"io" | |
| 	"io/ioutil" | |
| 	"mime" | |
| 	"net/http" | |
| 	"path" | |
| 	"strconv" | |
| 	"strings" | |
| 
 | |
| 	"github.com/chrislusf/seaweedfs/weed/glog" | |
| 	"github.com/chrislusf/seaweedfs/weed/util" | |
| ) | |
| 
 | |
| func parseMultipart(r *http.Request, sizeLimit int64) ( | |
| 	fileName string, data []byte, mimeType string, isGzipped bool, originalDataSize int, isChunkedFile bool, e error) { | |
| 	defer func() { | |
| 		if e != nil && r.Body != nil { | |
| 			io.Copy(ioutil.Discard, r.Body) | |
| 			r.Body.Close() | |
| 		} | |
| 	}() | |
| 	form, fe := r.MultipartReader() | |
| 	if fe != nil { | |
| 		glog.V(0).Infoln("MultipartReader [ERROR]", fe) | |
| 		e = fe | |
| 		return | |
| 	} | |
| 
 | |
| 	//first multi-part item | |
| 	part, fe := form.NextPart() | |
| 	if fe != nil { | |
| 		glog.V(0).Infoln("Reading Multi part [ERROR]", fe) | |
| 		e = fe | |
| 		return | |
| 	} | |
| 
 | |
| 	fileName = part.FileName() | |
| 	if fileName != "" { | |
| 		fileName = path.Base(fileName) | |
| 	} | |
| 
 | |
| 	data, e = ioutil.ReadAll(io.LimitReader(part, sizeLimit+1)) | |
| 	if e != nil { | |
| 		glog.V(0).Infoln("Reading Content [ERROR]", e) | |
| 		return | |
| 	} | |
| 	if len(data) == int(sizeLimit)+1 { | |
| 		e = fmt.Errorf("file over the limited %d bytes", sizeLimit) | |
| 		return | |
| 	} | |
| 
 | |
| 	//if the filename is empty string, do a search on the other multi-part items | |
| 	for fileName == "" { | |
| 		part2, fe := form.NextPart() | |
| 		if fe != nil { | |
| 			break // no more or on error, just safely break | |
| 		} | |
| 
 | |
| 		fName := part2.FileName() | |
| 
 | |
| 		//found the first <file type> multi-part has filename | |
| 		if fName != "" { | |
| 			data2, fe2 := ioutil.ReadAll(io.LimitReader(part2, sizeLimit+1)) | |
| 			if fe2 != nil { | |
| 				glog.V(0).Infoln("Reading Content [ERROR]", fe2) | |
| 				e = fe2 | |
| 				return | |
| 			} | |
| 			if len(data) == int(sizeLimit)+1 { | |
| 				e = fmt.Errorf("file over the limited %d bytes", sizeLimit) | |
| 				return | |
| 			} | |
| 
 | |
| 			//update | |
| 			data = data2 | |
| 			fileName = path.Base(fName) | |
| 			break | |
| 		} | |
| 	} | |
| 
 | |
| 	originalDataSize = len(data) | |
| 
 | |
| 	isChunkedFile, _ = strconv.ParseBool(r.FormValue("cm")) | |
| 
 | |
| 	if !isChunkedFile { | |
| 
 | |
| 		dotIndex := strings.LastIndex(fileName, ".") | |
| 		ext, mtype := "", "" | |
| 		if dotIndex > 0 { | |
| 			ext = strings.ToLower(fileName[dotIndex:]) | |
| 			mtype = mime.TypeByExtension(ext) | |
| 		} | |
| 		contentType := part.Header.Get("Content-Type") | |
| 		if contentType != "" && mtype != contentType { | |
| 			mimeType = contentType //only return mime type if not deductable | |
| 			mtype = contentType | |
| 		} | |
| 
 | |
| 		if part.Header.Get("Content-Encoding") == "gzip" { | |
| 			if unzipped, e := util.UnGzipData(data); e == nil { | |
| 				originalDataSize = len(unzipped) | |
| 			} | |
| 			isGzipped = true | |
| 		} else if util.IsGzippable(ext, mtype, data) { | |
| 			if compressedData, err := util.GzipData(data); err == nil { | |
| 				if len(data) > len(compressedData) { | |
| 					data = compressedData | |
| 					isGzipped = true | |
| 				} | |
| 			} | |
| 		} | |
| 	} | |
| 
 | |
| 	return | |
| }
 |