Beispiel #1
0
func middlewareScenario(desc string, fn scenarioFunc) {
	Convey(desc, func() {
		defer bus.ClearBusHandlers()

		sc := &scenarioContext{}
		viewsPath, _ := filepath.Abs("../../public/views")

		sc.m = macaron.New()
		sc.m.Use(macaron.Renderer(macaron.RenderOptions{
			Directory: viewsPath,
			Delims:    macaron.Delims{Left: "[[", Right: "]]"},
		}))

		sc.m.Use(GetContextHandler())
		// mock out gc goroutine
		startSessionGC = func() {}
		sc.m.Use(Sessioner(&session.Options{}))

		sc.defaultHandler = func(c *Context) {
			sc.context = c
			if sc.handlerFunc != nil {
				sc.handlerFunc(sc.context)
			}
		}

		sc.m.Get("/", sc.defaultHandler)

		fn(sc)
	})
}
Beispiel #2
0
func main() {
	// flag.Parse()
	log.Info("App Version: %s", APP_VER)
	var port string
	if port = os.Getenv(PortVar); port == "" {
		port = "8080"
	}
	log.Info("PORT: %s", port)

	m := macaron.Classic()
	m.Use(macaron.Renderer())
	// m.Use(middleware.Contexter())

	m.Get("/", func() string {
		return "Hello"
	})
	m.Get("/fibonacci", v1.Fibonacci)

	// log.Info("PORT: %s", setting.HTTPPort)
	// _ = setting.HTTPPort

	http.ListenAndServe(":"+port, m)

	// http.ListenAndServe(fmt.Sprintf(":%d", *port), m)
	// http.ListenAndServe(":"+setting.HTTPPort, m)
	// m.Run(":" + setting.HTTPPort)
}
Beispiel #3
0
func _StartMartini() {
	WEB.Use(macaron.Recovery())
	WEB.Use(macaron.Static("public",
		macaron.StaticOptions{
			FileSystem: bindata.Static(bindata.Options{
				Asset:      public.Asset,
				AssetDir:   public.AssetDir,
				AssetNames: public.AssetNames,
				Prefix:     "",
			}),
			SkipLogging: true,
		},
	))

	WEB.Use(macaron.Renderer(macaron.RenderOptions{
		//Directory:  "templates",                //!!when package,escape this line. Specify what path to load the templates from.
		Layout: "layout", // Specify a layout template. Layouts can call {{ yield }} to render the current template.
		//Extensions: []string{".tmpl", ".html"}, //!!when package,escape this line.  Specify extensions to load for templates.
		//Charset:    "UTF-8",                    //!!when package,escape this line.  Sets encoding for json and html content-types. Default is "UTF-8".
		TemplateFileSystem: bindata.Templates(bindata.Options{ //make templates files into bindata.
			Asset:      templates.Asset,
			AssetDir:   templates.AssetDir,
			AssetNames: templates.AssetNames,
			Prefix:     ""}),
	}))
	LoadRoute()
	WEB.Run(cfg.HOST, cfg.PORT)
}
Beispiel #4
0
func newGitea() *macaron.Macaron {
	m := macaron.Classic()

	m.Use(macaron.Renderer(macaron.RenderOptions{
		Funcs: []template.FuncMap{map[string]interface{}{
			"dict":     base.Dict,
			"str2html": base.Str2html,
			"appVersion": func() string {
				return version
			},
			"appRev": func() string {
				return revision
			},
		}},
	}))

	m.Use(i18n.I18n(i18n.Options{
		Langs:    setting.Langs,
		Names:    setting.Names,
		Redirect: true,
	}))

	m.Get("/", routers.Home)
	m.Get("/docs/images/:all", routers.Static)
	m.Get("/docs", routers.Docs)
	m.Get("/docs/*", routers.Docs)
	m.Get("/about", routers.About)
	m.Get("/team", routers.Team)

	return m
}
Beispiel #5
0
func main() {
	readConfig()

	log.SetOutputLevel(log.Ldebug)
	m.Use(macaron.Renderer())
	m.Run(*srvPort)
}
Beispiel #6
0
func newMacaron() *macaron.Macaron {
	macaron.Env = setting.Env
	m := macaron.New()

	m.Use(middleware.Logger())
	m.Use(macaron.Recovery())

	if setting.EnableGzip {
		m.Use(middleware.Gziper())
	}

	mapStatic(m, "", "public")
	mapStatic(m, "app", "app")
	mapStatic(m, "css", "css")
	mapStatic(m, "img", "img")
	mapStatic(m, "fonts", "fonts")
	mapStatic(m, "robots.txt", "robots.txt")

	m.Use(macaron.Renderer(macaron.RenderOptions{
		Directory:  path.Join(setting.StaticRootPath, "views"),
		IndentJSON: macaron.Env != macaron.PROD,
		Delims:     macaron.Delims{Left: "[[", Right: "]]"},
	}))

	if setting.EnforceDomain {
		m.Use(middleware.ValidateHostHeader(setting.Domain))
	}

	m.Use(middleware.GetContextHandler())
	m.Use(middleware.Sessioner(&setting.SessionOptions))

	return m
}
Beispiel #7
0
func main() {
	// Set log options.
	log.SetOutput(os.Stderr)
	log.SetLevel(log.WarnLevel)

	// Options.
	var opts struct {
		Verbose     bool   `short:"v" long:"verbose" description:"Verbose"`
		Version     bool   `long:"version" description:"Version"`
		BindAddr    string `short:"b" long:"bind-addr" description:"Bind to address" default:"0.0.0.0"`
		Port        int    `short:"p" long:"port" description:"Port" default:"5050"`
		StaticDir   string `short:"s" long:"static-dir" description:"Static content" default:"static"`
		TemplateDir string `short:"t" long:"template-dir" description:"Templates" default:"templates"`
	}

	// Parse options.
	if _, err := flags.Parse(&opts); err != nil {
		ferr := err.(*flags.Error)
		if ferr.Type == flags.ErrHelp {
			os.Exit(0)
		} else {
			log.Fatal(err.Error())
		}
	}

	// Print version.
	if opts.Version {
		fmt.Printf("peekaboo %s\n", Version)
		os.Exit(0)
	}

	// Set verbose.
	if opts.Verbose {
		log.SetLevel(log.InfoLevel)
	}

	// Check root.
	if runtime.GOOS != "darwin" && os.Getuid() != 0 {
		log.Fatal("This application requires root privileges to run.")
	}

	info, err := hwinfo.Get()
	if err != nil {
		log.Fatal(err.Error())
	}

	log.Infof("Using static dir: %s", opts.StaticDir)
	log.Infof("Using template dir: %s", opts.TemplateDir)

	m := macaron.Classic()
	m.Use(macaron.Static(opts.StaticDir))
	m.Use(macaron.Renderer(macaron.RenderOptions{
		Directory:  opts.TemplateDir,
		IndentJSON: true,
	}))

	routes(m, info)
	m.Run(opts.BindAddr, opts.Port)
}
Beispiel #8
0
func main() {
	log.Info("App Version: %s", APP_VER)
	m := macaron.Classic()
	m.Use(macaron.Renderer())
	m.Use(middleware.Contexter())

	m.Get("/fibonacci", v1.Fibonacci)

	m.Run(setting.HTTPPort)
}
Beispiel #9
0
// newMacaron initializes Macaron instance.
func newMacaron() *macaron.Macaron {
	m := macaron.New()
	m.Use(macaron.Logger())
	m.Use(macaron.Recovery())
	if setting.EnableGzip {
		m.Use(macaron.Gziper())
	}
	m.Use(macaron.Static(
		path.Join(setting.StaticRootPath, "public"),
		macaron.StaticOptions{
			SkipLogging: !setting.DisableRouterLog,
		},
	))
	m.Use(macaron.Renderer(macaron.RenderOptions{
		Directory:  path.Join(setting.StaticRootPath, "templates"),
		Funcs:      []template.FuncMap{base.TemplateFuncs},
		IndentJSON: macaron.Env != macaron.PROD,
	}))
	m.Use(i18n.I18n(i18n.Options{
		SubURL:          setting.AppSubUrl,
		Directory:       path.Join(setting.ConfRootPath, "locale"),
		CustomDirectory: path.Join(setting.CustomPath, "conf/locale"),
		Langs:           setting.Langs,
		Names:           setting.Names,
		Redirect:        true,
	}))
	m.Use(cache.Cacher(cache.Options{
		Adapter:  setting.CacheAdapter,
		Interval: setting.CacheInternal,
		Conn:     setting.CacheConn,
	}))
	m.Use(captcha.Captchaer(captcha.Options{
		SubURL: setting.AppSubUrl,
	}))
	m.Use(session.Sessioner(session.Options{
		Provider: setting.SessionProvider,
		Config:   *setting.SessionConfig,
	}))
	m.Use(csrf.Generate(csrf.Options{
		Secret:     setting.SecretKey,
		SetCookie:  true,
		Header:     "X-Csrf-Token",
		CookiePath: setting.AppSubUrl,
	}))
	m.Use(toolbox.Toolboxer(m, toolbox.Options{
		HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{
			&toolbox.HealthCheckFuncDesc{
				Desc: "Database connection",
				Func: models.Ping,
			},
		},
	}))
	m.Use(middleware.Contexter())
	return m
}
Beispiel #10
0
func main() {
	server_root := "https://nicksite.com:3000"
	local_login_url := "http://nicksite.com:4000/login"

	m := macaron.Classic()
	m.Use(macaron.Renderer())
	m.Use(session.Sessioner())

	m.Get("/login", func(ctx *macaron.Context, s session.Store) {
		ticket := ctx.Query("ticket")
		if len(ticket) == 0 {
			ctx.Redirect(server_root + "/login?service=" + local_login_url)
			return
		} else {
			s.Set("ticket", ticket)
			ctx.Redirect("/")
		}
	})

	m.Get("/", func(ctx *macaron.Context, s session.Store) string {
		if s.Get("login") != nil {
			return "Welcome, " + s.Get("login").(string)
		}

		// Retrieve the ticket
		if s.Get("ticket") == nil {
			ctx.Redirect("/login")
			return ""
		}

		// Validate the ticket
		ticket := s.Get("ticket").(string)
		resp, err := http.Get(server_root + "/validate?ticket=" + ticket + "&service=" + local_login_url)

		if err != nil {
			log.Fatalf("ERROR: %s\n", err)
			return "Unable to validate the ticket"
		}

		bs, _ := ioutil.ReadAll(resp.Body)
		split := strings.Split(string(bs), "\n")
		ticketValid, login := split[0] == "yes", split[1]

		if ticketValid {
			s.Set("login", login)
			ctx.Redirect("/")
			return ""
		}

		return "Invalid login"
	})

	m.Run()
}
Beispiel #11
0
func main() {
	m := macaron.Classic()
	m.Use(macaron.Renderer())
	m.Get("/", func(ctx *macaron.Context) {
		ctx.HTML(200, "home")
	})
	m.Get("/ws", func(ctx *macaron.Context) {
		conn, err := upgrader.Upgrade(ctx.Resp, ctx.Req.Request, nil)
		if err != nil {
			log.Printf("Fail to upgrade connection: %v", err)
			return
		}

		stop := make(chan bool)
		for {
			_, data, err := conn.ReadMessage()
			if err != nil {
				if err != io.EOF {
					log.Printf("Fail to read message: %v", err)
				}
				return
			}
			msg := string(data)

			switch msg {
			case "START":
				if len(people) == 0 {
					conn.WriteMessage(websocket.TextMessage, []byte("没人了我会乱说?"))
					conn.Close()
					return
				}
				go sendRandomInfo(conn, stop)
			case "STOP":
				stop <- true
			default:
				// Find corresponding name to display.
				for i, p := range people {
					if p.info == msg {
						if err = conn.WriteMessage(websocket.TextMessage, []byte(p.name)); err != nil {
							log.Printf("Fail to send message: %v", err)
							return
						}
						people = append(people[:i], people[i+1:]...)
					}
				}
			}
		}
	})
	m.Run()
}
Beispiel #12
0
func SetMiddlewares(m *macaron.Macaron) {
	m.Use(macaron.Static("external", macaron.StaticOptions{
		Expires: func() string { return "max-age=0" },
	}))

	m.Map(Log)
	//modify  default template setting
	m.Use(macaron.Renderer(macaron.RenderOptions{
		Directory:       "views",
		Extensions:      []string{".tmpl", ".html"},
		Funcs:           []template.FuncMap{},
		Delims:          macaron.Delims{"<<<", ">>>"},
		Charset:         "UTF-8",
		IndentJSON:      true,
		IndentXML:       true,
		PrefixXML:       []byte("macaron"),
		HTMLContentType: "text/html",
	}))
	m.Use(macaron.Recovery())
}
Beispiel #13
0
func newMacaronInstance() *macaron.Macaron {
	m := macaron.Classic()

	// Middlewares.
	m.Use(macaron.Renderer(macaron.RenderOptions{
		Funcs: []template.FuncMap{funcMap},
	}))
	m.Use(i18n.I18n(i18n.Options{
		Langs:    setting.Langs,
		Names:    setting.Names,
		Redirect: true,
	}))

	// Routers.
	m.Get("/", routers.MacaronDocs)
	m.Get("/docs", routers.MacaronDocs)
	m.Get("/docs/images/:all", routers.MacaronStatic)
	m.Get("/docs/*", routers.MacaronDocs)

	return m
}
Beispiel #14
0
func newMacaron() *macaron.Macaron {
	macaron.Env = setting.Env
	m := macaron.New()

	m.Use(middleware.Logger())
	m.Use(macaron.Recovery())
	m.Use(toolbox.Toolboxer(m))
	m.Use(func(ctx *macaron.Context) {
		if ctx.Req.URL.Path == "/debug/vars" {
			http.DefaultServeMux.ServeHTTP(ctx.Resp, ctx.Req.Request)
		}
	})

	if setting.EnableGzip {
		m.Use(middleware.Gziper())
	}

	mapStatic(m, "", "public")
	mapStatic(m, "app", "app")
	mapStatic(m, "css", "css")
	mapStatic(m, "img", "img")
	mapStatic(m, "fonts", "fonts")
	mapStatic(m, "plugins", "plugins")
	mapStatic(m, "robots.txt", "robots.txxt")

	m.Use(macaron.Renderer(macaron.RenderOptions{
		Directory:  path.Join(setting.StaticRootPath, "views"),
		IndentJSON: macaron.Env != macaron.PROD,
		Delims:     macaron.Delims{Left: "[[", Right: "]]"},
	}))

	if setting.EnforceDomain {
		m.Use(middleware.ValidateHostHeader(setting.Domain))
	}

	m.Use(middleware.GetContextHandler())
	m.Use(middleware.Sessioner(&setting.SessionOptions))

	return m
}
Beispiel #15
0
func newMacaron() *macaron.Macaron {
	macaron.Env = setting.Env
	m := macaron.New()

	m.Use(middleware.Logger())
	m.Use(macaron.Recovery())

	if setting.EnableGzip {
		m.Use(middleware.Gziper())
	}

	for _, route := range plugins.StaticRoutes {
		pluginRoute := path.Join("/public/plugins/", route.Url)
		log.Info("Plugin: Adding static route %s -> %s", pluginRoute, route.Path)
		mapStatic(m, route.Path, "", pluginRoute)
	}

	mapStatic(m, setting.StaticRootPath, "", "public")
	mapStatic(m, setting.StaticRootPath, "app", "app")
	mapStatic(m, setting.StaticRootPath, "css", "css")
	mapStatic(m, setting.StaticRootPath, "img", "img")
	mapStatic(m, setting.StaticRootPath, "fonts", "fonts")
	mapStatic(m, setting.StaticRootPath, "robots.txt", "robots.txt")

	m.Use(macaron.Renderer(macaron.RenderOptions{
		Directory:  path.Join(setting.StaticRootPath, "views"),
		IndentJSON: macaron.Env != macaron.PROD,
		Delims:     macaron.Delims{Left: "[[", Right: "]]"},
	}))

	if setting.EnforceDomain {
		m.Use(middleware.ValidateHostHeader(setting.Domain))
	}

	m.Use(middleware.GetContextHandler())
	m.Use(middleware.Sessioner(&setting.SessionOptions))

	return m
}
Beispiel #16
0
func Test_Bindata(t *testing.T) {
	Convey("Bindata service", t, func() {
		m := macaron.New()
		m.Use(macaron.Static("",
			macaron.StaticOptions{
				SkipLogging: false,
				FileSystem: Static(Options{
					Asset:      testdata.Asset,
					AssetDir:   testdata.AssetDir,
					AssetNames: testdata.AssetNames,
					Prefix:     "",
				}),
			},
		))
		m.Use(macaron.Renderer(macaron.RenderOptions{
			TemplateFileSystem: Templates(Options{
				Asset:      testdata.Asset,
				AssetDir:   testdata.AssetDir,
				AssetNames: testdata.AssetNames,
				Prefix:     "",
			}),
		}))
		m.Get("/", func(ctx *macaron.Context) {
			ctx.HTML(200, "templates/hello", "Joe")
		})

		resp := httptest.NewRecorder()
		req, err := http.NewRequest("GET", "/static/hello.css", nil)
		So(err, ShouldBeNil)
		m.ServeHTTP(resp, req)
		So(resp.Body.String(), ShouldEqual, ".hello.world {\n\tfont-size: 1px;\n}")

		resp = httptest.NewRecorder()
		req, err = http.NewRequest("GET", "/", nil)
		So(err, ShouldBeNil)
		m.ServeHTTP(resp, req)
		So(resp.Body.String(), ShouldEqual, "Hello, Joe!")
	})
}
Beispiel #17
0
func NewApi(adminKey string, metrics met.Backend) *macaron.Macaron {
	m := macaron.Classic()
	m.Use(macaron.Renderer())
	m.Use(GetContextHandler())
	m.Use(Auth(adminKey))
	bind := binding.Bind

	m.Get("/", heartbeat)
	m.Group("/api/v1", func() {
		m.Get("/", heartbeat)
		m.Group("/agents", func() {
			m.Combo("/").
				Get(bind(model.GetAgentsQuery{}), GetAgents).
				Post(AgentQuota(), bind(model.AgentDTO{}), AddAgent).
				Put(bind(model.AgentDTO{}), UpdateAgent)
			m.Get("/:id", GetAgentById)
			m.Get("/:id/metrics", GetAgentMetrics)
			m.Delete("/:id", DeleteAgent)
		})

		m.Get("/metrics", bind(model.GetMetricsQuery{}), GetMetrics)

		m.Group("/tasks", func() {
			m.Combo("/").
				Get(bind(model.GetTasksQuery{}), GetTasks).
				Post(bind(model.TaskDTO{}), TaskQuota(), AddTask).
				Put(bind(model.TaskDTO{}), UpdateTask)
			m.Get("/:id", GetTaskById)
			m.Delete("/:id", DeleteTask)
		})
		m.Get("/socket/:agent/:ver", socket)
	})

	taskCreate = metrics.NewCount("api.tasks_create")
	taskDelete = metrics.NewCount("api.tasks_delete")
	return m
}
Beispiel #18
0
func newGogsInstance() *macaron.Macaron {
	m := macaron.Classic()

	// Middlewares.
	m.Use(macaron.Renderer(macaron.RenderOptions{
		Funcs: []template.FuncMap{funcMap},
	}))
	m.Use(i18n.I18n(i18n.Options{
		Langs:    setting.Langs,
		Names:    setting.Names,
		Redirect: true,
	}))

	// Routers.
	m.Get("/", routers.GogsHome)
	m.Get("/docs", routers.GogsDocs)
	m.Get("/docs/images/:all", routers.GogsStatic)
	m.Get("/docs/*", routers.GogsDocs)
	m.Get("/about", routers.About)
	m.Get("/team", routers.Team)
	m.Get("/donate", routers.Donate)

	return m
}
Beispiel #19
0
func InitApp() *macaron.Macaron {
	app := macaron.Classic()
	app.Use(macaron.Static("public"))
	app.Use(session.Sessioner())
	app.Use(oauth2.Github(
		&goauth2.Config{
			ClientID:     os.Getenv("GITHUB_CLIENT_ID"),
			ClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"),
			// https://developer.github.com/v3/oauth/#scopes
			Scopes:      []string{"user:email", "public_repo", "write:repo_hook"},
			RedirectURL: "",
		},
	))

	app.Use(macaron.Renderer(macaron.RenderOptions{
		Delims: macaron.Delims{"{[", "]}"},
	}))

	app.Get("/", routers.Homepage)
	app.Get("/build", oauth2.LoginRequired, routers.Build)
	app.Post("/stats/:org/:name/:branch/:os/:arch", routers.DownloadStats)

	app.Get("/:org/:name", func(ctx *macaron.Context, r *http.Request) {
		org := ctx.Params(":org")
		//name := ctx.Params(":name")
		if org == "js" {
			ctx.Next()
			return
		}
		ctx.Redirect(r.RequestURI+"/"+"master", 302)
	})

	// api
	app.Group("/api", func() {
		app.Get("/repos", api.RepoList)
		app.Post("/repos", api.AnonymousTriggerBuild)
		app.Any("/user/repos", oauth2.LoginRequired, middleware.UserNeeded, api.UserRepoList)
		app.Get("/recent/repos", api.RecentBuild)
		app.Post("/builds", oauth2.LoginRequired, api.TriggerBuild)

		// accept PUT(callback), POST(trigger build)
		app.Any("/repos/:id/build", oauth2.LoginRequired, middleware.UserNeeded, api.RepoBuild)
		app.Get("/user", oauth2.LoginRequired, middleware.UserNeeded, api.UserInfo)
	})

	app.Get("/explore", func(ctx *macaron.Context) {
		ctx.HTML(200, "explore", nil)
	})
	app.Get("/repos", func(ctx *macaron.Context) {
		ctx.HTML(200, "repos", nil)
	})

	app.Get("/:org/:name/:branch", func(ctx *macaron.Context, r *http.Request) {
		org := ctx.Params(":org")
		name := ctx.Params(":name")
		branch := ctx.Params(":branch")

		// Here need redis connection
		repoPath := org + "/" + name
		domain := "dn-gobuild5.qbox.me"
		buildJson := fmt.Sprintf("//%s/gorelease/%s/%s/%s/%s", domain, org, name, branch, "builds.json")

		ctx.Data["DlCount"], _ = rdx.Get("downloads:" + repoPath).Int64()
		ctx.Data["Org"] = org
		ctx.Data["Name"] = name
		ctx.Data["Branch"] = branch
		ctx.Data["BuildJSON"] = template.URL(buildJson)
		prepo := &Repo{
			Domain: domain,
			Org:    org,
			Name:   name,
			Branch: branch,
			Ext:    "",
		}
		pubs := make([]*Publish, 0)
		pubs = append(pubs, prepo.Pub("darwin", "amd64"))
		pubs = append(pubs, prepo.Pub("linux", "amd64"))
		pubs = append(pubs, prepo.Pub("linux", "386"))
		pubs = append(pubs, prepo.Pub("linux", "arm"))
		pubs = append(pubs, prepo.Pub("windows", "amd64"))
		pubs = append(pubs, prepo.Pub("windows", "386"))
		ctx.Data["Pubs"] = pubs
		ctx.HTML(200, "release")
	})
	return app
}
Beispiel #20
0
func main() {
	// Set log options.
	log.SetOutput(os.Stderr)
	log.SetLevel(log.WarnLevel)

	// Options.
	var opts struct {
		Verbose      bool    `short:"v" long:"verbose" description:"Verbose"`
		Version      bool    `long:"version" description:"Version"`
		BindAddr     string  `short:"b" long:"bind-addr" description:"Bind to address" default:"0.0.0.0"`
		Port         int     `short:"p" long:"port" description:"Port" default:"5050"`
		StaticDir    string  `short:"s" long:"static-dir" description:"Static content" default:"static"`
		TemplateDir  string  `short:"t" long:"template-dir" description:"Templates" default:"templates"`
		KafkaEnabled bool    `short:"K" long:"kafka" description:"Enable Kafka message bus"`
		KafkaTopic   string  `long:"kafka-topic" description:"Kafka topic" default:"peekaboo"`
		KafkaPeers   *string `long:"kafka-peers" description:"Comma-delimited list of Kafka brokers"`
		KafkaCert    *string `long:"kafka-cert" description:"Certificate file for client authentication"`
		KafkaKey     *string `long:"kafka-key" description:"Key file for client client authentication"`
		KafkaCA      *string `long:"kafka-ca" description:"CA file for TLS client authentication"`
		KafkaVerify  bool    `long:"kafka-verify" description:"Verify SSL certificate"`
	}

	// Parse options.
	if _, err := flags.Parse(&opts); err != nil {
		ferr := err.(*flags.Error)
		if ferr.Type == flags.ErrHelp {
			os.Exit(0)
		} else {
			log.Fatal(err.Error())
		}
	}

	// Print version.
	if opts.Version {
		fmt.Printf("peekaboo %s\n", Version)
		os.Exit(0)
	}

	// Set verbose.
	if opts.Verbose {
		log.SetLevel(log.InfoLevel)
	}

	// Check root.
	if runtime.GOOS != "darwin" && os.Getuid() != 0 {
		log.Fatal("This application requires root privileges to run.")
	}

	// Get hardware info.
	info := hwinfo.NewHWInfo()
	if err := info.GetTTL(); err != nil {
		log.Fatal(err.Error())
	}

	// Produce message to Kafka bus.
	log.Infof("Produce startup event to Kafka bus with topic: %s", opts.KafkaTopic)
	if opts.KafkaEnabled {
		if opts.KafkaPeers == nil {
			log.Fatal("You need to specify Kafka Peers")
		}

		user, err := user.Current()
		if err != nil {
			log.Fatal(err.Error())
		}

		event := &Event{
			Name:      "Peekaboo startup",
			EventType: STARTED,
			Created:   time.Now().Format("20060102T150405ZB"),
			CreatedBy: CreatedBy{
				User:    user.Username,
				Service: "peekaboo",
				Host:    info.Hostname,
			},
			Descr: "Peekaboo startup event",
			Data:  info,
		}

		producer := newProducer(strings.Split(*opts.KafkaPeers, ","), opts.KafkaCert, opts.KafkaKey, opts.KafkaCA, opts.KafkaVerify)
		partition, offset, err := producer.SendMessage(&sarama.ProducerMessage{
			Topic: opts.KafkaTopic,
			Value: event,
		})
		if err != nil {
			log.Fatal(err.Error())
		}

		log.Infof("Kafka partition: %v, offset: %v", partition, offset)
	}

	log.Infof("Using static dir: %s", opts.StaticDir)
	log.Infof("Using template dir: %s", opts.TemplateDir)

	m := macaron.Classic()
	m.Use(macaron.Static(opts.StaticDir))
	m.Use(macaron.Renderer(macaron.RenderOptions{
		Directory:  opts.TemplateDir,
		IndentJSON: true,
	}))

	routes(m, info)
	m.Run(opts.BindAddr, opts.Port)
}
Beispiel #21
0
// newMacaron initializes Macaron instance.
func newMacaron() *macaron.Macaron {
	m := macaron.New()
	if !setting.DisableRouterLog {
		m.Use(macaron.Logger())
	}
	m.Use(macaron.Recovery())
	if setting.EnableGzip {
		m.Use(macaron.Gziper())
	}
	if setting.Protocol == setting.FCGI {
		m.SetURLPrefix(setting.AppSubUrl)
	}
	m.Use(macaron.Static(
		path.Join(setting.StaticRootPath, "public"),
		macaron.StaticOptions{
			SkipLogging: setting.DisableRouterLog,
		},
	))
	m.Use(macaron.Static(
		setting.AvatarUploadPath,
		macaron.StaticOptions{
			Prefix:      "avatars",
			SkipLogging: setting.DisableRouterLog,
		},
	))
	m.Use(macaron.Renderer(macaron.RenderOptions{
		Directory:  path.Join(setting.StaticRootPath, "templates"),
		Funcs:      []template.FuncMap{base.TemplateFuncs},
		IndentJSON: macaron.Env != macaron.PROD,
	}))

	localeNames, err := bindata.AssetDir("conf/locale")
	if err != nil {
		log.Fatal(4, "Fail to list locale files: %v", err)
	}
	localFiles := make(map[string][]byte)
	for _, name := range localeNames {
		localFiles[name] = bindata.MustAsset("conf/locale/" + name)
	}
	m.Use(i18n.I18n(i18n.Options{
		SubURL:          setting.AppSubUrl,
		Files:           localFiles,
		CustomDirectory: path.Join(setting.CustomPath, "conf/locale"),
		Langs:           setting.Langs,
		Names:           setting.Names,
		Redirect:        true,
	}))
	m.Use(cache.Cacher(cache.Options{
		Adapter:       setting.CacheAdapter,
		AdapterConfig: setting.CacheConn,
		Interval:      setting.CacheInternal,
	}))
	m.Use(captcha.Captchaer(captcha.Options{
		SubURL: setting.AppSubUrl,
	}))
	m.Use(session.Sessioner(setting.SessionConfig))
	m.Use(csrf.Csrfer(csrf.Options{
		Secret:     setting.SecretKey,
		SetCookie:  true,
		Header:     "X-Csrf-Token",
		CookiePath: setting.AppSubUrl,
	}))
	m.Use(toolbox.Toolboxer(m, toolbox.Options{
		HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{
			&toolbox.HealthCheckFuncDesc{
				Desc: "Database connection",
				Func: models.Ping,
			},
		},
	}))

	// OAuth 2.
	if setting.OauthService != nil {
		for _, info := range setting.OauthService.OauthInfos {
			m.Use(oauth2.NewOAuth2Provider(info.Options, info.AuthUrl, info.TokenUrl))
		}
	}
	m.Use(middleware.Contexter())
	return m
}
Beispiel #22
0
func main() {
	m := macaron.Classic()

	// New permissions middleware
	perm, err := permissionHSTORE.New()
	if err != nil {
		log.Fatalln(err)
	}

	// Blank slate, no default permissions
	//perm.Clear()

	// Logging middleware
	m.Use(macaron.Logger())

	// Renderer middleware
	m.Use(macaron.Renderer())

	// Set up a middleware handler for Macaron, with a custom "permission denied" message.
	permissionHandler := func(ctx *macaron.Context) {
		// Check if the user has the right admin/user rights
		if perm.Rejected(ctx.Resp, ctx.Req.Request) {
			fmt.Fprintf(ctx.Resp, "Permission denied!")
			// Deny the request
			ctx.Error(http.StatusForbidden)
			// Don't call other middleware handlers
			return
		}
		// Call the next middleware handler
		ctx.Next()
	}

	// Enable the permissions middleware, must come before recovery
	m.Use(permissionHandler)

	// Recovery middleware
	m.Use(macaron.Recovery())

	// Get the userstate, used in the handlers below
	userstate := perm.UserState()

	m.Get("/", func(ctx *macaron.Context) (msg string) {
		msg += fmt.Sprintf("Has user bob: %v\n", userstate.HasUser("bob"))
		msg += fmt.Sprintf("Logged in on server: %v\n", userstate.IsLoggedIn("bob"))
		msg += fmt.Sprintf("Is confirmed: %v\n", userstate.IsConfirmed("bob"))
		msg += fmt.Sprintf("Username stored in cookies (or blank): %v\n", userstate.Username(ctx.Req.Request))
		msg += fmt.Sprintf("Current user is logged in, has a valid cookie and *user rights*: %v\n", userstate.UserRights(ctx.Req.Request))
		msg += fmt.Sprintf("Current user is logged in, has a valid cookie and *admin rights*: %v\n", userstate.AdminRights(ctx.Req.Request))
		msg += fmt.Sprintln("\nTry: /register, /confirm, /remove, /login, /logout, /makeadmin, /clear, /data and /admin")
		return // msg
	})

	m.Get("/register", func(ctx *macaron.Context) string {
		userstate.AddUser("bob", "hunter1", "*****@*****.**")
		return fmt.Sprintf("User bob was created: %v\n", userstate.HasUser("bob"))
	})

	m.Get("/confirm", func(ctx *macaron.Context) string {
		userstate.MarkConfirmed("bob")
		return fmt.Sprintf("User bob was confirmed: %v\n", userstate.IsConfirmed("bob"))
	})

	m.Get("/remove", func(ctx *macaron.Context) string {
		userstate.RemoveUser("bob")
		return fmt.Sprintf("User bob was removed: %v\n", !userstate.HasUser("bob"))
	})

	m.Get("/login", func(ctx *macaron.Context) string {
		// Headers will be written, for storing a cookie
		userstate.Login(ctx.Resp, "bob")
		return fmt.Sprintf("bob is now logged in: %v\n", userstate.IsLoggedIn("bob"))
	})

	m.Get("/logout", func(ctx *macaron.Context) string {
		userstate.Logout("bob")
		return fmt.Sprintf("bob is now logged out: %v\n", !userstate.IsLoggedIn("bob"))
	})

	m.Get("/makeadmin", func(ctx *macaron.Context) string {
		userstate.SetAdminStatus("bob")
		return fmt.Sprintf("bob is now administrator: %v\n", userstate.IsAdmin("bob"))
	})

	m.Get("/clear", func(ctx *macaron.Context) string {
		userstate.ClearCookie(ctx.Resp)
		return "Clearing cookie"
	})

	m.Get("/data", func(ctx *macaron.Context) string {
		return "user page that only logged in users must see!"
	})

	m.Get("/admin", func(ctx *macaron.Context) {
		fmt.Fprintf(ctx.Resp, "super secret information that only logged in administrators must see!\n\n")
		if usernames, err := userstate.AllUsernames(); err == nil {
			fmt.Fprintf(ctx.Resp, "list of all users: "+strings.Join(usernames, ", "))
		}
	})

	// Serve
	m.Run(3000)
}
Beispiel #23
0
func main() {
	// initiate the app
	m := macaron.Classic()

	// register middleware
	m.Use(macaron.Recovery())
	m.Use(macaron.Gziper())
	m.Use(macaron.Static("public",
		macaron.StaticOptions{
			// Prefix is the optional prefix used to serve the static directory content. Default is empty string.
			Prefix: "public",
			// SkipLogging will disable [Static] log messages when a static file is served. Default is false.
			SkipLogging: true,
			// IndexFile defines which file to serve as index if it exists. Default is "index.html".
			IndexFile: "index.html",
			// Expires defines which user-defined function to use for producing a HTTP Expires Header. Default is nil.
			// https://developers.google.com/speed/docs/insights/LeverageBrowserCaching
			Expires: func() string { return "max-age=0" },
		}))
	m.Use(session.Sessioner(session.Options{
		// Name of provider. Default is "memory".
		Provider: "memory",
		// Provider configuration, it's corresponding to provider.
		ProviderConfig: "",
		// Cookie name to save session ID. Default is "MacaronSession".
		CookieName: "MacaronSession",
		// Cookie path to store. Default is "/".
		CookiePath: "/",
		// GC interval time in seconds. Default is 3600.
		Gclifetime: 3600,
		// Max life time in seconds. Default is whatever GC interval time is.
		Maxlifetime: 3600,
		// Use HTTPS only. Default is false.
		Secure: false,
		// Cookie life time. Default is 0.
		CookieLifeTime: 0,
		// Cookie domain name. Default is empty.
		Domain: "",
		// Session ID length. Default is 16.
		IDLength: 16,
		// Configuration section name. Default is "session".
		Section: "session",
	}))
	m.Use(macaron.Renderer(macaron.RenderOptions{
		// Directory to load templates. Default is "templates".
		Directory: "templates",
		// Extensions to parse template files from. Defaults are [".tmpl", ".html"].
		Extensions: []string{".tmpl", ".html"},
		// Funcs is a slice of FuncMaps to apply to the template upon compilation. Default is [].
		Funcs: []template.FuncMap{map[string]interface{}{
			"AppName": func() string {
				return "Macaron"
			},
			"AppVer": func() string {
				return "1.0.0"
			},
		}},
		// Delims sets the action delimiters to the specified strings. Defaults are ["{{", "}}"].
		Delims: macaron.Delims{"{{", "}}"},
		// Appends the given charset to the Content-Type header. Default is "UTF-8".
		Charset: "UTF-8",
		// Outputs human readable JSON. Default is false.
		IndentJSON: true,
		// Outputs human readable XML. Default is false.
		IndentXML: true,
		// Prefixes the JSON output with the given bytes. Default is no prefix.
		// PrefixJSON: []byte("macaron"),
		// Prefixes the XML output with the given bytes. Default is no prefix.
		// PrefixXML: []byte("macaron"),
		// Allows changing of output to XHTML instead of HTML. Default is "text/html".
		HTMLContentType: "text/html",
	}))
	m.Use(cache.Cacher(cache.Options{
		// Name of adapter. Default is "memory".
		Adapter: "memory",
		// Adapter configuration, it's corresponding to adapter.
		AdapterConfig: "",
		// GC interval time in seconds. Default is 60.
		Interval: 60,
		// Configuration section name. Default is "cache".
		Section: "cache",
	}))

	// setup handlers
	m.Get("/", myHandler)
	m.Get("/welcome", myOtherHandler)
	m.Get("/query", myQueryStringHandler) // /query?name=Some+Name
	m.Get("/json", myJsonHandler)
	m.Post("/contact/submit", binding.Bind(ContactForm{}), mySubmitHandler)
	m.Get("/session", mySessionHandler)
	m.Get("/set/cookie/:value", mySetCookieHandler)
	m.Get("/get/cookie", myGetCookieHandler)
	m.Get("/database", myDatabaseHandler)
	m.Get("/database/list", myDatabaseListHandler)
	m.Get("/cache/write/:key/:value", myCacheWriteHandler)
	m.Get("/cache/read/:key", myCacheReadHandler)

	log.Println("Server is running on localhost:4000...")
	log.Println(http.ListenAndServe("0.0.0.0:4000", m))
}
func main() {
	initParse()

	err := readConfig("service.conf", &c.Config)
	if err != nil {
		glog.V(1).Infof("Read Configure file fail:%#v", err)
		return
	}

	initDB(c.Config)

	m := macaron.Classic()
	macaron.Env = macaron.PROD
	m.Use(macaron.Renderer())
	m.Use(session.Sessioner(session.Options{
		Provider:       "redis",
		ProviderConfig: "addr=127.0.0.1:6379",
	}))

	m.Use(macaron.Static("public",
		macaron.StaticOptions{
			// 请求静态资源时的 URL 前缀,默认没有前缀
			Prefix: "public",
			// 禁止记录静态资源路由日志,默认为不禁止记录
			SkipLogging: true,
			// 当请求目录时的默认索引文件,默认为 "index.html"
			IndexFile: "index.html",
			// 用于返回自定义过期响应头,不能为不设置
			// https://developers.google.com/speed/docs/insights/LeverageBrowserCaching
			Expires: func() string {
				return time.Now().Add(24 * 60 * time.Minute).UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT")
			},
		}))

	m.Use(macaron.Renderer(macaron.RenderOptions{
		// 模板文件目录,默认为 "templates"
		Directory: "templates",
		// 模板文件后缀,默认为 [".tmpl", ".html"]
		Extensions: []string{".tmpl", ".html"},
		// 模板函数,默认为 []
		Funcs: []template.FuncMap{map[string]interface{}{
			"AppName": func() string {
				return "Macaron"
			},
			"AppVer": func() string {
				return "1.0.0"
			},
		}},
		// 模板语法分隔符,默认为 ["{{", "}}"]
		Delims: macaron.Delims{"{{", "}}"},
		// 追加的 Content-Type 头信息,默认为 "UTF-8"
		Charset: "UTF-8",
		// 渲染具有缩进格式的 JSON,默认为不缩进
		IndentJSON: true,
		// 渲染具有缩进格式的 XML,默认为不缩进
		IndentXML: true,
		// 渲染具有前缀的 JSON,默认为无前缀
		PrefixJSON: []byte(""),
		// 渲染具有前缀的 XML,默认为无前缀
		PrefixXML: []byte(""),
		// 允许输出格式为 XHTML 而不是 HTML,默认为 "text/html"
		HTMLContentType: "text/html",
	}))
	m.Map(x)
	m.SetDefaultCookieSecret("UYCNJSHA123JCN409")
	//	m.Post("/login",controller.Login)
	//	m.Get("/logout",controller.Logout)

	m.Group("/users", func() {
		m.Post("", binding.Bind(Customer{}), controller.PostCustomer)
		m.Get("", controller.GetCustomers)
	})

	m.Group("/goods", func() {
		m.Post("", binding.Bind(Goods{}), controller.PostGood)
		m.Get("", controller.GetGoods)
	})

	m.Group("/orders", func() {
		m.Post("/alipay", binding.Bind(Order{}), controller.PostOrder)
		m.Get("", controller.GetOrders)
	})

	m.Group("/alipay", func() {
		m.Post("/notify", controller.AlipayNotify)
		m.Get("/return", controller.AlipayReturn)
	})

	m.Run(8080)
}
Beispiel #25
0
func daemon(c *cobra.Command, a []string) {
	m := macaron.New()
	setting.NewContext(c)
	err := models.NewEngine()

	m.Use(middleware.Contexter())
	m.Use(macaron.Recovery())
	m.Use(macaron.Logger())
	m.Use(macaron.Renderer(
		macaron.RenderOptions{
			Directory: "templates",
			TemplateFileSystem: bindata.Templates(bindata.Options{
				Asset:      templates.Asset,
				AssetDir:   templates.AssetDir,
				AssetNames: templates.AssetNames,
				Prefix:     "",
			}),
		},
	))
	m.Use(macaron.Static("web/images",
		macaron.StaticOptions{
			Prefix: "images",
			FileSystem: bindata.Static(bindata.Options{
				Asset:      web.Asset,
				AssetDir:   web.AssetDir,
				AssetNames: web.AssetNames,
				Prefix:     "web/images",
			}),
		},
	))
	m.Use(macaron.Static("web/template",
		macaron.StaticOptions{
			Prefix: "template",
			FileSystem: bindata.Static(bindata.Options{
				Asset:      web.Asset,
				AssetDir:   web.AssetDir,
				AssetNames: web.AssetNames,
				Prefix:     "web/template",
			}),
		},
	))

	m.Use(macaron.Static("web",
		macaron.StaticOptions{
			FileSystem: bindata.Static(bindata.Options{
				Asset:      web.Asset,
				AssetDir:   web.AssetDir,
				AssetNames: web.AssetNames,
				Prefix:     "web",
			}),
			Prefix: viper.GetString("version"),
		},
	))

	m.Get("/assets/html/user/views/oauth.html", user.OauthHandler)
	m.Combo("/api/oauth").
		Get(user.OauthUrl).
		Post(binding.Json(auth.Oauth2{}), user.OauthLogin)

	m.Post("/api/login", binding.Json(auth.SignIn{}), user.SignIn)
	m.Post("/api/register", binding.Json(auth.SignUp{}), user.SignUp)
	m.Group("/api", func() {
		m.Get("/boards", board.ListBoards)
		m.Post("/boards/configure", binding.Json(models.BoardRequest{}), board.Configure)

		m.Get("/board", board.ItemBoard)
		m.Get("/labels", board.ListLabels)
		m.Get("/cards", board.ListCards)
		m.Get("/milestones", board.ListMilestones)
		m.Get("/users", board.ListMembers)
		m.Combo("/comments").
			Get(board.ListComments).
			Post(binding.Json(models.CommentRequest{}), board.CreateComment)

		m.Combo("/card").
			Post(binding.Json(models.CardRequest{}), board.CreateCard).
			Put(binding.Json(models.CardRequest{}), board.UpdateCard).
			Delete(binding.Json(models.CardRequest{}), board.DeleteCard)

		m.Put("/card/move", binding.Json(models.CardRequest{}), board.MoveToCard)

	}, middleware.Auther())
	m.Get("/*", routers.Home)
	m.Get("/ws/", sockets.Messages(), ws.ListenAndServe)

	listen := viper.GetString("server.listen")
	log.Printf("Listen: %s", listen)
	err = http.ListenAndServe(listen, m)

	if err != nil {
		log.Fatalf("Failed to start: %s", err)
	}
}
Beispiel #26
0
func runWeb(c *cli.Context) {
	if err := models.InitDb(); err != nil {
		log.Fatal("Fail to init DB: %v", err)
	}

	if c.IsSet("port") {
		setting.HTTPPort = c.Int("port")
	}

	bindIgnErr := binding.BindIgnErr

	m := macaron.New()
	m.Use(macaron.Logger())
	m.Use(macaron.Recovery())
	m.Use(macaron.Renderer(macaron.RenderOptions{
		IndentJSON: !setting.ProdMode,
	}))
	m.Use(web.Contexter())

	group := func() {
		m.Group("/flows", func() {
			m.Combo("").Get(web.Flows).
				Post(bindIgnErr(api.CreateFlowOptions{}), web.CreateFlow)
			m.Combo("/:uuid").Get(web.GetFlow).
				Post(bindIgnErr(api.CreateFlowOptions{}), web.UpdateFlow).
				Delete(web.DeleteFlow)
		})

		m.Group("/pipelines", func() {
			m.Combo("").Get(web.Pipelines).
				Post(bindIgnErr(api.CreatePipelineOptions{}), web.CreatePipeline)
			m.Combo("/:uuid").Get(web.GetPipeline).
				Post(bindIgnErr(api.CreatePipelineOptions{}), web.UpdatePipeline).
				Delete(web.DeletePipeline)
		})

		m.Group("/stages", func() {
			m.Combo("").Get(web.Stages).
				Post(bindIgnErr(api.CreateStageOptions{}), web.CreateStage)
			m.Combo("/:uuid").Get(web.GetStage).
				Post(bindIgnErr(api.CreateStageOptions{}), web.UpdateStage).
				Delete(web.DeleteStage)
		})

		m.Group("/jobs", func() {
			m.Combo("").Get(web.Jobs).
				Post(bindIgnErr(api.CreateJobOptions{}), web.CreateJob)
			m.Combo("/:uuid").Get(web.GetJob).
				Post(bindIgnErr(api.CreateJobOptions{}), web.UpdateJob).
				Delete(web.DeleteJob)
		})

		m.Post("/build", web.Build)
	}
	m.Group("", group)
	m.Group("/v1", group)

	listenAddr := fmt.Sprintf("0.0.0.0:%d", setting.HTTPPort)
	log.Info("Vessel %s %s", setting.AppVer, listenAddr)
	if err := http.ListenAndServe(listenAddr, m); err != nil {
		log.Fatal("Fail to start web server: %v", err)
	}
}
Beispiel #27
0
func init() {
	m.Use(macaron.Renderer(macaron.RenderOptions{
		Delims: macaron.Delims{"[[", "]]"},
	}))
}
Beispiel #28
0
// +build bindata

package modules

import (
	"github.com/Unknwon/macaron"
	"github.com/codeskyblue/file-server/public"
	"github.com/codeskyblue/file-server/templates"
	"github.com/macaron-contrib/bindata"
)

var Public = macaron.Static("public",
	macaron.StaticOptions{
		Prefix: "-",
		FileSystem: bindata.Static(bindata.Options{
			Asset:      public.Asset,
			AssetDir:   public.AssetDir,
			AssetNames: public.AssetNames,
			Prefix:     "",
		}),
	})

var Renderer = macaron.Renderer(macaron.RenderOptions{
	TemplateFileSystem: bindata.Templates(bindata.Options{
		Asset:      templates.Asset,
		AssetDir:   templates.AssetDir,
		AssetNames: templates.AssetNames,
		Prefix:     "",
	}),
})
Beispiel #29
0
func Test_Fibonacci(t *testing.T) {
	Convey("Test Fibonacci calculator", t, func() {
		// Setup dummy server.
		m := macaron.New()
		m.Use(macaron.Renderer())
		m.Use(middleware.Contexter())

		m.Get("/fibonacci", v1.Fibonacci)

		Convey("Invalid parameters", func() {
			Convey("Give a negative number", func() {
				resp := httptest.NewRecorder()
				req, err := http.NewRequest("GET", "/fibonacci?n=-1", nil)
				So(err, ShouldBeNil)
				m.ServeHTTP(resp, req)

				So(resp.Code, ShouldEqual, 422)
				So(resp.Body.String(), ShouldEqual, `{"error":"Unprocessable number: -1"}`)
			})

			Convey("Give a super large number", func() {
				resp := httptest.NewRecorder()
				req, err := http.NewRequest("GET", "/fibonacci?n=150", nil)
				So(err, ShouldBeNil)
				m.ServeHTTP(resp, req)

				So(resp.Code, ShouldEqual, 422)
				So(resp.Body.String(), ShouldEqual, `{"error":"Unprocessable number: 150"}`)
			})
		})

		Convey("Valid parameters", func() {
			// 0
			resp := httptest.NewRecorder()
			req, err := http.NewRequest("GET", "/fibonacci?n=0", nil)
			So(err, ShouldBeNil)
			m.ServeHTTP(resp, req)

			So(resp.Code, ShouldEqual, 200)
			So(resp.Body.String(), ShouldEqual, `{"sequence":[]}`)

			// 1
			resp = httptest.NewRecorder()
			req, err = http.NewRequest("GET", "/fibonacci?n=1", nil)
			So(err, ShouldBeNil)
			m.ServeHTTP(resp, req)

			So(resp.Code, ShouldEqual, 200)
			So(resp.Body.String(), ShouldEqual, `{"sequence":[0]}`)

			// 2
			resp = httptest.NewRecorder()
			req, err = http.NewRequest("GET", "/fibonacci?n=2", nil)
			So(err, ShouldBeNil)
			m.ServeHTTP(resp, req)

			So(resp.Code, ShouldEqual, 200)
			So(resp.Body.String(), ShouldEqual, `{"sequence":[0,1]}`)

			// 5
			resp = httptest.NewRecorder()
			req, err = http.NewRequest("GET", "/fibonacci?n=5", nil)
			So(err, ShouldBeNil)
			m.ServeHTTP(resp, req)

			So(resp.Code, ShouldEqual, 200)
			So(resp.Body.String(), ShouldEqual, `{"sequence":[0,1,1,2,3]}`)

			// 10
			resp = httptest.NewRecorder()
			req, err = http.NewRequest("GET", "/fibonacci?n=10", nil)
			So(err, ShouldBeNil)
			m.ServeHTTP(resp, req)

			So(resp.Code, ShouldEqual, 200)
			So(resp.Body.String(), ShouldEqual, `{"sequence":[0,1,1,2,3,5,8,13,21,34]}`)
		})
	})
}