예제 #1
0
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)
	}
}
예제 #2
0
// 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
}
예제 #3
0
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
}
예제 #4
0
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
}
예제 #6
0
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
}
예제 #7
0
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
}
예제 #9
0
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
}
예제 #10
0
// 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)
}
예제 #11
0
파일: handlers.go 프로젝트: athom/tenpu
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
	}
}