Beispiel #1
0
// New returns a new Storage that stores blobs in the
// given database. The collections created will be given names with the
// given prefix.
func New(db *mgo.Database, collectionPrefix string) *Storage {
	s := &Storage{
		fs: db.GridFS(collectionPrefix),
	}
	// TODO check error
	s.fs.Files.EnsureIndex(mgo.Index{
		Key:    []string{"filename"},
		Unique: true,
	})
	return s
}
Beispiel #2
0
func getMongoFileContent(ctx *goproxy.ProxyCtx, db mgo.Database, objId bson.ObjectId) (file *mgo.GridFile, err error) {
	ctx.Logf("db: %+v", db)
	file, err = db.GridFS("fs").OpenId(objId)

	if err != nil {
		return file, err
		if err == mgo.ErrNotFound {
		}
	}
	//defer file.Close()

	return file, err
}
Beispiel #3
0
// Store file in MongoDB GridFS
func saveFileToMongo(db mgo.Database, objId bson.ObjectId, contentType string, openFile io.Reader, fileName string, ctx *goproxy.ProxyCtx) {
	ctx.Logf("db: %+v", db)
	mdbfile, err := db.GridFS("fs").Create(fileName)
	if err == nil {
		mdbfile.SetContentType(contentType)
		mdbfile.SetId(objId)
		ctx.Logf("Copying to: %s", fileName)
		_, err = io.Copy(mdbfile, openFile)
		if err != nil {
			ctx.Logf("Unable to copy to mongo: %s - %v", fileName, err)
		}
		ctx.Logf("Done copying, closing")
		err = mdbfile.Close()
		if err != nil {
			ctx.Logf("Unable to close copy to mongo")
		}
		ctx.Logf("MongoDB body file saved")
	}
}
Beispiel #4
0
func get(w http.ResponseWriter, req *http.Request, vars martini.Params, db *mgo.Database) {
	// validate _id
	if !bson.IsObjectIdHex(vars["_id"]) {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	// define main variables
	_id := bson.ObjectIdHex(vars["_id"])
	query := db.C(vars["coll"] + ".files").FindId(_id)
	meta := bson.M{}
	err := query.One(&meta)

	// found file or not
	if err != nil {
		if err.Error() == "not found" {
			w.WriteHeader(http.StatusNotFound)
		} else {
			w.WriteHeader(http.StatusBadRequest)
			w.Write([]byte(err.Error()))
		}
		return
	}

	uploadDate := meta["uploadDate"].(time.Time)
	contentType := meta["contentType"].(string)
	fileName := meta["filename"].(string)

	req.ParseForm()
	head := w.Header()
	head.Add("Accept-Ranges", "bytes")
	head.Add("ETag", vars["_id"]+"+"+req.URL.RawQuery)
	head.Add("Date", uploadDate.Format(FORMAT))
	head.Add("Last-Modified", uploadDate.Format(FORMAT))
	// Expires after ten years :)
	head.Add("Expires", uploadDate.Add(87600*time.Hour).Format(FORMAT))
	head.Add("Cache-Control", "public, max-age=31536000")
	head.Add("Content-Type", contentType)
	if _, dl := req.Form["dl"]; (contentType == "application/octet-stream") || dl {
		head.Add("Content-Disposition", "attachment; filename='"+fileName+"'")
	}

	// already served
	if h := req.Header.Get("If-None-Match"); h == vars["_id"]+"+"+req.URL.RawQuery {
		w.WriteHeader(http.StatusNotModified)
		w.Write([]byte("304 Not Modified"))
		return
	}

	// get file
	file, err := db.GridFS(vars["coll"]).OpenId(_id)
	defer file.Close()
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		w.Write([]byte(err.Error()))
		return
	}
	// check to crop/resize
	cr, isCrop := req.Form["crop"]
	scr, isSCrop := req.Form["scrop"]
	rsz, isResize := req.Form["resize"]

	isIn := ^in([]string{"image/png", "image/jpeg"}, file.ContentType()) != 0

	if isCrop && isIn && cr != nil {
		parsed, _ := parseParams(cr[0])
		if parsed != nil {
			crop(w, file, parsed)
			return
		}
	} else if isSCrop && isIn && scr != nil {
		parsed, _ := parseParams(scr[0])
		if parsed != nil {
			smartCrop(w, file, parsed)
			return
		}

	} else if isResize && isIn && rsz != nil {
		parsed, _ := parseParams(rsz[0])
		if parsed != nil {
			resize(w, file, parsed)
			return
		}
	} else {
		io.Copy(w, file)
	}

}
Beispiel #5
0
func post(w http.ResponseWriter, req *http.Request, vars martini.Params, db *mgo.Database) {
	formFile, formHead, err := req.FormFile("field")
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		w.Write([]byte("400 Bad Request"))
		return
	}
	defer formFile.Close()

	//remove any directory names in the filename
	//START: work around IE sending full filepath and manually get filename
	itemHead := formHead.Header["Content-Disposition"][0]
	lookfor := "filename=\""
	fileIndex := strings.Index(itemHead, lookfor)

	if fileIndex < 0 {
		w.WriteHeader(http.StatusBadRequest)
		w.Write([]byte("400 Bad Request"))
		return
	}

	filename := itemHead[fileIndex+len(lookfor):]
	filename = filename[:strings.Index(filename, "\"")]

	slashIndex := strings.LastIndex(filename, "\\")
	if slashIndex > 0 {
		filename = filename[slashIndex+1:]
	}

	slashIndex = strings.LastIndex(filename, "/")
	if slashIndex > 0 {
		filename = filename[slashIndex+1:]
	}
	//END: work around IE sending full filepath

	// GridFs actions
	file, err := db.GridFS(vars["coll"]).Create(filename)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		w.Write([]byte("400 Bad Request"))
		return
	}
	defer file.Close()

	io.Copy(file, formFile)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		w.Write([]byte("400 Bad Request"))
		return
	}

	b := make([]byte, 512)
	formFile.Seek(0, 0)
	formFile.Read(b)

	file.SetContentType(http.DetectContentType(b))
	file.SetMeta(req.Form)
	err = file.Close()

	_id, _ := file.Id().(bson.ObjectId)

	// json response
	field := "/" + _id.Hex() + "/" + filename
	if !conf.TailOnly {
		field = "/" + vars["coll"] + field
	}

	bytes, _ := json.Marshal(map[string]interface{}{
		"error": err,
		"field": field,
	})
	w.Write(bytes)
}