diff --git a/api.go b/api.go index 9683e09..9f2a51c 100644 --- a/api.go +++ b/api.go @@ -8,10 +8,12 @@ import ( "labix.org/v2/mgo" "labix.org/v2/mgo/bson" "net/http" + "net/url" "strconv" ) type VultureBackend struct { + MongoURL string Client *mgo.Session Db *mgo.Database Collection *mgo.Collection @@ -20,20 +22,25 @@ type VultureBackend struct { func GetVultureBackend(req *http.Request) (*VultureBackend, error) { vars := mux.Vars(req) - serverURL, ok := vars["server"] + serverName, ok := vars["server"] if !ok { return nil, errors.New("server field not specified") } - client, err := shared.GetMongoClient(serverURL) + mongoURL, ok := params.MongoServers.GetServerUrl(serverName) + if !ok { + return nil, errors.New("no server for asked name.") + } + + client, err := shared.GetMongoClient(mongoURL) if err != nil { return nil, err } - vb := &VultureBackend{Client: client} - vb.setDatabaseCollection(req) + vb := &VultureBackend{Client: client, MongoURL: mongoURL} + vb.setDatabaseAndCollection(req) return vb, nil } -func (this *VultureBackend) setDatabaseCollection(req *http.Request) { +func (this *VultureBackend) setDatabaseAndCollection(req *http.Request) { vars := mux.Vars(req) database, ok := vars["database"] if !ok { @@ -49,7 +56,23 @@ func (this *VultureBackend) setDatabaseCollection(req *http.Request) { } func (this *VultureBackend) GetDataBases() ([]string, error) { - return this.Client.DatabaseNames() + + dbs, err := this.Client.DatabaseNames() + if err == nil { + return dbs, nil + } else if err.Error() == "unauthorized" { + return this.getDatabaseFromMongoURL() + } else { + return nil, err + } +} + +func (this *VultureBackend) getDatabaseFromMongoURL() ([]string, error) { + u, e := url.Parse(this.MongoURL) + if e != nil { + return nil, errors.New("cannot extract database from url") + } + return []string{u.Path[1:len(u.Path)]}, nil } func (this *VultureBackend) GetCollections() ([]string, error) { @@ -121,7 +144,11 @@ func (this *VultureBackend) GetAllDocuments(query interface{}) (interface{}, err } func getAvailableServers(w http.ResponseWriter, request *http.Request) (interface{}, error) { - return params.MongoServers, nil + ret := make([]string, len(params.MongoServers)) + for i, ms := range params.MongoServers { + ret[i] = ms.Name + } + return ret, nil } func getAvailableDataBases(w http.ResponseWriter, request *http.Request) (interface{}, error) { diff --git a/client/coffee/filters.coffee b/client/coffee/filters.coffee index 19bbc1c..30ad54a 100644 --- a/client/coffee/filters.coffee +++ b/client/coffee/filters.coffee @@ -1,7 +1,7 @@ root = this; root.filters.filter 'escape', () -> - return window.escape; + return window.encodeURIComponent; root.filters.filter 'replaceAllCommasBySpaces', () -> diff --git a/handlerWrapper.go b/handlerWrapper.go index b676133..e3e1d41 100644 --- a/handlerWrapper.go +++ b/handlerWrapper.go @@ -13,6 +13,7 @@ type errorWrapper struct { type ApiHandler func(w http.ResponseWriter, request *http.Request) (interface{}, error) func (this ApiHandler) ServeHTTP(w http.ResponseWriter, request *http.Request) { + log.Println("request for", request.URL) ret, err := this(w, request) if err != nil { log.Println(err) diff --git a/main.go b/main.go index 9e44c8a..93502a4 100644 --- a/main.go +++ b/main.go @@ -14,10 +14,26 @@ import ( const PARAM_FILE string = "params.yml" const STATIC_DIR string = "client" +type MongoServer struct { + Name string `yaml:"name"` + Url string `yaml:"url"` +} + +type MongoServers []*MongoServer + +func (this MongoServers) GetServerUrl(name string) (url string, found bool) { + for _, server := range this { + if server.Name == name { + return server.Url, true + } + } + return "", false +} + type Params struct { - Port int `yaml:"Port,omitempty"` - ServingAddress string `yaml:"ServingAddress,omitempty"` - MongoServers []string `yaml:"MongoServers,omitempty"` + Port int `yaml:"Port,omitempty"` + ServingAddress string `yaml:"ServingAddress,omitempty"` + MongoServers MongoServers `yaml:"MongoServers,omitempty"` } func (this *Params) LoadFromYamlFile(fileName string) error { @@ -47,7 +63,11 @@ func (this *Params) LoadFromYamlData(data []byte) error { return nil } -var params = &Params{8000, "localhost", []string{"localhost:27017"}} +func GetDefaultParams() *Params { + return &Params{8000, "localhost", MongoServers{&MongoServer{Name: "localhost", Url: "localhost:27017"}}} +} + +var params = GetDefaultParams() func init() { if err := params.LoadFromYamlFile(PARAM_FILE); err != nil { diff --git a/main_test.go b/main_test.go index 0d1b2f0..3bfbaf0 100644 --- a/main_test.go +++ b/main_test.go @@ -6,19 +6,25 @@ import ( "net/http/httptest" "os" "path" - "reflect" "testing" ) -func TestLoadFromYamlDataAndInitialParams(t *testing.T) { +func TestInitialParams(t *testing.T) { + params := GetDefaultParams() if params.Port != 8000 { t.Error("wrong port") } if params.ServingAddress != "localhost" { t.Error("wrong png dpi") } - if !reflect.DeepEqual(params.MongoServers, []string{"localhost:27017"}) { - t.Fail() + if len(params.MongoServers) != 1 { + + t.Error("bad default number of mongo servers", len(params.MongoServers)) + return + } + ms := params.MongoServers[0] + if ms.Name != "localhost" || ms.Url != "localhost:27017" { + t.Error("bad ms", ms) } } @@ -28,7 +34,6 @@ func createMockStaticFile() (*os.File, error) { return nil, err } return f, ioutil.WriteFile(f.Name(), []byte("hello world"), 0600) - } func TestServingStaticFiles(t *testing.T) { diff --git a/params.yml b/params.yml index 24bf5f3..3fad683 100644 --- a/params.yml +++ b/params.yml @@ -12,5 +12,12 @@ Port: 8000 # should use `0.0.0.0` ServingAddress: localhost +# The list of mongo servers. Each server is an object with a field *name* that will +# be shown in the web user interface and a *url* field that points to the mongo server MongoServers: - - localhost:27017 \ No newline at end of file + - + name: localhost + url: localhost:27017 + # - + # name: example + # url: mongodb://username:password@ds90210.mongolab.com:52652/database_name