Giter Site home page Giter Site logo

alice's People

Contributors

dvrkps avatar hallas avatar jkearse3 avatar justinas avatar juztin avatar kevwan avatar mmlb avatar mveytsman avatar nhooyr avatar ojongerius avatar santosh653 avatar wayneashleyberry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alice's Issues

Conditional middlewares

I though it might be a good idea to make alice be able to apply middlewares based on conditions which the Request must satisfy.
For example some url paths need user authentication and some don't. It's a waste to apply the auth middleware to those as well.

Any idea on this?

tag 1.0.0 was deleted without notice which caused errors with glide

Hi, we've just noticed that our build jobs started failing because of the deleted tag in your repository.

we use glide with a following configuration:

  • package: github.com/justinas/alice
    version: ^1.0.0

However, with this configuration glide fails to fetch corresponding alice package
To reproduce issue locally, first remove glide cache under ~/.glide/

glide version:

$ glide -v
glide version v0.12.3

Examples

Hello! I’m a huge fan of Alice. I use it for all of my go servers. I almost always use the same three or four middleware’s as a baseline (logging, recovery, authentication, rate limiting, etc). Would you be open to a PR adding example middleware’s that solve common problems?

I know there’s some in the README but something like logging or conditional middlewares are a bit more verbose than a quick start.

If this is something you think would be helpful I’d be happy to put together a PR. I just don’t know if it’d be better as complete code in an examples folder or additions to the README.

Provide http.HandlerFunc alternative for middleware?

After playing around with alice for a bit, I was wondering, might it be a good idea to provide a Constructor alternative whose signature is func(http.HandlerFunc) http.HandlerFunc? All my middleware are just handler functions, and so I have to do http.HandlerFunc(myMiddlewareFunc) before passing them into alice. This is not a big deal, but since there is also a .ThenFunc alternative to the .Then function to pass in the final handler, I was wondering if there is a reason not to provide the same flexibility for the middleware? I am not sure though what a good name for that alternative Constructor type would be since ConstructorFunc doesn't feel right to me.

Initialize Go Modules and Tag v1.0.0 release

I realize alice had a v1.0.0 release which was removed. Now that modules support for Go is stable and adoption is growing, would it be possible to add back the v1.0.0 release tag and initialize modules for alice? Thanks for your consideration!

Dan

go get error

when I install throttled, execute go get command:

go get "github.com/throttled/throttled"

here is an error:

can't load package: package github.com/throttled/throttled: code in directory /Users/litanhua/GoglandProjects/cloudstorage/src/github.com/throttled/throttled expects import "gopkg.in/throttled/throttled.v2"

thank you!

gorilla-mux

how is this used with gorilla mux for example?
--Update.. Got it working.. my issue was actually in my middleware.. However is there are reason for example that the Gorilla mux router can't be chained.. right now I have it as

alice.New(th.Throttle, timeoutHandler, authReq).Then(gorillaMuxRouter) to work..
if I do
alice.New(th.Throttle, timeoutHandler, authReq,gorillaMuxRouter).Then(nil)
then it won't work and I'll get a compile time error.

Reuse chain?

I haven't tried Alice yet, but I am curious if the example below is possible:

stdStack := alice.New(gzipHandler, ratelimitHandler, securityHandler, authHandler)
indexChain := stdStack.Then(indexHandler)
resourceChain := stdStack.Then(resourceHandler)

If that works, it would be nice to have it mentioned in the docs.

How to execute a middleware after the app?

Hi,Justinas.

Nice Work,I must say !! Alice is a elegant way to implement a middleware layer.

But I also found it is diffcult to execute a middleware after the app run? Just like how the logger do in negroni.

like this:

in --> recovery --> logging --> csrf --> app

out <- logging

Do I make myself clear?

Any more examples?

There are no more examples? request more examples available for testing.

inconvenient Constructor type alias

type Constructor func(http.Handler) http.Handler is used for defining middleware functions, and is used as part of New(constructors ...Constructor) { this has caused some problems for me due to the lack of implicit type aliasing on sliced variadic parameters. example here: https://play.golang.org/p/5arBiRLckG
the issue i'm facing is that i'm writing a package where i'd like to users to be able to define a slice of func(http.Handler) http.Handler and not have to import alice in order to provide them. i know i can iterate and manually do the type conversion, and i'm doing that for now, but i figured i'd make this issue anyway just as something for you to consider.

Thanks

Blog post URL is not working

Issue
Blog post URL provided in README.md is not working and throwing 404 error.
There is a slash at the end of URL that causes this issue.
Possibly, the server has configured routes in this way thus it is expected behavior at blog (server).

Solution
Need to remove last slash from URL

Status code not being passed

Status code is not being passed. Try returning an error:

http.Error(w, http.StatusText(401), http.StatusUnauthorized)

You will get the message but not the status code.

Reworking Constructor interface?

Thoughts on an implementation along the lines of this? I'm not a very experienced programmer, so my opinions may be invalid.

type Constructor interface {
        Construct(http.Handler) http.Handler
}

type ConstructorFunc func(http.Handler) http.Handler
func (c ConstructorFunc) Construct(h http.Handler) http.Handler {
        return c(h)
}

This allows a function with that signature to be casted with ConstructorFunc,
trying to follow the same idiom as http.Handler and http.HandlerFunc.

Useful things like wrapping something and giving it a Construct method would be great.

type AliceLogger struct {
    *log.Logger
}

func (l *AliceLogger) Construct(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        l.Printf("Logging the %v request.", r.Method)
        h.ServeHTTP(w, r)
    })
}

Although this would be a breaking change, but would allow for easy addition of various kinds of middleware simply by writing a Construct method. Also I noticed that Then() would allow Alice to implement itself (although unnecessary) by changing Then() to Construct().

logger := &log.Logger{log.New(os.Stdout, "TestLogger", 0)}
alice.New(logger).Construct(nil)

Also, if it's breaking, maybe rename it to Adapter, with a method of Adapt(), based on this talk by Mat Ryer:
https://youtu.be/tIm8UkSf6RA?t=26m56s

I also implemented this in a separate branch to test it out:
https://github.com/jkearse3/alice/tree/newinterface

Thoughts or corrections to anything I proposed?

http.TimeoutHandler

Have you guys tested using http.TimeoutHandler with alice?

How is the best way, in your opinion, to make it works?

Gracefully handle errors

I don't like the way there are no error management.
What do you think to change a little bit the code to handle errors.

something like :

type Constructor func(http.Handler) (http.Handler, error)
type ErrorHandler func(http.Handler, error) http.Handler //create a new type to handle errors on Then

And then on Method Then :

func (c Chain) Then(h http.Handler, eh ErrorHandler) http.Handler {
	if h == nil {
		h = http.DefaultServeMux
	}

	for i := range c.constructors {
		h, err := c.constructors[len(c.constructors)-1-i](h)
		if err != nil && eh != nil {
			h = eh(h, err)
                        break
		}
	}

	return h
}

nothing else change. But it will allow people to create middlewares like :

var ErrInvalidParameter = errors.New("invalid parameter")

func Mid1(h http.Handler) (http.Handler, error) {
     //Do a lot of stuff and if there are an issue with parameter 
    return h, ErrInvalidParameter // can be another error depending on the code of course this is just an example
}

func ErrHandler(http.Handler, error) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch err {
		        case ErrInvalidParameter:
			       w.WriteHeader(http.StatusBadRequest)
		        default:
			       w.WriteHeader(http.StatusInternalServerError)
		}
	        
               //Add more information if wanted
	        w.Header().Set("Content-Type", "application/json; charset=utf-8")
	        json.NewEncoder(w).Encode(map[string]interface{}{
		         "error": err.Error(),
                }
           })
}

//And somewhere on main.go
alice.New(Mid1, Mid2, Mid3).Then(App, ErrHandler)

What do you think ?
If you agree with the concept, I can do the code and unit tests.

An And() method for easy extending of a stack.

@gust1n proposed an And() method for easily returning a new stack with more middleware appended to the end of the request cycle.

While I'm reluctant to add new methods, And() seems reasonable, as it is such an essential one. As it is now, extending the stack is a bit tricky.

stdHandlers := []alice.Constructor{gzipHandler, ratelimitHandler,
 securityHandler, authHandler}
indexHandlers := make([]alice.Constructor, len(stdHandlers))
copy(indexChain, stdHandlers)
append(indexChain, xssHandler)
indexChain := alice.New(indexHandlers).Then(indexHandler)

On that note, Remove() and others will probably never come to life (defining function equality is tricky, etc.).

And() will probably return a new stack to prevent modifying existing stacks when extending them into new ones.

stdStack := alice.New(M1, M2)
extStack := stdStack.And(M3)
// stdStack is left unmodified, with only two pieces of middleware.

OR-Chained middlewares

It would be cool if alice could support chaining middlewares with or instead of executing them one after one. Currently, alice executes middlewares one after the other. The thing I have in mind would be to execute the first one in the list, if that fails execute the second one etc.

A bit more context on the use case:
We would like to use this with the chain middleware in traefik which is powered by alice. We have one site which we want to secure using ip whitelist and basic auth either one should work. If a user accesses the site not on the ip whitelist, it should need to complete the basic auth.

I'm not sure this is the right place to ask, but I figured I'd just open an issue to get the discussion going. Maybe this is a too-specific use-case for alice and would be better suited in traefik itself.

How to use with httprouter

Hi, I love alice and it works great alongside github.com/julienschmidt/httprouter until I need to do a per route middleware.

        authChain := alice.New(
		rest.CorrellationMiddleware, 
		rest.LogMiddleware(log),
		rest.TimeoutMiddleware, 
		rest.JwtAuthenticationMiddleware(pubKey)
	);
	noAuthChain := alice.New(
		rest.CorrellationMiddleware, 
		rest.LogMiddleware(log),
		rest.TimeoutMiddleware
	);

	router.POST("/auth/login", noAuthChain.ThenFunc(userController.Authenticate))
	router.GET("/users/me", authChain.ThenFunc(userController.Me))

This wont work since Httprouter requires a signature of (w http.ResponseWriter, r *http.Request, _ httprouter.Params) as a handler
Is there some way to get this to work even though?

A way of passing variables between middlewares

Which way of passing values between middlewares do you suggest?

In case you do not want to have a global vars (e.g.. gorilla-*) but want something specific to the request itself.

Imaging that you have middleware which extracts a lot of data from request and store then in some context struct for down the road middlewares to use this info to perform activities.
(simple example is Authentication or Session info)

e.g.: goji passes a goji.C (a context) struct down the chain.

Why alice doesn't accept a basic handler in the Then() method?

I'm trying to create a website with httprouter and alice. I saw that alice has the nice option to do alice.New().Then() and pass in the Then() a handler to be executed. Sadly, I can only pass a handler declared as this: func myhandler(w http.ResponseWriter, r *http.Request) { if I only wrap it in an http.HandlerFunc() first. Why isn't possible to just pass one of those? Assuming there's a good chance that the majority of the users will be passing one of those handlers there?

Dependency Injection Support?

Is there any way I can inject a dependency such as a *sql.DB or something into my middleware?

I want to be able to verify session users and user roles that require access to a database. It makes sense to add this logic to the middleware, but I'm struggling to wrap my head around how it would work.

Any suggestions?

Is there a negative consequences to using alice in a route?

This works:

r.Get("/hello/{name}", alice.New(middleware.Junk).Then(http.HandlerFunc(HelloServer)))
chain := alice.New(middleware.Auth).Then(r)
http.ListenAndServe(":12345", chain)

For specifying route specific middleware. Is there any reason why I should not do this and also have middleware for the router? It would be useful for route specific permissions (the use case I had in mind).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.