func upload(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { uploadTemplate.Execute(w, nil) } else { part_reader, err := r.MultipartReader() if err != nil { log.Println("get file:", err) w.WriteHeader(http.StatusInternalServerError) } log.Println("start copy") var file_part *multipart.Part for { if file_part, err = part_reader.NextPart(); err != nil { if err == io.EOF { err = nil } break } if file_part.FormName() == "file" { if err = write_file(file_part); err != nil { break } } file_part.Close() } if err != nil { log.Println("write file:", err) w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, "/upload", 302) } }
// Extract form fields and file data from a HTTP POST Policy func extractPostPolicyFormValues(reader *multipart.Reader) (filePart io.Reader, fileName string, formValues map[string]string, err error) { /// HTML Form values formValues = make(map[string]string) fileName = "" for err == nil { var part *multipart.Part part, err = reader.NextPart() if part != nil { canonicalFormName := http.CanonicalHeaderKey(part.FormName()) if canonicalFormName != "File" { var buffer []byte limitReader := io.LimitReader(part, maxFormFieldSize+1) buffer, err = ioutil.ReadAll(limitReader) if err != nil { return nil, "", nil, err } if int64(len(buffer)) > maxFormFieldSize { return nil, "", nil, errSizeUnexpected } formValues[canonicalFormName] = string(buffer) } else { filePart = part fileName = part.FileName() // As described in S3 spec, we expect file to be the last form field break } } } return filePart, fileName, formValues, nil }
func extractHTTPFormValues(reader *multipart.Reader) (io.Reader, map[string]string, *probe.Error) { /// HTML Form values formValues := make(map[string]string) filePart := new(bytes.Buffer) var err error for err == nil { var part *multipart.Part part, err = reader.NextPart() if part != nil { if part.FileName() == "" { buffer, err := ioutil.ReadAll(part) if err != nil { return nil, nil, probe.NewError(err) } formValues[http.CanonicalHeaderKey(part.FormName())] = string(buffer) } else { _, err := io.Copy(filePart, part) if err != nil { return nil, nil, probe.NewError(err) } } } } return filePart, formValues, nil }
func multipartUploadHandler(r *http.Request) (albumName, contentType, fileName, contentLength string, fileReader io.Reader, err error) { mbound, err := checkMultipart(r) if err != nil { return } // Count reader, counts bytes read as they are read. creader := iomod.NewReadCounter(r.Body) mreader := multipart.NewReader(creader, mbound) sconlen := r.Header.Get("Content-Length") conlen, err := strconv.Atoi(sconlen) // Picasa REQUIRES Content-Length! if err != nil { log.Println("No Content-Length header or invalid value!", sconlen) return } for { var mpart *multipart.Part mpart, err = mreader.NextPart() if mpart != nil { log.Println("Multipart handler:", mpart, mpart.FormName(), err) } else { return } conlen -= 1 name := mpart.FormName() switch name { case "album": var albumNameBytes []byte albumNameBytes, err = ioutil.ReadAll(mpart) if err != nil { log.Println("Error reading album name!", albumName, err) return } log.Println("Read", creader.Count, "bytes so far ( content-length is", r.Header["Content-Length"], ")") albumName = string(albumNameBytes) case "Filedata": contentType = mpart.Header.Get("Content-Type") var mtypes map[string]string _, mtypes, err = mime.ParseMediaType(mpart.Header.Get("Content-Disposition")) if err != nil { return } fileName = mtypes["filename"] log.Println("Read", creader.Count, "bytes so far ( content-length is", r.Header.Get("Content-Length"), ")") // We have to do this, because it seems like the only reliable way to determine the size of the file... Hopefully the files they send are not too large... // WARNING: Security vunerability with large files, could overrun the server. buf := new(bytes.Buffer) io.Copy(buf, mpart) fileReader = buf contentLength = strconv.Itoa(buf.Len()) } } return }
func checkPartFileExists(t *testing.T, part *multipart.Part) (ok, skipped bool) { if part.FormName() != "file" { return false, true } if part.FileName() != "file1.ext" { t.Errorf("Filename not set") return } return true, false }
func (d *tenpuInput) SetMultipart(part *multipart.Part) (isFile bool) { if part.FileName() != "" { d.FileName = part.FileName() d.ContentType = part.Header["Content-Type"][0] isFile = true return } switch part.FormName() { case "OwnerId": d.OwnerId = formValue(part) } return }
func (this *ImageInput) SetMultipart(part *multipart.Part) (isFile bool) { if part.FileName() != "" { this.FileName = part.FileName() this.ContentType = part.Header["Content-Type"][0] isFile = true return } switch part.FormName() { case "OwnerId": this.OwnerId = formValue(part) } return }
func checkPartSignatureIsValid(t *testing.T, part *multipart.Part) (ok, skipped bool) { if part.FormName() != "signature" { return false, true } var pbody bytes.Buffer if n, err := pbody.ReadFrom(part); err != nil { t.Errorf("Unable to read part: %d %s, %+v", n, err, part) return } if pbody.String() != "ljNZVWWNydBahCG5wWD64fTFEOU=" { t.Errorf("Signature: Expected ljNZVWWNydBahCG5wWD64fTFEOU= got: %s", pbody.String()) } ok = true return }
func getParam(part *multipart.Part) (string, float32, error) { name := part.FormName() fmt.Printf("Read name %s", name) if name == "submit" { return name, float32(0), nil } buffer := make([]byte, 1024) n, err := part.Read(buffer) fmt.Printf("Read %s", string(buffer[:n])) if err != nil { return "", 0.0, err } value, err := strconv.ParseFloat(string(buffer[:n]), 32) if err != nil { return "", 0.0, err } return name, float32(value), nil }
// Create handles multipart upload of meta data and blob func (handler *ObjectWebHandler) Create(w http.ResponseWriter, r *http.Request) { var ( err error part *multipart.Part value []byte file *mgo.GridFile ) // We respond as JSON w.Header().Set("Content-Type", "application/json; charset=utf-8") // Check if the content type is correct if ctype := r.Header.Get("Content-Type"); !strings.HasPrefix(ctype, "multipart/form-data") { respondWithError(w, http.StatusUnsupportedMediaType, "Unsupported media type", fmt.Errorf("Expecting multipart/form-data content type but received: %v", ctype)) return } body, err := r.MultipartReader() if err != nil { respondWithError(w, http.StatusBadRequest, "Failed to parse data", err) return } fs := handler.Session.DB(os.Getenv(EnvGridFSDatabase)).GridFS(os.Getenv(EnvGridFSPrefix)) obj := &ObjectMeta{} obj.Metadata = map[string]interface{}{} obj.Metadata["cid"] = r.Header.Get("X-Correlation-Id") for part, err = body.NextPart(); err == nil; part, err = body.NextPart() { if part.FormName() == "filename" && part.FileName() == "" { value, err = ioutil.ReadAll(part) if err != nil { break } obj.Filename = string(value) } else if part.FormName() == "content_type" && part.FileName() == "" { value, err = ioutil.ReadAll(part) if err != nil { break } obj.ContentType = string(value) } else if part.FormName() == "extra.bucket" && part.FileName() == "" { value, err = ioutil.ReadAll(part) if err != nil { break } obj.Metadata["bucket"] = string(value) } else if part.FormName() == "object" && part.FileName() != "" { file, err = fs.Create(part.FileName()) if err != nil { respondWithError(w, http.StatusInternalServerError, "Failed to create GridFS file", err) return } _, err = io.Copy(file, part) if err != nil { file.Close() respondWithError(w, http.StatusInternalServerError, "Failed to save GridFS file", err) return } } } if err != nil && err != io.EOF { if file != nil { file.Close() } respondWithError(w, http.StatusBadRequest, "Failed to process multipart form", err) return } else if file == nil { respondWithError(w, http.StatusBadRequest, "Bad request", fmt.Errorf("No object has been uploaded")) return } // Update metadata file.SetName(obj.Filename) file.SetMeta(obj.Metadata) if obj.ContentType != "" { file.SetContentType(obj.ContentType) } err = file.Close() if err != nil { respondWithError(w, http.StatusInternalServerError, "Failed to close GridFS file", err) return } obj.ID = file.Id().(bson.ObjectId) // Read newly created meta & return it err = fs.Find(bson.M{"_id": obj.ID}).One(&obj) if err == mgo.ErrNotFound { respondWithError(w, http.StatusInternalServerError, "Newly created could not be found", err) return } else if err != nil { respondWithError(w, http.StatusInternalServerError, "Operational error", err) return } w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(obj) }
func makeUploader(ownerName string, category string, clear bool, storage Storage) http.HandlerFunc { if storage == nil { panic("storage must be provided.") } return func(w http.ResponseWriter, r *http.Request) { mr, err := r.MultipartReader() if err != nil { panic(err) } var ownerId string var part *multipart.Part var attachments []*Attachment for { part, err = mr.NextPart() if err != nil { break } if part.FileName() == "" { if part.FormName() == ownerName { ownerId = formValue(part) } continue } if ownerId == "" { writeJson(w, fmt.Sprintf("ownerId required, Please put a hidden field in form called `%s`", ownerName), nil) return } att := &Attachment{} att.Category = category att.OwnerId = ownerId err = storage.Put(part.FileName(), part.Header["Content-Type"][0], part, att) if err != nil { att.Error = err.Error() } attachments = append(attachments, att) } if len(attachments) == 0 { writeJson(w, "No attachments uploaded.", nil) return } for _, att := range attachments { if att.Error != "" { err = errors.New("Some attachment has error") } else { storage.Database().Save(CollectionName, att) } } if clear { dbc := DatabaseClient{Database: storage.Database()} ats := dbc.Attachments(ownerId) for i := len(ats) - 1; i >= 0; i -= 1 { found := false for _, newAt := range attachments { if ats[i].Id == newAt.Id { found = true break } } if found { continue } for _, newAt := range attachments { if newAt.OwnerId == ats[i].OwnerId { _, err = deleteAttachment(ats[i].Id, storage) } } } } dbc := DatabaseClient{Database: storage.Database()} ats := dbc.Attachments(ownerId) if err != nil { writeJson(w, err.Error(), ats) return } writeJson(w, "", ats) return } }