Skip to content

Commit 9b2b654

Browse files
committed
can save image binary
1 parent c2796d5 commit 9b2b654

File tree

7 files changed

+104
-16
lines changed

7 files changed

+104
-16
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@ imgongo
22
=======
33

44
An image server written in go lang and uses mongodb as backend persistence.
5+
6+
It makes good use of the 16M limitation of mongodb document in order to serve
7+
lots of small files. (It does not use the GridFS because all the files are
8+
smaller than 16M, using GridFS would be a waste of space)

document.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"log"
5+
"time"
56

67
"labix.org/v2/mgo"
78
"labix.org/v2/mgo/bson"
@@ -12,18 +13,20 @@ type Document struct {
1213
Name string `bson:"name"`
1314
Path string `bson:"path"`
1415
ContentType string `bson:"content_type"`
16+
CreatedAt time.Time `bson:"created_at"`
1517
Binary bson.Binary `bson:"binary"`
1618
}
1719

18-
func (d *Document) Collcetion(s *mgo.Session) *mgo.Collection {
20+
func (d Document) Collection(s *mgo.Session) *mgo.Collection {
1921
return s.DB(Configuration.DBName).C(Configuration.Collection)
2022
}
2123

2224
func (d *Document) Save(s *mgo.Session) error {
23-
coll := d.Collcetion(s)
25+
coll := d.Collection(s)
2426

2527
if !bson.IsObjectIdHex(d.Id.Hex()) {
2628
d.Id = bson.NewObjectId()
29+
d.CreatedAt = time.Now()
2730
}
2831

2932
_, err := coll.Upsert(bson.M{"_id": d.Id}, d)
@@ -33,3 +36,13 @@ func (d *Document) Save(s *mgo.Session) error {
3336
}
3437
return nil
3538
}
39+
40+
func (d Document) Find(s *mgo.Session, name string, path string) (*Document, error) {
41+
result := new(Document)
42+
coll := d.Collection(s)
43+
44+
query := coll.Find(bson.M{"name": name, "path": path})
45+
err := query.One(result)
46+
47+
return result, err
48+
}

document_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
"time"
6+
)
7+
8+
func TestCreate(t *testing.T) {
9+
s := MgoSession.Copy()
10+
defer s.Close()
11+
12+
document := &Document{Name: "name", Path: "foo, bar, folder1", CreatedAt: time.Now()}
13+
document.Save(s)
14+
15+
result, err := new(Document).Find(s, "name", "foo, bar, folder1")
16+
if err != nil {
17+
t.Fail()
18+
}
19+
if result.Name != "name" {
20+
t.Fail()
21+
}
22+
23+
result2, err := new(Document).Find(s, "name", "foo, bar")
24+
if err == nil {
25+
t.Fail()
26+
}
27+
if result2.Name == "name" {
28+
t.Fail()
29+
}
30+
}

handler.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package main
22

33
import (
44
"io"
5+
"io/ioutil"
6+
"labix.org/v2/mgo/bson"
57
"log"
68
"net/http"
79
"strings"
@@ -25,17 +27,26 @@ func (h *ImgHandler) handleGET(w http.ResponseWriter, req *http.Request) {
2527
}
2628

2729
func (h *ImgHandler) handlePOST(w http.ResponseWriter, req *http.Request) {
28-
h.createDocument(req)
30+
h.upsertDocument(req)
2931
io.WriteString(w, "Hello POST\n")
3032
}
3133

32-
func (h *ImgHandler) createDocument(req *http.Request) {
34+
func (h *ImgHandler) upsertDocument(req *http.Request) {
3335
s := MgoSession.Copy()
3436
defer s.Close()
3537

3638
name, path := h.convertPath(req.URL.Path)
37-
document := &Document{Name: name, Path: path}
38-
err := document.Save(s)
39+
document, _ := new(Document).Find(s, name, path)
40+
document.Name = name
41+
document.Path = path
42+
43+
data, err := ioutil.ReadAll(req.Body)
44+
if err != nil {
45+
log.Fatalln(err)
46+
}
47+
document.Binary = bson.Binary{0x00, data}
48+
49+
err = document.Save(s)
3950
if err != nil {
4051
log.Fatalln(err)
4152
}

handler_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"net/http"
6+
"net/http/httptest"
7+
"os"
8+
"path/filepath"
9+
"testing"
10+
)
11+
12+
func TestHandlePOST(t *testing.T) {
13+
picture1, err := os.Open(filepath.Join(
14+
os.Getenv("GOPATH"), "src", "github.com", "arkxu", "imgongo", "testdata", "picture1.png"))
15+
if err != nil {
16+
log.Panicln(err)
17+
}
18+
19+
req, err := http.NewRequest("POST", "http://example.com/foo/sdf/sdflkj/abc.jpg", picture1)
20+
if err != nil {
21+
log.Fatal(err)
22+
}
23+
24+
w := httptest.NewRecorder()
25+
26+
hander := &ImgHandler{}
27+
hander.ServeHTTP(w, req)
28+
}

main.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ type Config struct {
2626
}
2727

2828
func main() {
29+
// start the server
30+
s := &http.Server{
31+
Addr: Configuration.Address,
32+
Handler: new(ImgHandler),
33+
ReadTimeout: Configuration.ReadTimeout * time.Second,
34+
WriteTimeout: Configuration.WriteTimeout * time.Second,
35+
}
36+
log.Panicln(s.ListenAndServe())
37+
38+
}
39+
40+
func init() {
2941
// read config file
3042
configFile, err := os.Open(filepath.Join(
3143
os.Getenv("GOPATH"), "src", "github.com", "arkxu", "imgongo", "config.json"))
@@ -41,14 +53,4 @@ func main() {
4153
if err != nil {
4254
log.Panicln(err)
4355
}
44-
45-
// start the server
46-
s := &http.Server{
47-
Addr: Configuration.Address,
48-
Handler: new(ImgHandler),
49-
ReadTimeout: Configuration.ReadTimeout * time.Second,
50-
WriteTimeout: Configuration.WriteTimeout * time.Second,
51-
}
52-
log.Panicln(s.ListenAndServe())
53-
5456
}

testdata/picture1.png

37 KB
Loading

0 commit comments

Comments
 (0)