예제 #1
0
func (u *Upstream) FilterRequest(request *falcore.Request) (res *http.Response) {
	var err error
	req := request.HttpRequest

	// Force the upstream to use http
	if u.ForceHttp || req.URL.Scheme == "" {
		req.URL.Scheme = "http"
		req.URL.Host = req.Host
	}
	before := time.Now()
	req.Header.Set("Connection", "Keep-Alive")
	if u.tcpconn != nil {
		u.tcpconn.SetDeadline(time.Now().Add(u.Timeout))
	}
	res, err = u.transport.RoundTrip(req)
	diff := falcore.TimeDiff(before, time.Now())
	if err != nil {
		if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
			falcore.Error("%s Upstream Timeout error: %v", request.ID, err)
			res = falcore.SimpleResponse(req, 504, nil, "Gateway Timeout\n")
			request.CurrentStage.Status = 2 // Fail
		} else {
			falcore.Error("%s Upstream error: %v", request.ID, err)
			res = falcore.SimpleResponse(req, 502, nil, "Bad Gateway\n")
			request.CurrentStage.Status = 2 // Fail
		}
	}
	falcore.Debug("%s [%s] [%s] %s s=%d Time=%.4f", request.ID, req.Method, u.host, req.URL, res.StatusCode, diff)
	return
}
예제 #2
0
func (f *Filter) FilterRequest(req *falcore.Request) (res *http.Response) {
	// Clean asset path
	asset_path := filepath.Clean(filepath.FromSlash(req.HttpRequest.URL.Path))

	// Resolve PathPrefix
	if strings.HasPrefix(asset_path, f.PathPrefix) {
		asset_path = asset_path[len(f.PathPrefix):]
	} else {
		falcore.Debug("%v doesn't match prefix %v", asset_path, f.PathPrefix)
		res = falcore.SimpleResponse(req.HttpRequest, 404, nil, "Not found.")
		return
	}

	// Resolve FSBase
	if f.BasePath != "" {
		asset_path = filepath.Join(f.BasePath, asset_path)
	} else {
		falcore.Error("file_filter requires a BasePath")
		return falcore.SimpleResponse(req.HttpRequest, 500, nil, "Server Error\n")
	}

	// Open File
	if file, err := os.Open(asset_path); err == nil {
		// Make sure it's an actual file
		if stat, err := file.Stat(); err == nil && stat.Mode()&os.ModeType == 0 {
			res = &http.Response{
				Request:       req.HttpRequest,
				StatusCode:    200,
				Proto:         "HTTP/1.1",
				ProtoMajor:    1,
				ProtoMinor:    1,
				Body:          file,
				Header:        make(http.Header),
				ContentLength: stat.Size(),
			}
			if ct := mime.TypeByExtension(filepath.Ext(asset_path)); ct != "" {
				res.Header.Set("Content-Type", ct)
			}
		} else {
			file.Close()
			return falcore.SimpleResponse(req.HttpRequest, 404, nil, "File not found\n")
		}
	} else {
		falcore.Debug("Can't open %v: %v", asset_path, err)
		res = falcore.SimpleResponse(req.HttpRequest, 404, nil, "File not found\n")
	}
	return
}
예제 #3
0
func init() {
	go func() {
		// falcore setup
		pipeline := falcore.NewPipeline()
		pipeline.Upstream.PushBack(falcore.NewRequestFilter(func(req *falcore.Request) *http.Response {
			for _, data := range serverData {
				if data.path == req.HttpRequest.URL.Path {
					header := make(http.Header)
					header.Set("Etag", data.etag)
					return falcore.SimpleResponse(req.HttpRequest, data.status, header, string(data.body))
				}
			}
			return falcore.SimpleResponse(req.HttpRequest, 404, nil, "Not Found")
		}))

		pipeline.Downstream.PushBack(new(Filter))

		srv = falcore.NewServer(0, pipeline)
		if err := srv.ListenAndServe(); err != nil {
			panic("Could not start falcore")
		}
	}()
}
예제 #4
0
func main() {

	port := 8080

	pipeline := falcore.NewPipeline()

	pipeline.Upstream.PushBack(
		falcore.NewRequestFilter(
			func(req *falcore.Request) *http.Response {
				return falcore.SimpleResponse(
					req.HttpRequest,
					200,
					nil,
					"Hello, World!")
			}))

	server := falcore.NewServer(port, pipeline)

	if err := server.ListenAndServe(); err != nil {
		fmt.Println("Could not start server:" + err.Error())
	}

}
예제 #5
0
func (u *Upstream) FilterRequest(request *falcore.Request) (res *http.Response) {
	var err error
	req := request.HttpRequest

	// Force the upstream to use http
	if u.ForceHttp || req.URL.Scheme == "" {
		req.URL.Scheme = "http"
		req.URL.Host = req.Host
	}
	before := time.Now()
	req.Header.Set("Connection", "Keep-Alive")
	if u.tcpconn != nil {
		u.tcpconn.SetDeadline(time.Now().Add(u.Timeout))
	}
	var upstrRes *http.Response
	upstrRes, err = u.transport.RoundTrip(req)
	diff := falcore.TimeDiff(before, time.Now())
	if err == nil {
		// Copy response over to new record.  Remove connection noise.  Add some sanity.
		res = falcore.SimpleResponse(req, upstrRes.StatusCode, nil, "")
		if upstrRes.ContentLength > 0 && upstrRes.Body != nil {
			res.ContentLength = upstrRes.ContentLength
			res.Body = upstrRes.Body
		} else if upstrRes.ContentLength == 0 && upstrRes.Body != nil {
			// Any bytes?
			var testBuf [1]byte
			n, _ := io.ReadFull(upstrRes.Body, testBuf[:])
			if n == 1 {
				// Yes there are.  Chunked it is.
				res.TransferEncoding = []string{"chunked"}
				res.ContentLength = -1
				rc := &passThruReadCloser{
					io.MultiReader(bytes.NewBuffer(testBuf[:]), upstrRes.Body),
					upstrRes.Body,
				}

				res.Body = rc
			}
		} else if upstrRes.Body != nil {
			res.Body = upstrRes.Body
			res.ContentLength = -1
			res.TransferEncoding = []string{"chunked"}
		}
		// Copy over headers with a few exceptions
		res.Header = make(http.Header)
		for hn, hv := range upstrRes.Header {
			switch hn {
			case "Content-Length":
			case "Connection":
			case "Transfer-Encoding":
			default:
				res.Header[hn] = hv
			}
		}
	} else {
		if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
			falcore.Error("%s Upstream Timeout error: %v", request.ID, err)
			res = falcore.SimpleResponse(req, 504, nil, "Gateway Timeout\n")
			request.CurrentStage.Status = 2 // Fail
		} else {
			falcore.Error("%s Upstream error: %v", request.ID, err)
			res = falcore.SimpleResponse(req, 502, nil, "Bad Gateway\n")
			request.CurrentStage.Status = 2 // Fail
		}
	}
	falcore.Debug("%s [%s] [%s] %s s=%d Time=%.4f", request.ID, req.Method, u.host, req.URL, res.StatusCode, diff)
	return
}
예제 #6
0
func (f *Filter) FilterRequest(req *falcore.Request) (res *http.Response) {
	// Clean asset path
	asset_path := filepath.Clean(filepath.FromSlash(req.HttpRequest.URL.Path))

	if filepath.Ext(asset_path) != ".css" {
		return
	}

	// Resolve PathPrefix
	if strings.HasPrefix(asset_path, f.PathPrefix) {
		asset_path = asset_path[len(f.PathPrefix):]
	} else {
		falcore.Debug("%v doesn't match prefix %v", asset_path, f.PathPrefix)
		res = falcore.SimpleResponse(req.HttpRequest, 404, nil, "Not found.")
		return
	}

	// Resolve FSBase
	if f.BasePath != "" {
		asset_path = filepath.Join(f.BasePath, asset_path)
	} else {
		falcore.Error("file_filter requires a BasePath")
		return falcore.SimpleResponse(req.HttpRequest, 500, nil, "Server Error\n")
	}

	scss_asset_path := strings.Replace(asset_path, ".css", ".scss", -1)
	sass_asset_path := strings.Replace(asset_path, ".css", ".sass", -1)
	if _, err := os.Stat(scss_asset_path); err == nil {
		asset_path = scss_asset_path
	} else if _, err := os.Stat(sass_asset_path); err == nil {
		asset_path = sass_asset_path
	} else {
		return
	}

	if file, err := os.Open(asset_path); err == nil {
		// Make sure it's an actual file
		if stat, err := file.Stat(); err == nil && stat.Mode()&os.ModeType == 0 {
			cmd := exec.Command("sass", "--scss", asset_path)
			var out bytes.Buffer
			cmd.Stdout = &out
			err = cmd.Run()
			if err != nil {
				falcore.Error("Can't compile SCSS file : %v", asset_path)
				return
			}
			css := out.String()

			res = &http.Response{
				Request:       req.HttpRequest,
				StatusCode:    200,
				Proto:         "HTTP/1.1",
				ProtoMajor:    1,
				ProtoMinor:    1,
				Body:          ioutil.NopCloser(bytes.NewBufferString(css)),
				Header:        make(http.Header),
				ContentLength: int64(len(css)),
			}

			res.Header.Set("Content-Type", mime.TypeByExtension(".css"))

			// css, err := sc.CompileFile(asset_path)
			// if err != nil {
			// 	falcore.Error("%v", err)
			// 	return
			// }

			// res = &http.Response{
			// 	Request:       req.HttpRequest,
			// 	StatusCode:    200,
			// 	Proto:         "HTTP/1.1",
			// 	ProtoMajor:    1,
			// 	ProtoMinor:    1,
			// 	Body:          ioutil.NopCloser(bytes.NewBufferString(css)),
			// 	Header:        make(http.Header),
			// 	ContentLength: int64(len(css)),
			// }

			// res.Header.Set("Content-Type", mime.TypeByExtension(".css"))

		} else {
			file.Close()
		}
	} else {
		falcore.Finest("Can't open %v: %v", asset_path, err)
	}

	return
}
예제 #7
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.SimpleResponse(req.HttpRequest, 200, nil, "hello world!")
})
예제 #8
0
// very simple request filter
func Filter(request *falcore.Request) *http.Response {
	return falcore.SimpleResponse(request.HttpRequest, 200, nil, "OK\n")
}
예제 #9
0
func (f helloFilter) FilterRequest(req *falcore.Request) *http.Response {
	return falcore.SimpleResponse(req.HttpRequest, 200, nil, "hello world!\n")
}