diff options
| author | Horus3 | 2015-08-02 00:16:24 +0200 |
|---|---|---|
| committer | Horus3 | 2015-08-02 00:16:24 +0200 |
| commit | 4e1f9ae3e7864e791d6df2c215ca70bd1e42eaf6 (patch) | |
| tree | 604ce9614a40875b5d21a367c3ef9ab175520c88 | |
| parent | 6afcbc7ba57d80bacace21b6e73ca474dd8217ca (diff) | |
| download | mandible-4e1f9ae3e7864e791d6df2c215ca70bd1e42eaf6.tar.gz | |
Added multidomain support.
| -rw-r--r-- | .gitignore | 1 | ||||
| -rwxr-xr-x | env.sh | 13 | ||||
| -rw-r--r-- | imagestore/gcsstore.go | 62 | ||||
| -rw-r--r-- | imagestore/localstore.go | 4 | ||||
| -rw-r--r-- | imagestore/s3store.go | 53 | ||||
| -rw-r--r-- | imagestore/store.go | 4 | ||||
| -rw-r--r-- | imagestore/strippath.go | 10 | ||||
| -rw-r--r-- | mandible.service | 11 | ||||
| -rw-r--r-- | server/server.go | 25 | ||||
| -rwxr-xr-x | start.sh | 12 |
10 files changed, 57 insertions, 138 deletions
@@ -30,5 +30,6 @@ config/conf.json files/ cli/imgup/imgup cli/imgup/imgup.sig +logs/mandible.* *.sw[o-p] @@ -0,0 +1,13 @@ +#!/bin/bash + +export APP="mandible" +export DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) ## you may replace this with hardcoded path +export LOG=$DIR/logs/ + +export PORT=8087 +export IP=127.0.0.1 +export STATIC_DIR=$DIR/static +export IMGUR_GO_CONF=$DIR/config/conf.json +export UPLOAD_DIR=$DIR/files +export UPLOAD_URL=https://i.iamfabulous.de +export ORIGIN_URL=https://images.iamfabulous.de diff --git a/imagestore/gcsstore.go b/imagestore/gcsstore.go deleted file mode 100644 index 67da3d7..0000000 --- a/imagestore/gcsstore.go +++ /dev/null @@ -1,62 +0,0 @@ -package imagestore - -import ( - "io/ioutil" - "log" - - "golang.org/x/net/context" - "google.golang.org/cloud/storage" -) - -type GCSImageStore struct { - ctx context.Context - bucketName string - storeRoot string - namePathMapper *NamePathMapper -} - -func NewGCSImageStore(ctx context.Context, bucket string, root string, mapper *NamePathMapper) *GCSImageStore { - return &GCSImageStore{ - ctx: ctx, - bucketName: bucket, - storeRoot: root, - namePathMapper: mapper, - } -} - -func (this *GCSImageStore) Exists(obj *StoreObject) (bool, error) { - _, err := storage.StatObject(this.ctx, this.bucketName, this.toPath(obj)) - if err != nil { - return false, err - } - return true, nil -} - -func (this *GCSImageStore) Save(src string, obj *StoreObject, url string) (*StoreObject, error) { - data, err := ioutil.ReadFile(src) - if err != nil { - log.Printf("error on read file: %s", err) - return nil, err - } - - wc := storage.NewWriter(this.ctx, this.bucketName, this.toPath(obj)) - wc.ContentType = obj.MimeType - if _, err := wc.Write(data); err != nil { - log.Printf("error on write data: %s", err) - return nil, err - } - if err := wc.Close(); err != nil { - log.Printf("error on close writer: %s", err) - return nil, err - } - - obj.Url = "https://storage.googleapis.com/" + this.bucketName + "/" + this.toPath(obj) - return obj, nil -} - -func (this *GCSImageStore) toPath(obj *StoreObject) string { - if this.storeRoot != "" { - return this.storeRoot + "/" + this.namePathMapper.mapToPath(obj) - } - return this.namePathMapper.mapToPath(obj) -} diff --git a/imagestore/localstore.go b/imagestore/localstore.go index 4df2931..707503d 100644 --- a/imagestore/localstore.go +++ b/imagestore/localstore.go @@ -27,7 +27,7 @@ func (this *LocalImageStore) Exists(obj *StoreObject) (bool, error) { return true, nil } -func (this *LocalImageStore) Save(src string, obj *StoreObject) (*StoreObject, error) { +func (this *LocalImageStore) Save(src string, obj *StoreObject, responseUrl string) (*StoreObject, error) { // open input file fi, err := os.Open(src) if err != nil { @@ -75,7 +75,7 @@ func (this *LocalImageStore) Save(src string, obj *StoreObject) (*StoreObject, e } obj.Url = this.toPath(obj) - obj.Url = stripPath(obj.Url) + obj.Url = stripPath(obj.Url, responseUrl) return obj, nil } diff --git a/imagestore/s3store.go b/imagestore/s3store.go deleted file mode 100644 index c31a45f..0000000 --- a/imagestore/s3store.go +++ /dev/null @@ -1,53 +0,0 @@ -package imagestore - -import ( - "github.com/mitchellh/goamz/s3" - "io/ioutil" -) - -type S3ImageStore struct { - bucketName string - storeRoot string - client *s3.S3 - namePathMapper *NamePathMapper -} - -func NewS3ImageStore(bucket string, root string, client *s3.S3, mapper *NamePathMapper) *S3ImageStore { - return &S3ImageStore{ - bucketName: bucket, - storeRoot: root, - client: client, - namePathMapper: mapper, - } -} - -func (this *S3ImageStore) Exists(obj *StoreObject) (bool, error) { - bucket := this.client.Bucket(this.bucketName) - response, err := bucket.Head(this.toPath(obj)) - if err != nil { - return false, err - } - - return (response.StatusCode == 200), nil -} - -func (this *S3ImageStore) Save(src string, obj *StoreObject, url string) (*StoreObject, error) { - bucket := this.client.Bucket(this.bucketName) - - data, err := ioutil.ReadFile(src) - if err != nil { - return nil, err - } - - err = bucket.Put(this.toPath(obj), data, obj.MimeType, s3.PublicReadWrite) - if err != nil { - return nil, err - } - - obj.Url = "https://s3.amazonaws.com/" + this.bucketName + this.toPath(obj) - return obj, nil -} - -func (this *S3ImageStore) toPath(obj *StoreObject) string { - return this.storeRoot + "/" + this.namePathMapper.mapToPath(obj) -} diff --git a/imagestore/store.go b/imagestore/store.go index a58d1ff..97aaa1d 100644 --- a/imagestore/store.go +++ b/imagestore/store.go @@ -1,13 +1,13 @@ package imagestore type ImageStore interface { - Save(src string, obj *StoreObject) (*StoreObject, error) + Save(src string, obj *StoreObject, url string) (*StoreObject, error) Exists(obj *StoreObject) (bool, error) } type ImageStores []ImageStore -func (this *ImageStores) Save(src string, obj *StoreObject) { +func (this *ImageStores) Save(src string, obj *StoreObject, url string) { // TODO } diff --git a/imagestore/strippath.go b/imagestore/strippath.go index 11ea12e..7f804ce 100644 --- a/imagestore/strippath.go +++ b/imagestore/strippath.go @@ -5,9 +5,15 @@ import ( "strings" ) -func stripPath(url string) string { +func stripPath(url, responseUrl string) string { + var URL string ABSPATH := os.Getenv("UPLOAD_DIR") - URL := os.Getenv("UPLOAD_URL") + if responseUrl == "" { + URL = os.Getenv("UPLOAD_URL") + } else { + URL = responseUrl + } + return URL + strings.Replace(strings.TrimPrefix(url, ABSPATH), "/original/", "/i/", 1) //return URL + strings.TrimPrefix(url, ABSPATH) } diff --git a/mandible.service b/mandible.service new file mode 100644 index 0000000..efdb54a --- /dev/null +++ b/mandible.service @@ -0,0 +1,11 @@ +[Unit] + +Description=Mandible is an image hosting server with RESTlike API. + +[Service] +EnvironmentFile=-/path/to/mandible/env.sh +ExecStart=/path/to/mandible/start.sh +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/server/server.go b/server/server.go index 37fa8aa..58c8411 100644 --- a/server/server.go +++ b/server/server.go @@ -38,7 +38,7 @@ func CreateServer(c *config.Configuration) *Server { return &Server{c, httpclient, store, hashGenerator} } -func (s *Server) uploadFile(uploadFile io.Reader, w http.ResponseWriter, fileName string, thumbs []*uploadedfile.ThumbFile) { +func (s *Server) uploadFile(uploadFile io.Reader, w http.ResponseWriter, fileName string, thumbs []*uploadedfile.ThumbFile, responseUrl string) { w.Header().Set("Content-Type", "application/json") tmpFile, err := ioutil.TempFile(os.TempDir(), "image") @@ -84,7 +84,7 @@ func (s *Server) uploadFile(uploadFile io.Reader, w http.ResponseWriter, fileNam factory := imagestore.NewFactory(s.Config) obj := factory.NewStoreObject(upload.GetHash(), upload.GetMime(), "original") - obj, err = s.imageStore.Save(upload.GetPath(), obj) + obj, err = s.imageStore.Save(upload.GetPath(), obj, responseUrl) if err != nil { ErrorResponse(w, "Unable to save image!", http.StatusInternalServerError) return @@ -94,7 +94,7 @@ func (s *Server) uploadFile(uploadFile io.Reader, w http.ResponseWriter, fileNam for _, t := range upload.GetThumbs() { thumbName := fmt.Sprintf("%s/%s", upload.GetHash(), t.GetName()) tObj := factory.NewStoreObject(thumbName, upload.GetMime(), "t") - tObj, err = s.imageStore.Save(t.GetPath(), tObj) + tObj, err = s.imageStore.Save(t.GetPath(), tObj, responseUrl) if err != nil { ErrorResponse(w, "Unable to save thumbnail!", http.StatusInternalServerError) return @@ -145,7 +145,7 @@ func (s *Server) Start() { return } - s.uploadFile(uploadFile, w, header.Filename, thumbs) + s.uploadFile(uploadFile, w, header.Filename, thumbs, getResponseUrl(r)) uploadFile.Close() } @@ -163,7 +163,7 @@ func (s *Server) Start() { return } - s.uploadFile(uploadFile, w, "", thumbs) + s.uploadFile(uploadFile, w, "", thumbs, getResponseUrl(r)) uploadFile.Close() } @@ -178,7 +178,7 @@ func (s *Server) Start() { return } - s.uploadFile(uploadFile, w, "", thumbs) + s.uploadFile(uploadFile, w, "", thumbs, getResponseUrl(r)) } rootHandler := func(w http.ResponseWriter, r *http.Request) { @@ -199,7 +199,7 @@ func (s *Server) Start() { err := templ.ExecuteTemplate(w, "api.html", struct { OriginUrl string ResponseUrl string - }{os.Getenv("ORIGIN_URL"), os.Getenv("UPLOAD_URL")}) + }{getOriginUrl(r), getResponseUrl(r)}) if err != nil { ErrorResponse(w, err.Error(), http.StatusInternalServerError) return @@ -315,3 +315,14 @@ func parseThumbs(r *http.Request) ([]*uploadedfile.ThumbFile, error) { return thumbs, nil } + +func getResponseUrl(r *http.Request) string { + return r.Header.Get("X-Response-Url") +} + +func getOriginUrl(r *http.Request) string { + if r.Header.Get("X-Origin-Url") != "" { + return r.Header.Get("X-Origin-Url") + } + return os.Getenv("ORIGIN_URL") +} @@ -1,16 +1,8 @@ #!/bin/bash # To be called from start-stop-daemon -APP="mandible" DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -LOG=$DIR cd "$DIR" && \ -PORT=8081 \ -IP=127.0.0.1 \ -STATIC_DIR=$DIR/static \ -IMGUR_GO_CONF=$DIR/config/conf.json \ -UPLOAD_DIR=$DIR/files \ -UPLOAD_URL=https://i.iamfabulous.de \ -ORIGIN_URL=https://images.iamfabulous.de \ -exec "$DIR/$APP" >> ${LOG}/logs/mandible/mandible.log 2 >> ${LOG}/logs/mandible/mandible.err +source "$DIR"/env.sh && \ +exec "$DIR/$APP" >> ${LOG}/mandible.log 2 >> ${LOG}/mandible.err |
