func ExampleRoute() { code := ` ajaxRouteV3: PathRegexp(/^\/api\/v3\/.*/) -> ajaxHeader("v3") -> "https://api.example.org"` routes, err := eskip.Parse(code) if err != nil { log.Println(err) return } r := routes[0] fmt.Println("Parsed a route:") fmt.Printf("id: %v\n", r.Id) fmt.Printf("match regexp: %s\n", r.PathRegexps[0]) fmt.Printf("# of filters: %v\n", len(r.Filters)) fmt.Printf("is shunt: %v\n", r.Shunt) fmt.Printf("backend address: \"%v\"\n", r.Backend) // output: // Parsed a route: // id: ajaxRouteV3 // match regexp: ^/api/v3/.* // # of filters: 1 // is shunt: false // backend address: "https://api.example.org" }
func (r *inlineReader) LoadAndParseAll() ([]*eskip.RouteInfo, error) { routes, err := eskip.Parse(r.routes) if err != nil { return nil, err } return routesToRouteInfos(routes), nil }
// Converts a set of Innkeeper route definitions to their eskip representation. func convertJsonToEskip(data []*routeData, prependFilters, appendFilters []*eskip.Filter) ([]*eskip.Route, []string, string) { var ( routes []*eskip.Route deleted []string lastChanged string ) for _, d := range data { if d.Timestamp > lastChanged { lastChanged = d.Timestamp } if d.Action.Delete() { deleted = append(deleted, d.Name) } else { r, err := eskip.Parse(d.Eskip) if err == nil { for _, ri := range r { ri.Filters = append(prependFilters, append(ri.Filters, appendFilters...)...) } routes = append(routes, r...) } else { log.Error("error while parsing routes, innkeeper ", d.Name, err) } } } return routes, deleted, lastChanged }
func TestTeeEndToEndBody(t *testing.T) { shadowHandler := &MyHandler{name: "shadow"} shadowServer := httptest.NewServer(shadowHandler) shadowUrl := shadowServer.URL defer shadowServer.Close() originalHandler := &MyHandler{name: "original"} originalServer := httptest.NewServer(originalHandler) originalUrl := originalServer.URL defer originalServer.Close() routeStr := fmt.Sprintf(`route1: * -> tee("%v") -> "%v";`, shadowUrl, originalUrl) route, _ := eskip.Parse(routeStr) registry := make(filters.Registry) registry.Register(NewTee()) p := proxytest.New(registry, route...) defer p.Close() testingStr := "TESTEST" req, _ := http.NewRequest("GET", p.URL, strings.NewReader(testingStr)) req.Host = "www.example.org" req.Header.Set("X-Test", "true") req.Close = true rsp, _ := (&http.Client{}).Do(req) rsp.Body.Close() if shadowHandler.body != testingStr && originalHandler.body != testingStr { t.Error("Bodies are not equal") } }
// Creates a Client with an initial set of route definitions in eskip // format. If parsing the eskip document fails, returns an error. func NewDoc(doc string) (*Client, error) { routes, err := eskip.Parse(doc) if err != nil { return nil, err } return New(routes), nil }
// parse a routing doc and process it to runtime routes func docToRoutes(doc string) ([]*Route, error) { defs, err := eskip.Parse(doc) if err != nil { return nil, err } return processRouteDefs([]PredicateSpec{&truePredicate{}}, nil, defs), nil }
// Updates the current set of routes with new/modified and deleted // route definitions in eskip format. In case the parsing of the // document fails, it returns an error. func (c *Client) UpdateDoc(upsertDoc string, deletedIds []string) error { routes, err := eskip.Parse(upsertDoc) if err != nil { return err } c.Update(routes, deletedIds) return nil }
// Parses a single route expression, fails if more than one // expressions in the data. func parseOne(data string) (*eskip.Route, error) { r, err := eskip.Parse(data) if err != nil { return nil, err } if len(r) != 1 { return nil, errors.New("invalid route entry: multiple route expressions") } return r[0], nil }
// Opens an eskip file and parses it, returning a DataClient implementation. // If reading or parsing the file fails, returns an error. func Open(path string) (*Client, error) { content, err := ioutil.ReadFile(path) if err != nil { return nil, err } routes, err := eskip.Parse(string(content)) if err != nil { return nil, err } return &Client{routes}, nil }
// load and parse routes from a reader (used for stdin). func loadReader(r io.Reader) (loadResult, error) { // this pretty much disables continuous piping, // but since the reset command first upserts all // and deletes the diff only after, it may not // even be consistent to do continous piping. // May change in the future. doc, err := ioutil.ReadAll(r) if err != nil { return loadResult{}, err } routes, err := eskip.Parse(string(doc)) return loadResult{routes: routes}, err }
func ExampleParse() { code := ` PathRegexp(/\.html$/) && Header("Accept", "text/html") -> modPath(/\.html$/, ".jsx") -> requestHeader("X-Type", "page") -> "https://render.example.org"` routes, err := eskip.Parse(code) if err != nil { log.Println(err) return } fmt.Printf("Parsed route with backend: %s\n", routes[0].Backend) // output: Parsed route with backend: https://render.example.org }
func Example() { code := ` // Skipper - Eskip: // a routing table document, containing multiple route definitions // route definition to a jsx page renderer route0: PathRegexp(/\.html$/) && HeaderRegexp("Accept", "text/html") -> modPath(/\.html$/, ".jsx") -> requestHeader("X-Type", "page") -> "https://render.example.org"; route1: Path("/some/path") -> "https://backend-0.example.org"; // a simple route // route definition with a shunt (no backend address) route2: Path("/some/other/path") -> static("/", "/var/www") -> <shunt>; // route definition directing requests to an api endpoint route3: Method("POST") && Path("/api") -> requestHeader("X-Type", "ajax-post") -> "https://api.example.org" ` routes, err := eskip.Parse(code) if err != nil { log.Println(err) return } format := "%v: [match] -> [%v filter(s) ->] <%v> \"%v\"\n" fmt.Println("Parsed routes:") for _, r := range routes { fmt.Printf(format, r.Id, len(r.Filters), r.Shunt, r.Backend) } // output: // Parsed routes: // route0: [match] -> [2 filter(s) ->] <false> "https://render.example.org" // route1: [match] -> [0 filter(s) ->] <false> "https://backend-0.example.org" // route2: [match] -> [1 filter(s) ->] <true> "" // route3: [match] -> [1 filter(s) ->] <false> "https://api.example.org" }
func (r *stdinReader) LoadAndParseAll() ([]*eskip.RouteInfo, error) { // this pretty much disables continuous piping, // but since the reset command first upserts all // and deletes the diff only after, it may not // even be consistent to do continous piping. // May change in the future. doc, err := ioutil.ReadAll(r.reader) if err != nil { return nil, err } routes, err := eskip.Parse(string(doc)) if err != nil { return nil, err } return routesToRouteInfos(routes), nil }
func ExampleFilter() { code := ` Method("GET") -> helloFilter("Hello, world!", 3.14) -> "https://backend.example.org"` routes, err := eskip.Parse(code) if err != nil { log.Println(err) return } f := routes[0].Filters[0] fmt.Println("Parsed a route with a filter:") fmt.Printf("filter name: %v\n", f.Name) fmt.Printf("filter arg 0: %v\n", f.Args[0].(string)) fmt.Printf("filter arg 1: %v\n", f.Args[1].(float64)) // output: // Parsed a route with a filter: // filter name: helloFilter // filter arg 0: Hello, world! // filter arg 1: 3.14 }
// parse routes from a string. func loadString(doc string) (loadResult, error) { routes, err := eskip.Parse(doc) return loadResult{routes: routes}, err }