Esempio n. 1
0
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)
}
Esempio n. 2
0
// NewLandingFilter generates a Falcore RequestFilter that produces a simple
// landing page.
func NewLandingFilter() falcore.RequestFilter {
	log().Debug("registering a new landing filter")

	return falcore.NewRequestFilter(
		func(req *falcore.Request) *http.Response {
			log().Info("running landing filter")

			return falcore.StringResponse(
				req.HttpRequest,
				200,
				nil,
				"<html><head><title>"+
					"Pullcord Landing Page"+
					"</title></head><body><h1>"+
					"Pullcord Landing Page"+
					"</h1><p>"+
					"This is the landing page for Pullcord, "+
					"a reverse proxy for cloud-based web apps "+
					"that allows the servers the web apps run on "+
					"to be turned off when not in use."+
					"</p><p>"+
					"If you are unsure of how to proceed, "+
					"please contact the site administrator."+
					"</p></body></html>",
			)
		},
	)
}
Esempio n. 3
0
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)
	}
}
Esempio n. 4
0
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")
		}
	}()
}
Esempio n. 5
0
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)
		}
	}

}
Esempio n. 6
0
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)
			}
		}
	}
}
Esempio n. 7
0
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")
		}
	}()
}
Esempio n. 8
0
func validGetRequest() (req *falcore.Request) {
	tmp, _ := http.NewRequest("GET", "/hello", bytes.NewBuffer(make([]byte, 0)))
	req, _ = falcore.TestWithRequest(tmp, falcore.NewRequestFilter(func(req *falcore.Request) *http.Response { return nil }), nil)
	return
}
Esempio n. 9
0
func TestPassthruLoginPage(t *testing.T) {
	/* setup */
	testUser := "******"
	testPassword := "******"

	downstreamFilter := falcore.NewRequestFilter(
		func(request *falcore.Request) *http.Response {
			return falcore.StringResponse(
				request.HttpRequest,
				200,
				nil,
				"<html><body><p>logged in</p></body></html>",
			)
		},
	)
	sessionHandler := NewMinSessionHandler(
		"testSessionHandler",
		"/",
		"example.com",
	)
	hash, err := GetPbkdf2Hash(testPassword, Pbkdf2MinIterations)
	assert.NoError(t, err)
	passwordChecker := InMemPwdStore{
		map[string]*Pbkdf2Hash{
			testUser: hash,
		},
	}

	request1, err := http.NewRequest("GET", "/", nil)
	assert.NoError(t, err)

	/* run */
	handler := &LoginHandler{
		"testLoginHandler",
		&passwordChecker,
		downstreamFilter,
	}
	filter := &CookiemaskFilter{
		sessionHandler,
		handler,
		falcore.NewRequestFilter(
			func(request *falcore.Request) *http.Response {
				return internalServerError(request)
			},
		),
	}

	_, response1 := falcore.TestWithRequest(request1, filter, nil)
	assert.Equal(t, 200, response1.StatusCode)
	assert.NotEmpty(t, response1.Header["Set-Cookie"])

	content1, err := ioutil.ReadAll(response1.Body)
	assert.NoError(t, err)
	htmlRoot, err := html.Parse(bytes.NewReader(content1))
	assert.NoError(t, err)
	xsrfToken, err := getXsrfToken(htmlRoot, "xsrf-"+handler.Identifier)
	assert.NoError(t, err)

	postdata2 := url.Values{}
	postdata2.Add("xsrf-"+handler.Identifier, xsrfToken)
	postdata2.Add("username-"+handler.Identifier, testUser)
	postdata2.Add("password-"+handler.Identifier, testPassword)

	request2, err := http.NewRequest(
		"POST",
		"/",
		strings.NewReader(postdata2.Encode()),
	)
	request2.Header.Set(
		"Content-Type",
		"application/x-www-form-urlencoded",
	)
	assert.NoError(t, err)

	for _, cke := range response1.Cookies() {
		request2.AddCookie(cke)
	}

	_, response2 := falcore.TestWithRequest(request2, filter, nil)

	assert.Equal(t, 200, response2.StatusCode)

	content2, err := ioutil.ReadAll(response2.Body)
	assert.NoError(t, err)
	assert.True(
		t,
		strings.Contains(string(content2), "logged in"),
		"content is: "+string(content2),
	)

	request3, err := http.NewRequest("GET", "/", nil)
	assert.NoError(t, err)
	for _, cke := range response1.Cookies() {
		request3.AddCookie(cke)
	}

	_, response3 := falcore.TestWithRequest(request3, filter, nil)

	/* check */
	assert.Equal(t, 200, response3.StatusCode)

	content3, err := ioutil.ReadAll(response3.Body)
	assert.NoError(t, err)
	assert.True(
		t,
		strings.Contains(string(content3), "logged in"),
		"content is: "+string(content3),
	)
}
Esempio n. 10
0
func TestInitialLoginPage(t *testing.T) {
	/* setup */
	testUser := "******"
	testPassword := "******"

	downstreamFilter := falcore.NewRequestFilter(
		func(request *falcore.Request) *http.Response {
			return falcore.StringResponse(
				request.HttpRequest,
				200,
				nil,
				"<html><body><p>logged in</p></body></html>",
			)
		},
	)
	sessionHandler := NewMinSessionHandler(
		"testSessionHandler",
		"/",
		"example.com",
	)
	hash, err := GetPbkdf2Hash(testPassword, Pbkdf2MinIterations)
	assert.NoError(t, err)
	passwordChecker := InMemPwdStore{
		map[string]*Pbkdf2Hash{
			testUser: hash,
		},
	}

	request, err := http.NewRequest("GET", "/", nil)
	assert.NoError(t, err)

	/* run */
	handler := &LoginHandler{
		"testLoginHandler",
		&passwordChecker,
		downstreamFilter,
	}
	filter := &CookiemaskFilter{
		sessionHandler,
		handler,
		falcore.NewRequestFilter(
			func(request *falcore.Request) *http.Response {
				return internalServerError(request)
			},
		),
	}
	_, response := falcore.TestWithRequest(request, filter, nil)

	/* check */
	assert.Equal(t, 200, response.StatusCode)

	content, err := ioutil.ReadAll(response.Body)
	assert.NoError(t, err)
	assert.True(
		t,
		strings.Contains(string(content), "xsrf-testLoginHandler"),
		"content is: "+string(content),
	)
	assert.False(
		t,
		strings.Contains(string(content), "error"),
		"content is: "+string(content),
	)

	assert.NotEmpty(t, response.Header["Set-Cookie"])
}
Esempio n. 11
0
}

var requiredHeaders = falcore.NewResponseFilter(func(req *falcore.Request, res *http.Response) {
	res.Header.Set("Server", "falcore")
	res.Header.Set("Date", time.Now().Format(time.RFC1123))
})

var applicationJson = http.Header{"Content-Type": []string{"application/json"}}
var textPlain = http.Header{"Content-Type": []string{"text/plain"}}
var textHtml = http.Header{"Content-Type": []string{"text/html"}}

// Test 1: JSON serialization
var jsonFilter = falcore.NewRequestFilter(func(req *falcore.Request) *http.Response {
	if req.HttpRequest.URL.Path == "/json" {
		resp, _ := responder.JSONResponse(req.HttpRequest, 200, applicationJson, &Message{helloWorldString})
		return resp
	}
	return nil
})

// Test 2: Single database query
var dbFilter = falcore.NewRequestFilter(func(req *falcore.Request) *http.Response {
	if req.HttpRequest.URL.Path == "/db" {
		var world World
		err := worldStatement.QueryRow(rand.Intn(worldRowCount)+1).Scan(&world.Id, &world.RandomNumber)
		if err != nil {
			log.Fatalf("Error scanning world row: %s", err.Error())
		}

		resp, _ := responder.JSONResponse(req.HttpRequest, 200, applicationJson, &world)
		return resp
Esempio n. 12
0
)

// Command line options
var (
	port = flag.Int("port", 8000, "the port to listen on")
)

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)
	}
}

var helloFilter = falcore.NewRequestFilter(func(req *falcore.Request) *http.Response {
	return falcore.StringResponse(req.HttpRequest, 200, nil, "hello world!")
})
Esempio n. 13
0
}

var cookieMaskTestPage = falcore.NewRequestFilter(
	func(req *falcore.Request) *http.Response {
		var content = "<html><body><h1>cookies</h1><ul>"
		for _, cke := range req.HttpRequest.Cookies() {
			content +=
				"<li class=\"cke\">" +
					cke.String() +
					"</li>"
		}
		content += "</ul><h1>context</h1><ul>"
		sesh := req.Context["session"].(*MinSession)
		for key, val := range sesh.GetValues() {
			content +=
				"<li class=\"sesh\">" +
					key +
					": " +
					gostring(val) +
					"</li>"
		}
		content += "</ul></body></html>"
		return falcore.StringResponse(
			req.HttpRequest,
			200,
			nil,
			content,
		)
	},
)

var errorPage = falcore.NewRequestFilter(
Esempio n. 14
0
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)
			}
		}
	}

}