func ExampleAddChain() {
	c := xhandler.Chain{}

	close := xhandler.CloseHandler
	cors := cors.Default().Handler
	timeout := xhandler.TimeoutHandler(2 * time.Second)
	auth := func(next xhandler.HandlerC) xhandler.HandlerC {
		return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			if v := ctx.Value("Authorization"); v == nil {
				http.Error(w, "Not authorized", http.StatusUnauthorized)
				return
			}
			next.ServeHTTPC(ctx, w, r)
		})
	}

	c.Add(close, cors, timeout)

	mux := http.NewServeMux()

	// Use c.Handler to terminate the chain with your final handler
	mux.Handle("/", c.Handler(xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		fmt.Fprintf(w, "Welcome to the home page!")
	})))

	// Create a new chain from an existing one, and add route-specific middleware to it
	protected := c.With(auth)

	mux.Handle("/admin", protected.Handler(xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
		fmt.Fprintf(w, "protected endpoint!")
	})))
}
Esempio n. 2
0
func main() {
	router := xmux.New()

	router.GET("/unoconv/health", xhandler.HandlerFuncC(healthHandler))
	router.POST("/unoconv/:filetype", xhandler.HandlerFuncC(unoconvHandler))
	log.Fatal(http.ListenAndServe(":3000", mw.Handler(router)))
}
Esempio n. 3
0
func router(a *server) http.Handler {
	mux := xmux.New()

	c := xhandler.Chain{}

	c.Use(mwLogger)
	c.Use(mwAuthenticationCheck(a.key))

	mux.GET("/sites", c.HandlerCF(xhandler.HandlerFuncC(a.handleAllSites)))
	mux.GET("/sites/:id", c.HandlerCF(xhandler.HandlerFuncC(a.handleSingleSite)))
	mux.GET("/torrents", c.HandlerCF(xhandler.HandlerFuncC(a.handleTorrents)))
	mux.POST("/download/:hash", c.HandlerCF(xhandler.HandlerFuncC(a.handleDownload)))

	return xhandler.New(context.Background(), mux)
}
Esempio n. 4
0
File: auth.go Progetto: blang/posty
// Callback handles the oidc/oauth2 callback after a login attempt from the user.
// If the idenity provider returned a proof for valid login, the userid is stored in the session.
// This includes the model lookup and a possible creation for new users.
// The users last login timestamp is updated.
func (c *AuthController) Callback(successURL string) xhandler.HandlerC {
	return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		log.Info("Handler: Callback")
		user, err := c.Provider.Callback(w, r)

		if err != nil {
			log.Printf("Error occurred: %s", err)
			http.Error(w, "Bad Request", http.StatusBadRequest)
			return
		}
		if user == nil {
			log.Printf("Error occurred uid is nil")
			http.Error(w, "Bad Request", http.StatusBadRequest)
			return
		}
		uuid := c.ProviderName + ":" + user["id"]

		u, err := c.loginUser(uuid, user["name"])
		if err != nil {
			log.Warnf("Could not create new user: %s", err)
			http.Error(w, "Bad Request", http.StatusBadRequest)
			return
		}
		session := ctx.Value("session").(*sessions.Session)
		session.Values["user"] = u.ID
		session.Save(r, w)

		http.Redirect(w, r, successURL, http.StatusFound)
	})
}
Esempio n. 5
0
File: auth.go Progetto: blang/posty
// Login handles login requests and delegates to the oidc provider.
func (c *AuthController) Login() xhandler.HandlerC {
	return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		log.Info("Handler: Login")
		c.Provider.NewAuth(w, r)
		return
	})
}
Esempio n. 6
0
func TestNewHandlerWrongAudience(t *testing.T) {
	c := Config{
		Secret:    "5d63GMY5fRsBRdB7cDsMoLlNX9vWxNSq",
		Issuer:    "dmiss",
		Audiences: []string{"aud1", "aud2"},
	}
	h := NewHandler(c)
	xh := h(xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
	}))

	tok, err := generateToken()
	if err != nil {
		t.Fatalf("generateToken() - error encoding claim: %s", err)
	}
	fullPath := "/?access_token=" + tok

	w := httptest.NewRecorder()
	r, _ := http.NewRequest("GET", fullPath, nil)

	xh.ServeHTTPC(context.Background(), w, r)

	if want, got := http.StatusForbidden, w.Code; want != got {
		t.Errorf("TestNewHandlerWrongAudience http code: want %d got %d", want, got)
	}
}
Esempio n. 7
0
// ToHandler - Converts function to middleware.
func ToHandler(fn func(ctx context.Context, w http.ResponseWriter, r *http.Request, next xhandler.HandlerC)) Handler {
	return func(next xhandler.HandlerC) xhandler.HandlerC {
		return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			fn(ctx, w, r, next)
		})
	}
}
Esempio n. 8
0
// HandleFunc regiester a standard http.HandlerFunc request handler with the given
// path and method. With this adapter, your handler won't have access to the
// context and thus won't work with URL parameters.
func (mux *Mux) HandleFunc(method, path string, handler http.HandlerFunc) {
	mux.HandleC(method, path,
		xhandler.HandlerFuncC(func(_ context.Context, w http.ResponseWriter, r *http.Request) {
			handler(w, r)
		}),
	)
}
Esempio n. 9
0
func TestMuxLookup(t *testing.T) {
	routed := false
	wantHandler := xhandler.HandlerFuncC(func(_ context.Context, _ http.ResponseWriter, _ *http.Request) {
		routed = true
	})

	mux := New()

	// try empty router first
	handler, _, tsr := mux.Lookup("GET", "/nope")
	assert.Nil(t, handler, "Got handle for unregistered pattern: %v", handler)
	assert.False(t, tsr, "Got wrong TSR recommendation!")

	// insert route and try again
	mux.GET("/user/:name", wantHandler)

	handler, params, tsr := mux.Lookup("GET", "/user/gopher")
	if assert.NotNil(t, handler) {
		handler.ServeHTTPC(nil, nil, nil)
		assert.True(t, routed, "Routing failed!")
	}

	assert.Equal(t, newParams("name", "gopher"), params)

	handler, _, tsr = mux.Lookup("GET", "/user/gopher/")
	assert.Nil(t, handler, "Got handle for unregistered pattern: %v", handler)
	assert.True(t, tsr, "Got no TSR recommendation!")

	handler, _, tsr = mux.Lookup("GET", "/nope")
	assert.Nil(t, handler, "Got handle for unregistered pattern: %v", handler)
	assert.False(t, tsr, "Got wrong TSR recommendation!")
}
Esempio n. 10
0
func middlewareByName(opts Options) (Handler, error) {
	descriptors := Descriptors()
	sort.Sort(byName(descriptors))

	return func(next xhandler.HandlerC) xhandler.HandlerC {
		return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			name, err := opts.String(ctx, optMiddlewareName)
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

			reskey, _ := opts.String(ctx, optMiddlewareDestination)

			for _, desc := range descriptors {
				if desc.Name == name {
					ctx = components.WithTemplateKey(ctx, reskey, desc)
					break
				}
			}

			next.ServeHTTPC(ctx, w, r)
		})
	}, nil
}
Esempio n. 11
0
func NewHandler(c Config) func(xhandler.HandlerC) xhandler.HandlerC {
	return func(next xhandler.HandlerC) xhandler.HandlerC {
		return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			var auth bool

			// Skip verification of path is in skip list.
			for _, skipPath := range c.Skip {
				if r.URL.Path == skipPath {
					auth = true
					break
				}
			}

			if !auth && c.Secret != "" {
				// Check token credentials.
				auth = checkToken(c, r)
			}

			// Check basic auth if no authorization based on token.
			if !auth && c.BasicUser != "" && c.BasicPass != "" {
				auth = checkBasicAuth(c, w, r)
			}

			if auth {
				next.ServeHTTPC(ctx, w, r)
			} else {
				http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
			}
		})
	}
}
Esempio n. 12
0
func ExampleNewHandler() {
	c := xhandler.Chain{}

	// Install the metric handler with dogstatsd backend client and some env tags
	flushInterval := 5 * time.Second
	tags := []string{"role:my-service"}
	statsdWriter, err := net.Dial("udp", "127.0.0.1:8126")
	if err != nil {
		log.Fatal(err)
	}
	c.UseC(xstats.NewHandler(dogstatsd.New(statsdWriter, flushInterval), tags))

	// Here is your handler
	h := c.Handler(xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		// Get the xstats request's instance from the context. You can safely assume it will
		// be always there, if the handler is removed, xstats.FromContext will return a nop
		// instance.
		m := xstats.FromContext(ctx)

		// Count something
		m.Count("requests", 1, "route:index")
	}))

	http.Handle("/", h)

	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}
Esempio n. 13
0
func TestMuxPanicHandler(t *testing.T) {
	mux := New()
	panicHandled := false

	mux.PanicHandler = func(ctx context.Context, w http.ResponseWriter, r *http.Request, p interface{}) {
		panicHandled = true
	}

	mux.HandleC("PUT", "/user/:name", xhandler.HandlerFuncC(func(_ context.Context, _ http.ResponseWriter, _ *http.Request) {
		panic("oops!")
	}))

	w := new(mockResponseWriter)
	req, _ := http.NewRequest("PUT", "/user/gopher", nil)

	defer func() {
		if rcv := recover(); rcv != nil {
			t.Fatal("handling panic failed")
		}
	}()

	mux.ServeHTTPC(context.Background(), w, req)

	assert.True(t, panicHandled, "simulating failed")
}
Esempio n. 14
0
// MethodHandler returns a handler setting the request's method as a field
// to the current context's logger using the passed name as field name.
func MethodHandler(name string) func(next xhandler.HandlerC) xhandler.HandlerC {
	return func(next xhandler.HandlerC) xhandler.HandlerC {
		return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			FromContext(ctx).SetField(name, r.Method)
			next.ServeHTTPC(ctx, w, r)
		})
	}
}
Esempio n. 15
0
File: json.go Progetto: blang/posty
// JSONWrapper sets the content-type of the response to json.
func JSONWrapper() func(next xhandler.HandlerC) xhandler.HandlerC {
	return func(next xhandler.HandlerC) xhandler.HandlerC {
		return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			w.Header().Set("Content-Type", "application/vnd.api+json")
			next.ServeHTTPC(ctx, w, r)
		})
	}
}
Esempio n. 16
0
func main() {
	c := xhandler.Chain{}
	c.Use(recoverMiddleware)
	c.Use(normalLoggingMiddleware)
	c.Use(log15LoggingMiddleware)
	c.Use(logrusLoggingMiddleware)

	simpleHandler := xhandler.HandlerFuncC(simple)
	accountHandler := xhandler.HandlerFuncC(account)
	noteHandler := xhandler.HandlerFuncC(note)

	mux := bone.New()
	mux.Get("/account/:id", c.Handler(accountHandler))
	mux.Get("/note/:id", c.Handler(noteHandler))
	mux.Get("/simple", c.Handler(simpleHandler))
	http.ListenAndServe(":8080", mux)
}
Esempio n. 17
0
func ExampleMux_NewGroup() {
	mux := xmux.New()

	api := mux.NewGroup("/api")

	api.GET("/users/:name", xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "GET /api/users/%s", xmux.Param(ctx, "name"))
	}))

	api.POST("/users/:name", xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "POST /api/users/%s", xmux.Param(ctx, "name"))
	}))

	if err := http.ListenAndServe(":8080", xhandler.New(context.Background(), mux)); err != nil {
		log.Fatal(err)
	}
}
Esempio n. 18
0
File: main.go Progetto: blang/posty
func serveFiles(path string, prefix string) xhandler.HandlerC {
	fileserver := http.FileServer(http.Dir(path))
	handler := http.StripPrefix(prefix, fileserver)
	return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		log.Infof("Serving: %s", r.RequestURI)
		handler.ServeHTTP(w, r)
	})
}
Esempio n. 19
0
func routeTracing(route Route, handler xhandler.HandlerC) xhandler.HandlerC {
	rs := route.String()
	return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		tr := trace.New(rs, fmt.Sprintf("%s %s", r.Method, r.URL.Path))
		ctx = trace.NewContext(ctx, tr)
		handler.ServeHTTPC(ctx, w, r)
		tr.Finish()
	})
}
Esempio n. 20
0
// UserAgentHandler returns a handler setting the request's client's user-agent as
// a field to the current context's logger using the passed name as field name.
func UserAgentHandler(name string) func(next xhandler.HandlerC) xhandler.HandlerC {
	return func(next xhandler.HandlerC) xhandler.HandlerC {
		return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			if ua := r.Header.Get("User-Agent"); ua != "" {
				FromContext(ctx).SetField(name, ua)
			}
			next.ServeHTTPC(ctx, w, r)
		})
	}
}
Esempio n. 21
0
// RemoteAddrHandler returns a handler setting the request's remote address as a field
// to the current context's logger using the passed name as field name.
func RemoteAddrHandler(name string) func(next xhandler.HandlerC) xhandler.HandlerC {
	return func(next xhandler.HandlerC) xhandler.HandlerC {
		return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			if host, _, err := net.SplitHostPort(r.RemoteAddr); err == nil {
				FromContext(ctx).SetField(name, host)
			}
			next.ServeHTTPC(ctx, w, r)
		})
	}
}
Esempio n. 22
0
File: auth.go Progetto: blang/posty
// Logout handles logout requests and invalidates the users session.
func (c *AuthController) Logout(loginURL string) xhandler.HandlerC {
	return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		log.Info("Handler: Logout")
		session := ctx.Value("session").(*sessions.Session)
		delete(session.Values, "user")
		session.Save(r, w)

		http.Redirect(w, r, loginURL, http.StatusFound)
	})
}
Esempio n. 23
0
func TestRouteGroupAPI(t *testing.T) {
	var get, head, options, post, put, patch, delete bool

	mux := New()
	group := mux.NewGroup("/foo") // creates /foo group

	group.GET("/GET", xhandler.HandlerFuncC(func(_ context.Context, _ http.ResponseWriter, _ *http.Request) {
		get = true
	}))
	group.HEAD("/GET", xhandler.HandlerFuncC(func(_ context.Context, _ http.ResponseWriter, _ *http.Request) {
		head = true
	}))
	group.OPTIONS("/GET", xhandler.HandlerFuncC(func(_ context.Context, _ http.ResponseWriter, _ *http.Request) {
		options = true
	}))
	group.POST("/POST", xhandler.HandlerFuncC(func(_ context.Context, _ http.ResponseWriter, _ *http.Request) {
		post = true
	}))
	group.PUT("/PUT", xhandler.HandlerFuncC(func(_ context.Context, _ http.ResponseWriter, _ *http.Request) {
		put = true
	}))
	group.PATCH("/PATCH", xhandler.HandlerFuncC(func(_ context.Context, _ http.ResponseWriter, _ *http.Request) {
		patch = true
	}))
	group.DELETE("/DELETE", xhandler.HandlerFuncC(func(_ context.Context, _ http.ResponseWriter, _ *http.Request) {
		delete = true
	}))

	w := new(mockResponseWriter)

	r, _ := http.NewRequest("GET", "/foo/GET", nil)
	mux.ServeHTTPC(context.Background(), w, r)
	assert.True(t, get, "routing /foo/GET failed")

	r, _ = http.NewRequest("HEAD", "/foo/GET", nil)
	mux.ServeHTTPC(context.Background(), w, r)
	assert.True(t, head, "routing /foo/GET failed")

	r, _ = http.NewRequest("OPTIONS", "/foo/GET", nil)
	mux.ServeHTTPC(context.Background(), w, r)
	assert.True(t, options, "routing /foo/GET failed")

	r, _ = http.NewRequest("POST", "/foo/POST", nil)
	mux.ServeHTTPC(context.Background(), w, r)
	assert.True(t, post, "routing /foo/POST failed")

	r, _ = http.NewRequest("PUT", "/foo/PUT", nil)
	mux.ServeHTTPC(context.Background(), w, r)
	assert.True(t, put, "routing /foo/PUT failed")

	r, _ = http.NewRequest("PATCH", "/foo/PATCH", nil)
	mux.ServeHTTPC(context.Background(), w, r)
	assert.True(t, patch, "routing /foo/PATCH failed")

	r, _ = http.NewRequest("DELETE", "/foo/DELETE", nil)
	mux.ServeHTTPC(context.Background(), w, r)
	assert.True(t, delete, "routing /foo/DELETE failed")
}
Esempio n. 24
0
// tracingMiddleware - Tracing for middlewares.
func tracingMiddleware(md *middlewares.Middleware, handler middlewares.Handler) middlewares.Handler {
	return func(next xhandler.HandlerC) xhandler.HandlerC {
		h := handler(next)
		return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			tr, _ := trace.FromContext(ctx)
			tr.LazyPrintf("%s", md.Name)
			h.ServeHTTPC(ctx, w, r)
		})
	}
}
Esempio n. 25
0
// RefererHandler returns a handler setting the request's referer header as
// a field to the current context's logger using the passed name as field name.
func RefererHandler(name string) func(next xhandler.HandlerC) xhandler.HandlerC {
	return func(next xhandler.HandlerC) xhandler.HandlerC {
		return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			if ref := r.Header.Get("Referer"); ref != "" {
				FromContext(ctx).SetField(name, ref)
			}
			next.ServeHTTPC(ctx, w, r)
		})
	}
}
Esempio n. 26
0
func TestURLHandler(t *testing.T) {
	r := &http.Request{
		URL: &url.URL{Path: "/path", RawQuery: "foo=bar"},
	}
	h := URLHandler("url")(xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		l := FromContext(ctx).(*logger)
		assert.Equal(t, F{"url": "/path?foo=bar"}, F(l.fields))
	}))
	h = NewHandler(Config{})(h)
	h.ServeHTTPC(context.Background(), nil, r)
}
Esempio n. 27
0
func TestMethodHandler(t *testing.T) {
	r := &http.Request{
		Method: "POST",
	}
	h := MethodHandler("method")(xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		l := FromContext(ctx).(*logger)
		assert.Equal(t, F{"method": "POST"}, F(l.fields))
	}))
	h = NewHandler(Config{})(h)
	h.ServeHTTPC(context.Background(), nil, r)
}
Esempio n. 28
0
func TestRemoteAddrHandlerIPv6(t *testing.T) {
	r := &http.Request{
		RemoteAddr: "[2001:db8:a0b:12f0::1]:1234",
	}
	h := RemoteAddrHandler("ip")(xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		l := FromContext(ctx).(*logger)
		assert.Equal(t, F{"ip": "2001:db8:a0b:12f0::1"}, F(l.fields))
	}))
	h = NewHandler(Config{})(h)
	h.ServeHTTPC(context.Background(), nil, r)
}
Esempio n. 29
0
func TestHandler(t *testing.T) {
	s := &fakeSender{}
	n := xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		xs, ok := FromContext(ctx).(*xstats)
		assert.True(t, ok)
		assert.Equal(t, s, xs.s)
		assert.Equal(t, []string{"envtag"}, xs.tags)
	})
	h := NewHandler(s, []string{"envtag"})(n)
	h.ServeHTTPC(context.Background(), nil, nil)
}
Esempio n. 30
0
// CompileInContext - Compiles component from context.
// Stores result in context to be retrieved with `components.FromContext`.
func CompileInContext(next xhandler.HandlerC) xhandler.HandlerC {
	return xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		compiled, err := compiler.Compile(ctx)
		if err != nil {
			helpers.WriteError(w, r, http.StatusExpectationFailed, fmt.Sprintf("compile error: %v", err))
			return
		}
		ctx = components.NewCompiledContext(ctx, compiled)
		next.ServeHTTPC(ctx, w, r)
	})
}