func main() { pid := syscall.Getpid() flag.Parse() // create the pipeline pipeline := falcore.NewPipeline() pipeline.Upstream.PushBack(falcore.NewRequestFilter(Filter)) // create the server with the pipeline srv := falcore.NewServer(8090, pipeline) // if passed the socket file descriptor, setup the listener that way // if you don't have it, the default is to create the socket listener // with the data passed to falcore.NewServer above (happens in ListenAndServer()) if *socketFd != -1 { // I know I'm a child process if I get here so I can signal the parent when I'm ready to take over go childReady(srv) fmt.Printf("%v Got socket FD: %v\n", pid, *socketFd) srv.FdListen(*socketFd) } // using signals to manage the restart lifecycle go handleSignals(srv) // start the server // this is normally blocking forever unless you send lifecycle commands fmt.Printf("%v Starting Listener on 8090\n", pid) if err := srv.ListenAndServe(); err != nil { fmt.Printf("%v Could not start server: %v", pid, err) } fmt.Printf("%v Exiting now\n", pid) }
func main() { // parse command line options flag.Parse() // setup pipeline pipeline := falcore.NewPipeline() // upstream filters // Serve files pipeline.Upstream.PushBack(&filter.FileFilter{ BasePath: *path, DirectoryIndex: "index.html", // Serve index.html for root requests }) // downstream pipeline.Downstream.PushBack(filter.NewCompressionFilter(nil)) // setup server server := falcore.NewServer(*port, pipeline) // start the server // this is normally blocking forever unless you send lifecycle commands if err := server.ListenAndServe(); err != nil { fmt.Println("Could not start server:", err) } }
func init() { // Silence log output log.SetOutput(nil) // setup mime mime.AddExtensionType(".foo", "foo/bar") mime.AddExtensionType(".json", "application/json") mime.AddExtensionType(".txt", "text/plain") mime.AddExtensionType(".png", "image/png") mime.AddExtensionType(".html", "text/html") go func() { // falcore setup pipeline := falcore.NewPipeline() pipeline.Upstream.PushBack(&FileFilter{ PathPrefix: "/", BasePath: "../test/", DirectoryIndex: "index.html", }) srv = falcore.NewServer(0, pipeline) if err := srv.ListenAndServe(); err != nil { panic(fmt.Sprintf("Could not start falcore: %v", err)) } }() }
func main() { // parse command line options flag.Parse() // setup pipeline pipeline := falcore.NewPipeline() // upstream filters // Serve index.html for root requests pipeline.Upstream.PushBack(falcore.NewRequestFilter(func(req *falcore.Request) *http.Response { if req.HttpRequest.URL.Path == "/" { req.HttpRequest.URL.Path = "/index.html" } return nil })) // Serve files pipeline.Upstream.PushBack(&filter.FileFilter{ BasePath: *path, }) // downstream pipeline.Downstream.PushBack(filter.NewCompressionFilter(nil)) // setup server server := falcore.NewServer(*port, pipeline) // start the server // this is normally blocking forever unless you send lifecycle commands if err := server.ListenAndServe(); err != nil { fmt.Println("Could not start server:", err) } }
// TestPassthru verifies that a Falcore RequestFilter generated by // NewPassthruFilter will forward web traffic as expected. func TestPassthru(t *testing.T) { request, err := http.NewRequest("GET", "http://localhost", nil) assert.NoError(t, err) landingPipeline := falcore.NewPipeline() landingPipeline.Upstream.PushBack(pullcord.NewLandingFilter()) landingServer := falcore.NewServer(0, landingPipeline) regex, err := regexp.Compile("Pullcord Landing Page") assert.NoError(t, err) go serveLandingPage(landingServer) defer landingServer.StopAccepting() <-landingServer.AcceptReady _, response := falcore.TestWithRequest( request, NewPassthruFilter("localhost", landingServer.Port()), nil, ) assert.Equal(t, 200, response.StatusCode) contents, err := ioutil.ReadAll(response.Body) assert.NoError(t, err) assert.True(t, regex.Match(contents)) }
// init server and its filter pipeline func setupServer() *falcore.Server { pipeline := falcore.NewPipeline() var authentication filter.AuthenticationFilter var token filter.TokenFilter var devices filter.DevicesFilter var messages filter.MessagesFilter // var upload filter.UploadFilter var notFound filter.NotFoundFilter swaggerHeaders := new(filter.SwaggerHeadersFilter) // route based on request path router := router.NewPathRouter() router.AddMatch("^/tokens", token) router.AddMatch("^/devices", devices) router.AddMatch("^/messages", messages) //router.AddMatch("^/upload", upload) pipeline.Upstream.PushBack(authentication) // authentication is first in pipeline since it's mandatory pipeline.Upstream.PushBack(router) pipeline.Upstream.PushBack(notFound) // catch all filter is last, default response pipeline.Downstream.PushBack(swaggerHeaders) server := falcore.NewServer(*port, pipeline) // add request done callback stage //server.CompletionCallback = completionCallback setupServices() return server }
func init() { go func() { // falcore setup pipeline := falcore.NewPipeline() pipeline.Upstream.PushBack(falcore.NewRequestFilter(func(req *falcore.Request) *http.Response { for _, data := range eserverData { if data.path == req.HttpRequest.URL.Path { header := make(http.Header) header.Set("Etag", data.etag) if data.chunked { buf := new(bytes.Buffer) buf.Write(data.body) res := falcore.SimpleResponse(req.HttpRequest, data.status, header, -1, ioutil.NopCloser(buf)) res.TransferEncoding = []string{"chunked"} return res } else { return falcore.StringResponse(req.HttpRequest, data.status, header, string(data.body)) } } } return falcore.StringResponse(req.HttpRequest, 404, nil, "Not Found") })) pipeline.Downstream.PushBack(new(EtagFilter)) esrv = falcore.NewServer(0, pipeline) if err := esrv.ListenAndServe(); err != nil { panic("Could not start falcore") } }() }
func main() { runtime.GOMAXPROCS(runtime.NumCPU()) db, err := sql.Open("mysql", connectionString) if err != nil { log.Fatalf("Error opening database: %v", err) } db.SetMaxIdleConns(maxConnectionCount) worldStatement, err = db.Prepare(worldSelect) if err != nil { log.Fatal(err) } fortuneStatement, err = db.Prepare(fortuneSelect) if err != nil { log.Fatal(err) } updateStatement, err = db.Prepare(worldUpdate) if err != nil { log.Fatal(err) } pipeline := falcore.NewPipeline() pipeline.Upstream.PushBack(dbFilter) pipeline.Upstream.PushBack(queriesFilter) pipeline.Upstream.PushBack(jsonFilter) pipeline.Upstream.PushBack(fortuneFilter) pipeline.Upstream.PushBack(updateFilter) pipeline.Upstream.PushBack(plaintextFilter) pipeline.Downstream.PushBack(requiredHeaders) /* http.HandleFunc("/db", dbHandler) http.HandleFunc("/queries", queriesHandler) http.HandleFunc("/json", jsonHandler) http.HandleFunc("/fortune", fortuneHandler) http.HandleFunc("/update", updateHandler) http.HandleFunc("/plaintext", plaintextHandler) */ server := falcore.NewServer(8080, pipeline) // uncomment for printing internal peromance stats //server.CompletionCallback = CompletionCallback if err := server.ListenAndServe(); err != nil { log.Println("Could not start server:", err) } //if err := http.ListenAndServe(":8080", server); err != nil { // log.Println("Could not start server:", err) //} }
func TestUpstreamThrottle(t *testing.T) { // Start a test server sleepPipe := falcore.NewPipeline() sleepPipe.Upstream.PushBack(falcore.NewRequestFilter(func(req *falcore.Request) *http.Response { time.Sleep(time.Second) return falcore.StringResponse(req.HttpRequest, 200, nil, "OK") })) sleepSrv := falcore.NewServer(0, sleepPipe) go func() { sleepSrv.ListenAndServe() }() <-sleepSrv.AcceptReady // Build Upstream up := NewUpstream(NewUpstreamTransport("localhost", sleepSrv.Port(), 0, nil)) // pipe := falcore.NewPipeline() // pipe.Upstream.PushBack(up) resCh := make(chan *http.Response, 10) var i int64 = 1 for ; i < 12; i++ { start := time.Now() up.SetMaxConcurrent(i) for j := 0; j < 10; j++ { go func() { req, _ := http.NewRequest("GET", "/", nil) _, res := falcore.TestWithRequest(req, up, nil) resCh <- res // fmt.Println("OK") }() } for j := 0; j < 10; j++ { res := <-resCh if res.StatusCode != 200 { t.Fatalf("Error: %v", res) } } duration := time.Since(start) seconds := float64(duration) / float64(time.Second) goal := math.Ceil(10.0 / float64(i)) // fmt.Println(i, "Time:", seconds, "Goal:", goal) if seconds < goal { t.Errorf("%v: Too short: %v < %v", i, seconds, goal) } } }
func main() { // parse command line options flag.Parse() // create pipeline pipeline := falcore.NewPipeline() // setup file server for public directory if *flagPath != "" { // Serve files from public directory pipeline.Upstream.PushBack(&filter.FileFilter{ BasePath: *flagPath, DirectoryIndex: "index.html", }) } else { falcore.Warn("Path to public directory is missing") } // parse upstream list and create the upstream pool upStrings := regexp.MustCompile("[0-9]+").FindAllString(*flagUpstream, -1) ups := make([]*filter.UpstreamEntry, len(upStrings)) for i, s := range upStrings { port, _ := strconv.Atoi(s) ups[i] = &filter.UpstreamEntry{ Upstream: filter.NewUpstream(filter.NewUpstreamTransport("localhost", port, 0, nil)), Weight: 1, } } // create upstream pool and add to pipeline if len(ups) > 0 { pipeline.Upstream.PushBack(filter.NewUpstreamPool("railsdemo", ups)) } else { falcore.Warn("No upstream ports provided") } // add any downstream filters you might want such as etag support or compression // setup server server := falcore.NewServer(*flagPort, pipeline) // start the server // this is normally blocking forever unless you send lifecycle commands if err := server.ListenAndServe(); err != nil { fmt.Println("Could not start server:", err) } }
func TestUpstreamTimeout(t *testing.T) { // Start a test server sleepPipe := falcore.NewPipeline() sleepPipe.Upstream.PushBack(falcore.NewRequestFilter(func(req *falcore.Request) *http.Response { tt, _ := strconv.Atoi(req.HttpRequest.URL.Query().Get("time")) b, _ := strconv.Atoi(req.HttpRequest.URL.Query().Get("body")) bl, _ := strconv.Atoi(req.HttpRequest.URL.Query().Get("bl")) time.Sleep(time.Duration(tt)) pr, pw := io.Pipe() go func() { buf := make([]byte, 1024) for i := 0; i < bl; i++ { <-time.After(time.Duration(b)) pw.Write(buf) } pw.Close() }() return falcore.SimpleResponse(req.HttpRequest, 200, nil, int64(bl*1024), pr) })) sleepSrv := falcore.NewServer(0, sleepPipe) go func() { sleepSrv.ListenAndServe() }() <-sleepSrv.AcceptReady // Build Upstream up := NewUpstream(NewUpstreamTransport("localhost", sleepSrv.Port(), time.Second, nil)) for _, test := range upstreamTimeoutTestData { req, _ := http.NewRequest("GET", fmt.Sprintf("http://localhost/test?time=%v&body=%v&bl=%v", int64(test.Time), int64(test.BodyTime), test.BodyLen), nil) _, res := falcore.TestWithRequest(req, up, nil) if res.StatusCode != test.StatusCode { t.Errorf("%v Expected status %v Got %v", test.Name, test.StatusCode, res.StatusCode) } if res.StatusCode == 200 { i, _ := io.Copy(ioutil.Discard, res.Body) res.Body.Close() if i != (test.BodyLen * 1024) { t.Errorf("%v Expected body len %v Got %v", test.Name, (test.BodyLen * 1024), i) } } } }
// How to use Falcore properly with Defer Panic client library func main() { dps := deferstats.NewClient("z57z3xsEfpqxpr0dSte0auTBItWBYa1c") go dps.CaptureStats() // create pipeline pipeline := falcore.NewPipeline() // add upstream pipeline stages var filter helloFilter pipeline.Upstream.PushBack(filter) // create server on port 0 server := falcore.NewServer(0, pipeline) // start the server // this is normally blocking forever unless you send lifecycle commands http.ListenAndServe(":3000", middleware.Wrapper(dps, server)) }
func main() { // parse command line options flag.Parse() // setup pipeline pipeline := falcore.NewPipeline() // upstream pipeline.Upstream.PushBack(helloFilter) // setup server server := falcore.NewServer(*port, pipeline) // start the server // this is normally blocking forever unless you send lifecycle commands if err := server.ListenAndServe(); err != nil { fmt.Println("Could not start server:", err) } }
func main() { // create pipeline pipeline := falcore.NewPipeline() // add upstream pipeline stages var filter1 delayFilter pipeline.Upstream.PushBack(filter1) var filter2 helloFilter pipeline.Upstream.PushBack(filter2) // create server on port 8000 server := falcore.NewServer(8000, pipeline) // add request done callback stage server.CompletionCallback = reqCB // start the server // this is normally blocking forever unless you send lifecycle commands if err := server.ListenAndServe(); err != nil { fmt.Println("Could not start server:", err) } }
func init() { go func() { // falcore setup pipeline := falcore.NewPipeline() pipeline.Upstream.PushBack(falcore.NewRequestFilter(func(req *falcore.Request) *http.Response { for _, data := range eserverData { if data.path == req.HttpRequest.URL.Path { header := make(http.Header) header.Set("Etag", data.etag) return falcore.StringResponse(req.HttpRequest, data.status, header, string(data.body)) } } return falcore.StringResponse(req.HttpRequest, 404, nil, "Not Found") })) pipeline.Downstream.PushBack(new(EtagFilter)) esrv = falcore.NewServer(0, pipeline) if err := esrv.ListenAndServe(); err != nil { panic("Could not start falcore") } }() }
func TestUpstreamThrottle(t *testing.T) { // Build a thing for var started = make(chan chan bool, REQ_COUNT+1) // Start a test server sleepPipe := falcore.NewPipeline() sleepPipe.Upstream.PushBack(falcore.NewRequestFilter(func(req *falcore.Request) *http.Response { // get chan // j, _ := strconv.Atoi(req.HttpRequest.URL.Query().Get("j")) // fmt.Println(req.HttpRequest.URL, j) c := make(chan bool) started <- c // wait on chan <-c // fmt.Println("DONE") return falcore.StringResponse(req.HttpRequest, 200, nil, "OK") })) sleepSrv := falcore.NewServer(0, sleepPipe) defer sleepSrv.StopAccepting() go func() { sleepSrv.ListenAndServe() }() <-sleepSrv.AcceptReady // Build Upstream up := NewUpstream(NewUpstreamTransport("localhost", sleepSrv.Port(), 0, nil)) // pipe := falcore.NewPipeline() // pipe.Upstream.PushBack(up) resCh := make(chan *http.Response, REQ_COUNT) var i int64 = 1 for ; i < 12; i++ { // fmt.Println("Testing with limit", i) up.SetMaxConcurrent(i) for j := 0; j < REQ_COUNT; j++ { var jj = j go func() { // fmt.Println("STARTING") req, _ := http.NewRequest("GET", fmt.Sprintf("http://localhost/foo?j=%v", jj), nil) _, res := falcore.TestWithRequest(req, up, nil) res.Body.Close() resCh <- res // fmt.Println("OK") }() } for j := 0; j < REQ_COUNT; j++ { // make sure we haven't gone over the limit // fmt.Println(i, len(started)) if r := int64(len(started)); r > i { t.Errorf("%v: Over the limit: %v", i, r) } // send a finish signal (<-started) <- true // collect the result res := <-resCh if res.StatusCode != 200 { t.Fatalf("Error: %v", res) } } } }