func fsMapHandler() types.RequestHandler { var fileHandler = http.FileServer(httpfs.New(mapfs.New(fsmap))) return types.RequestHandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { fileHandler.ServeHTTP(w, r) }) }
func testStringHandler(t *testing.T, txt string) types.RequestHandler { return types.RequestHandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { var values = w.Header()[http.CanonicalHeaderKey("via")] if values[len(values)-1] != txt { t.Errorf("wrong value for via") } }) }
func newLocationWithHandler(name string) *types.Location { return &types.Location{ Name: name, Handler: types.RequestHandlerFunc(func(ctx context.Context, rw http.ResponseWriter, req *http.Request) { rw.WriteHeader(http.StatusOK) if _, err := rw.Write([]byte(name)); err != nil { panic(err) } }), } }
// New creates and returns a ready to used ServerStatusHandler. func New(cfg *config.Handler, l *types.Location, next types.RequestHandler) (types.RequestHandler, error) { return types.RequestHandlerFunc( func(ctx context.Context, w http.ResponseWriter, r *http.Request) { var start, err = strconv.Atoi(r.URL.Query().Get(startKey)) if err != nil || 0 >= start { // pass next.RequestHandle(ctx, w, r) return } r.URL.Query().Del(startKey) // clean that r.Header.Add("Range", fmt.Sprintf("bytes=%d-", start)) next.RequestHandle(ctx, &flvWriter{w: w}, r) }), nil }
// New creates and returns a ready to used ServerStatusHandler. func New(cfg *config.Handler, l *types.Location, next types.RequestHandler) (types.RequestHandler, error) { var s struct { Root string `json:"root"` } if err := json.Unmarshal(cfg.Settings, &s); err != nil { return nil, fmt.Errorf("dir handler: error while parsing settings - %s", err) } fs := http.FileServer(http.Dir(s.Root)) return types.RequestHandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { fs.ServeHTTP(w, r) }), nil }
// New creates and returns a ready to used ServerStatusHandler. func New(cfg *config.Handler, l *types.Location, next types.RequestHandler) (types.RequestHandler, error) { var s = defaultSettings if err := json.Unmarshal(cfg.Settings, &s); err != nil { return nil, fmt.Errorf("error while parsing settings for handler.pprof - %s", err) } var mux = http.NewServeMux() mux.HandleFunc(s.Path, pprof.Index) for prefix, handler := range prefixToHandler { mux.HandleFunc(path.Join(s.Path, prefix), handler) } return types.RequestHandlerFunc(func(ctx context.Context, w http.ResponseWriter, req *http.Request) { mux.ServeHTTP(w, req) }), nil }
// New creates and returns a ready to used ServerStatusHandler. func New(cfg *config.Handler, l *types.Location, next types.RequestHandler) (types.RequestHandler, error) { var s struct { Speed types.BytesSize `json:"speed"` } if err := json.Unmarshal(cfg.Settings, &s); err != nil { return nil, fmt.Errorf("handler.throttle got error while parsing settings - %s", err) } if s.Speed == 0 { return nil, fmt.Errorf("handler.throttle needs to have speed settings > 0") } return types.RequestHandlerFunc( func(ctx context.Context, w http.ResponseWriter, r *http.Request) { next.RequestHandle(ctx, &throttledResponseWriter{ResponseWriter: w, ThrottlerWriter: iocontrol.ThrottledWriter(w, int(s.Speed.Bytes()), time.Millisecond*10), }, r) }), nil }
// loggingHandler will write to accessLog each and every request to it while proxing it to next func loggingHandler(next types.RequestHandler, accessLog io.Writer, locationIdentification string) (types.RequestHandler, error) { if next == nil { return nil, types.NilNextHandler("accessLog") } if accessLog == nil { return next, nil } return types.RequestHandlerFunc( func(ctx context.Context, w http.ResponseWriter, r *http.Request) { t := time.Now() l := &responseLogger{ResponseWriter: w} url := *r.URL defer func() { go func() { writeLog(accessLog, r, locationIdentification, url, t, l.Status(), l.Size()) }() }() next.RequestHandle(ctx, l, r) }), nil }
func TestRemoveFromRequest(t *testing.T) { t.Parallel() var expectedHeaders = map[string][]string{ "Via": nil, "Added": {"old value", "added value"}, "Setting": {"this", "header"}, } v, err := New(config.NewHandler("headers", json.RawMessage(`{ "request": { "remove_headers": ["vIa"], "add_headers": { "added": "added value" }, "set_headers": { "setting": ["this", "header"] } } }`)), nil, types.RequestHandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { for key, expected := range expectedHeaders { got := r.Header[http.CanonicalHeaderKey(key)] if !reflect.DeepEqual(got, expected) { t.Errorf("for header '%s' expected '%+v', got '%+v'", key, got, expected) } } })) if err != nil { t.Errorf("Got error when initializing via - %s", err) } recorder := httptest.NewRecorder() req, err := http.NewRequest("get", "/to/test", nil) if err != nil { t.Fatal(err) } req.Header.Add(http.CanonicalHeaderKey("via"), "this should be removed") req.Header.Add(http.CanonicalHeaderKey("added"), "old value") req.Header.Add(http.CanonicalHeaderKey("setting"), "this should be resetted") v.RequestHandle(nil, recorder, req) }
func addHeaderHandler(t *testing.T, header string, value string) types.RequestHandler { return types.RequestHandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { w.Header().Add(header, value) w.WriteHeader(200) // this is actually needed }) }
func handlerCode(code int) types.RequestHandler { return types.RequestHandlerFunc(func(_ context.Context, w http.ResponseWriter, _ *http.Request) { w.WriteHeader(code) }) }
func TestLocationMatching(t *testing.T) { t.Parallel() muxer, err := NewLocationMuxer( []*types.Location{ newLocationWithHandler(exactStat), newLocationWithHandler(status), newLocationWithHandler(picturesWithoutRegex), newLocationWithHandler(specialJpG), newLocationWithHandler(jpgs), }, ) if err != nil { t.Fatal("Error while creating test LocationMuxer", err) } app := &Application{ notConfiguredHandler: newNotConfiguredHandler(), virtualHosts: map[string]*VirtualHost{ "localhost": { Location: types.Location{ Name: "localhost", Handler: types.RequestHandlerFunc(func(ctx context.Context, rw http.ResponseWriter, req *http.Request) { if req.Host != "localhost" { t.Fatalf("VirtualHost handler got requst for %s.", req.Host) } rw.WriteHeader(200) if _, err := rw.Write([]byte(notLocation)); err != nil { t.Fatalf("Unexpected Write error: %s", err) } }), }, Muxer: muxer, }, "localhost2": { Location: types.Location{ Name: "localhost2", }, Muxer: muxer, }, }, stats: new(applicationStats), } var mat = map[string]string{ "http://localhost/notinlocaitons": notLocation, "http://localhost/statu": notLocation, "http://localhost/stat/": notLocation, "http://localhost/stat": exactStat, "http://localhost/status/": status, "http://localhost/status/somewhereElse": status, "http://localhost/test.jpg": jpgs, "http://localhost/test.jpG": specialJpG, "http://localhost/pictures/test.jpg": picturesWithoutRegex, "http://localhost/pictures/test.jpG": picturesWithoutRegex, "http://localhost/Pictures/Terst.jpG": picturesWithoutRegex, // not in virtualhosts "http://localhost.com/pictures/test.jpG": notFound, // localhost2 "http://localhost2/notinlocaitons": notFound, "http://localhost2/statu": notFound, "http://localhost2/stat/": notFound, "http://localhost2/stat": exactStat, "http://localhost2/status/": status, "http://localhost2/status/somewhereElse": status, "http://localhost2/test.jpg": jpgs, "http://localhost2/test.jpG": specialJpG, "http://localhost2/pictures/test.jpg": picturesWithoutRegex, "http://localhost2/pictures/test.jpG": picturesWithoutRegex, "http://localhost2/Pictures/Terst.jpG": picturesWithoutRegex, } recorder := httptest.NewRecorder() for url, expected := range mat { recorder.Body.Reset() req, err := http.NewRequest("GET", url, nil) if err != nil { t.Fatalf("Error while creating request - %s", err) } app.ServeHTTP(recorder, req) got := recorder.Body.String() if got != expected { t.Errorf("Expected %s got %s in the body for url %s", expected, got, url) } } var stats = app.Stats() var expectedRequests, expectedResponded, expectedNotConfigured uint64 = 23, 19, 4 if stats.Requests != expectedRequests { t.Errorf("expected requests are %d but got %d", expectedRequests, stats.Requests) } if stats.Responded != expectedResponded { t.Errorf("expected responded requsts are %d but got %d", expectedResponded, stats.Responded) } if stats.NotConfigured != expectedNotConfigured { t.Errorf("expected non configured requests are %d but got %d", expectedNotConfigured, stats.NotConfigured) } }
func newNotConfiguredHandler() types.RequestHandler { return types.RequestHandlerFunc(func(_ context.Context, w http.ResponseWriter, r *http.Request) { http.NotFound(w, r) }) }