func main() { username, password := waitForPostgres(serviceName) db, err := postgres.Open(serviceName, fmt.Sprintf("dbname=postgres user=%s password=%s", username, password)) if err != nil { log.Fatal(err) } r := martini.NewRouter() m := martini.New() m.Use(martini.Logger()) m.Use(martini.Recovery()) m.Use(render.Renderer()) m.Action(r.Handle) m.Map(db) r.Post("/databases", createDatabase) r.Get("/ping", ping) port := os.Getenv("PORT") if port == "" { port = "3000" } addr := ":" + port if err := discoverd.Register(serviceName+"-api", addr); err != nil { log.Fatal(err) } log.Fatal(http.ListenAndServe(addr, m)) }
func Benchmark_WithoutCORS(b *testing.B) { recorder := httptest.NewRecorder() m := martini.New() b.ResetTimer() for i := 0; i < 100; i++ { r, _ := http.NewRequest("PUT", "foo", nil) m.ServeHTTP(recorder, r) } }
func APIHandler(conf *Config) http.Handler { r := martini.NewRouter() m := martini.New() m.Use(martini.Logger()) m.Use(martini.Recovery()) m.Use(render.Renderer(render.Options{ Directory: conf.StaticPath, Extensions: []string{".html"}, })) m.Action(r.Handle) m.Map(conf) httpInterfaceURL := conf.InterfaceURL if strings.HasPrefix(conf.InterfaceURL, "https") { httpInterfaceURL = "http" + strings.TrimPrefix(conf.InterfaceURL, "https") } m.Use(cors.Allow(&cors.Options{ AllowOrigins: []string{conf.InterfaceURL, httpInterfaceURL}, AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"}, AllowHeaders: []string{"Authorization", "Accept", "Content-Type", "If-Match", "If-None-Match"}, ExposeHeaders: []string{"ETag"}, AllowCredentials: true, MaxAge: time.Hour, })) r.Group(conf.PathPrefix, func(r martini.Router) { m.Use(reqHelperMiddleware) r.Post("/user/sessions", binding.Json(LoginInfo{}), login) r.Delete("/user/session", logout) r.Get("/config", getConfig) r.Get("/cert", getCert) r.Any("/assets/dashboard.*.js", serveDashboardJs) r.Any("/assets.*", martini.Static(filepath.Join(conf.StaticPath, "assets"), martini.StaticOptions{ Prefix: "/assets", })) r.Get("/.*", func(r render.Render) { r.HTML(200, "dashboard", "") }) }) return m }
func apiHandler(router *Router) http.Handler { r := martini.NewRouter() m := martini.New() m.Use(martini.Logger()) m.Use(martini.Recovery()) m.Use(render.Renderer()) m.Action(r.Handle) m.Map(router) r.Post("/routes", binding.Bind(strowger.Route{}), createRoute) r.Put("/routes", binding.Bind(strowger.Route{}), createOrReplaceRoute) r.Get("/routes", getRoutes) r.Get("/routes/:route_type/:route_id", getRoute) r.Delete("/routes/:route_type/:route_id", deleteRoute) return m }
func apiHandler(rtr *Router) http.Handler { r := martini.NewRouter() m := martini.New() m.Map(log.New(os.Stdout, "[router] ", log.LstdFlags|log.Lmicroseconds)) m.Use(martini.Logger()) m.Use(martini.Recovery()) m.Use(render.Renderer()) m.Action(r.Handle) m.Map(rtr) r.Post("/routes", binding.Bind(router.Route{}), createRoute) r.Put("/routes", binding.Bind(router.Route{}), createOrReplaceRoute) r.Get("/routes", getRoutes) r.Get("/routes/:route_type/:route_id", getRoute) r.Delete("/routes/:route_type/:route_id", deleteRoute) return m }
func Test_AllowRegexNoMatch(t *testing.T) { recorder := httptest.NewRecorder() m := martini.New() m.Use(Allow(&Options{ AllowOrigins: []string{"https://*.foo.com"}, })) origin := "https://ww.foo.com.evil.com" r, _ := http.NewRequest("PUT", "foo", nil) r.Header.Add("Origin", origin) m.ServeHTTP(recorder, r) headerValue := recorder.HeaderMap.Get(headerAllowOrigin) if headerValue != "" { t.Errorf("Allow-Origin header should not exist, found %v", headerValue) } }
func Test_AllowAll(t *testing.T) { recorder := httptest.NewRecorder() m := martini.New() m.Use(Allow(&Options{ AllowAllOrigins: true, })) origin := "https://bar.foo.com" r, _ := http.NewRequest("PUT", "foo", nil) r.Header.Add("Origin", origin) m.ServeHTTP(recorder, r) headerValue := recorder.HeaderMap.Get(headerAllowOrigin) if headerValue != origin { t.Errorf("Allow-Origin header should be %v, found %v", origin, headerValue) } }
func Benchmark_WithCORS(b *testing.B) { recorder := httptest.NewRecorder() m := martini.New() m.Use(Allow(&Options{ AllowAllOrigins: true, AllowCredentials: true, AllowMethods: []string{"PATCH", "GET"}, AllowHeaders: []string{"Origin", "X-whatever"}, MaxAge: 5 * time.Minute, })) b.ResetTimer() for i := 0; i < 100; i++ { r, _ := http.NewRequest("PUT", "foo", nil) m.ServeHTTP(recorder, r) } }
func Test_DefaultAllowHeaders(t *testing.T) { recorder := httptest.NewRecorder() m := martini.New() m.Use(Allow(&Options{ AllowAllOrigins: true, })) r, _ := http.NewRequest("PUT", "foo", nil) origin := "https://ww.foo.com.evil.com" r.Header.Add("Origin", origin) m.ServeHTTP(recorder, r) headersVal := recorder.HeaderMap.Get(headerAllowHeaders) if headersVal != "Origin,Accept,Content-Type,Authorization" { t.Errorf("Allow-Headers is expected to be Origin,Accept,Content-Type,Authorization; found %v", headersVal) } }
func APIHandler(conf *Config) http.Handler { r := martini.NewRouter() m := martini.New() m.Use(martini.Logger()) m.Use(martini.Recovery()) m.Use(render.Renderer(render.Options{})) m.Action(r.Handle) m.Map(conf) httpInterfaceURL := conf.InterfaceURL if strings.HasPrefix(conf.InterfaceURL, "https") { httpInterfaceURL = "http" + strings.TrimPrefix(conf.InterfaceURL, "https") } m.Use(corsHandler(&cors.Options{ AllowOrigins: []string{conf.InterfaceURL, httpInterfaceURL}, AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"}, AllowHeaders: []string{"Authorization", "Accept", "Content-Type", "If-Match", "If-None-Match"}, ExposeHeaders: []string{"ETag"}, AllowCredentials: true, MaxAge: time.Hour, })) r.Get(status.Path, status.HealthyHandler.ServeHTTP) r.Group(conf.PathPrefix, func(r martini.Router) { m.Use(reqHelperMiddleware) r.Post("/user/sessions", binding.Bind(LoginInfo{}), login) r.Delete("/user/session", logout) r.Get("/config", getConfig) r.Get("/cert", getCert) r.Any("/assets/dashboard.*.js", serveDashboardJs) r.Any("/assets.*", serveAsset) r.Get("/ping", pingHandler) r.Get("/.*", serveTemplate) }) return m }
func Test_OtherHeaders(t *testing.T) { recorder := httptest.NewRecorder() m := martini.New() m.Use(Allow(&Options{ AllowAllOrigins: true, AllowCredentials: true, AllowMethods: []string{"PATCH", "GET"}, AllowHeaders: []string{"Origin", "X-whatever"}, ExposeHeaders: []string{"Content-Length", "Hello"}, MaxAge: 5 * time.Minute, })) r, _ := http.NewRequest("PUT", "foo", nil) origin := "https://ww.foo.com.evil.com" r.Header.Add("Origin", origin) m.ServeHTTP(recorder, r) credentialsVal := recorder.HeaderMap.Get(headerAllowCredentials) methodsVal := recorder.HeaderMap.Get(headerAllowMethods) headersVal := recorder.HeaderMap.Get(headerAllowHeaders) exposedHeadersVal := recorder.HeaderMap.Get(headerExposeHeaders) maxAgeVal := recorder.HeaderMap.Get(headerMaxAge) if credentialsVal != "true" { t.Errorf("Allow-Credentials is expected to be true, found %v", credentialsVal) } if methodsVal != "PATCH,GET" { t.Errorf("Allow-Methods is expected to be PATCH,GET; found %v", methodsVal) } if headersVal != "Origin,X-whatever" { t.Errorf("Allow-Headers is expected to be Origin,X-whatever; found %v", headersVal) } if exposedHeadersVal != "Content-Length,Hello" { t.Errorf("Expose-Headers are expected to be Content-Length,Hello. Found %v", exposedHeadersVal) } if maxAgeVal != "300" { t.Errorf("Max-Age is expected to be 300, found %v", maxAgeVal) } }
func apiHandler(rtr *Router) http.Handler { r := martini.NewRouter() m := martini.New() m.Map(log.New(os.Stdout, "[router] ", log.LstdFlags|log.Lmicroseconds)) m.Use(martini.Logger()) m.Use(martini.Recovery()) m.Use(render.Renderer()) m.Action(r.Handle) m.Map(rtr) r.Get(status.Path, status.SimpleHandler(rtr.HTTP.Ping).ServeHTTP) r.Post("/routes", binding.Bind(router.Route{}), createRoute) r.Put("/routes/:route_type/:id", binding.Bind(router.Route{}), updateRoute) r.Get("/routes", getRoutes) r.Get("/routes/:route_type/:id", getRoute) r.Delete("/routes/:route_type/:id", deleteRoute) r.Get("/events", streamEvents) r.Any("/debug/**", pprof.Handler.ServeHTTP) return m }
func Test_Preflight(t *testing.T) { recorder := httptest.NewRecorder() m := martini.New() m.Use(Allow(&Options{ AllowAllOrigins: true, AllowMethods: []string{"PUT", "PATCH"}, AllowHeaders: []string{"Origin", "X-whatever", "X-CaseSensitive"}, })) r, _ := http.NewRequest("OPTIONS", "foo", nil) r.Header.Add(headerRequestMethod, "PUT") r.Header.Add(headerRequestHeaders, "X-whatever, x-casesensitive") origin := "https://bar.foo.com" r.Header.Add("Origin", origin) m.ServeHTTP(recorder, r) methodsVal := recorder.HeaderMap.Get(headerAllowMethods) headersVal := recorder.HeaderMap.Get(headerAllowHeaders) originVal := recorder.HeaderMap.Get(headerAllowOrigin) if methodsVal != "PUT,PATCH" { t.Errorf("Allow-Methods is expected to be PUT,PATCH, found %v", methodsVal) } if !strings.Contains(headersVal, "X-whatever") { t.Errorf("Allow-Headers is expected to contain X-whatever, found %v", headersVal) } if !strings.Contains(headersVal, "X-CaseSensitive") { t.Errorf("Allow-Headers is expected to contain x-casesensitive, found %v", headersVal) } if originVal != origin { t.Errorf("Allow-Origin is expected to be %v, found %v", origin, originVal) } }
func appHandler(c handlerConfig) (http.Handler, *martini.Martini) { r := martini.NewRouter() m := martini.New() m.Use(martini.Logger()) m.Use(martini.Recovery()) m.Use(render.Renderer()) m.Use(responseHelperHandler) m.Action(r.Handle) d := NewDB(c.db) providerRepo := NewProviderRepo(d) keyRepo := NewKeyRepo(d) resourceRepo := NewResourceRepo(d) appRepo := NewAppRepo(d, os.Getenv("DEFAULT_ROUTE_DOMAIN"), c.sc) artifactRepo := NewArtifactRepo(d) releaseRepo := NewReleaseRepo(d) jobRepo := NewJobRepo(d) formationRepo := NewFormationRepo(d, appRepo, releaseRepo, artifactRepo) m.Map(resourceRepo) m.Map(appRepo) m.Map(artifactRepo) m.Map(releaseRepo) m.Map(jobRepo) m.Map(formationRepo) m.Map(c.dc) m.MapTo(c.cc, (*clusterClient)(nil)) m.MapTo(c.sc, (*strowgerc.Client)(nil)) m.MapTo(c.dc, (*resource.DiscoverdClient)(nil)) getAppMiddleware := crud("apps", ct.App{}, appRepo, r) getReleaseMiddleware := crud("releases", ct.Release{}, releaseRepo, r) getProviderMiddleware := crud("providers", ct.Provider{}, providerRepo, r) crud("artifacts", ct.Artifact{}, artifactRepo, r) crud("keys", ct.Key{}, keyRepo, r) r.Put("/apps/:apps_id/formations/:releases_id", getAppMiddleware, getReleaseMiddleware, binding.Bind(ct.Formation{}), putFormation) r.Get("/apps/:apps_id/formations/:releases_id", getAppMiddleware, getFormationMiddleware, getFormation) r.Delete("/apps/:apps_id/formations/:releases_id", getAppMiddleware, getFormationMiddleware, deleteFormation) r.Get("/apps/:apps_id/formations", getAppMiddleware, listFormations) r.Post("/apps/:apps_id/jobs", getAppMiddleware, binding.Bind(ct.NewJob{}), runJob) r.Put("/apps/:apps_id/jobs/:jobs_id", getAppMiddleware, binding.Bind(ct.Job{}), putJob) r.Get("/apps/:apps_id/jobs", getAppMiddleware, listJobs) r.Delete("/apps/:apps_id/jobs/:jobs_id", getAppMiddleware, connectHostMiddleware, killJob) r.Get("/apps/:apps_id/jobs/:jobs_id/log", getAppMiddleware, connectHostMiddleware, jobLog) r.Put("/apps/:apps_id/release", getAppMiddleware, binding.Bind(releaseID{}), setAppRelease) r.Get("/apps/:apps_id/release", getAppMiddleware, getAppRelease) r.Post("/providers/:providers_id/resources", getProviderMiddleware, binding.Bind(ct.ResourceReq{}), resourceServerMiddleware, provisionResource) r.Get("/providers/:providers_id/resources", getProviderMiddleware, getProviderResources) r.Get("/providers/:providers_id/resources/:resources_id", getProviderMiddleware, getResourceMiddleware, getResource) r.Put("/providers/:providers_id/resources/:resources_id", getProviderMiddleware, binding.Bind(ct.Resource{}), putResource) r.Get("/apps/:apps_id/resources", getAppMiddleware, getAppResources) r.Post("/apps/:apps_id/routes", getAppMiddleware, binding.Bind(strowger.Route{}), createRoute) r.Get("/apps/:apps_id/routes", getAppMiddleware, getRouteList) r.Get("/apps/:apps_id/routes/:routes_type/:routes_id", getAppMiddleware, getRouteMiddleware, getRoute) r.Delete("/apps/:apps_id/routes/:routes_type/:routes_id", getAppMiddleware, getRouteMiddleware, deleteRoute) return rpcMuxHandler(m, rpcHandler(formationRepo), c.key), m }