Git Product home page Git Product logo

air's People

Contributors

aleksi avatar aofei avatar bouncyelf avatar sauldoescode 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

air's Issues

Cookies Go Missing when they're set before a redirect

air.GET("/auth/:verifier", func(req *air.Request, res *air.Response) error {
	user, err := VerifyUser(req.Param("verifier").Value().String())
	if err != nil || user == nil {
		if DevMode {
			fmt.Println("Unable to Authenticate user: ", err)
		}
		return UnauthorizedError.Send(res)
	}

	newtoken, err := GenerateAuthToken(user, false)
	if err == nil {
// This Cookie never reaches the client
		res.SetCookie("Auth", &air.Cookie{
			Value:    newtoken,
			Path:     "/",
			MaxAge:   60 * 60 * 24 * 7,
                        Domain: AppDomain,
			HTTPOnly: !DevMode,
			Secure:   !DevMode,
		})
	} else {
		if DevMode {
			fmt.Println("error verifying the user, GenerateAuthToken db problem: ", err)
		}
	}

	if user.isAdmin() {
		return res.Redirect("/admin")
	}
	return res.Redirect("/")
})

the problem is probably somewhere in res.Write, but it looks like the Header application step of serving is ignored when content io.ReadSeeker is nil, or something else is happening, not sure.
But I need cookies to set on redirects, it worked in echo, it should work here.

How to write test becnhmark

func airHandler(req *air.Request, res *air.Response) error {
	return nil
}
func airHandlerWrite(req *air.Request, res *air.Response) error {
	// io.WriteString(res, s)
	return res.WriteString(req.Param("name").Value().String())
}
func airHandlerTest(req *air.Request, res *air.Response) error {
	return res.WriteString(req.Path)
}

// func (a *air.Air) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 	// a := air.New()
// 	a.server.ServeHTTP(r, w)
// }
func loadAir(routes []route) http.Handler {
	h := airHandler
	if loadTestHandler {
		h = airHandlerTest
	}
	app := air.New()
	for _, r := range routes {
		switch r.method {
		case "GET":
			app.GET(r.path, h)
		case "POST":
			app.POST(r.path, h)
		case "PUT":
			app.PUT(r.path, h)
		case "PATCH":
			app.PATCH(r.path, h)
		case "DELETE":
			app.DELETE(r.path, h)
		default:
			panic("Unknow HTTP method: " + r.method)
		}
	}
	return app
}
func loadAirSingle(method, path string, h air.Handler) http.Handler {

	app := air.New()
	// app.Middleware.Skip(nil, h)
	switch method {
	case "GET":
		app.GET(path, h)
	case "POST":
		app.POST(path, h)
	case "PUT":
		app.PUT(path, h)
	case "PATCH":
		app.PATCH(path, h)
	case "DELETE":
		app.DELETE(path, h)
	default:
		panic("Unknow HTTP method: " + method)
	}

	return app
}

Error

./router.go:557:6: cannot define new methods on non-local type air.Air
./router.go:559:3: a.server undefined (cannot refer to unexported field or method server)
./router.go:583:2: cannot use app (type *air.Air) as type http.Handler in return argument:
        *air.Air does not implement http.Handler (missing ServeHTTP method)
./router.go:604:2: cannot use app (type *air.Air) as type http.Handler in return argument:
        *air.Air does not implement http.Handler (missing ServeHTTP method)

Code organization and API naming convention.

Writing Format

  1. 100 characters per line.
  2. Use <Tab> to indentation.
  3. A <Tab> occupies 8 spaces.
  4. Use // to comment.

Code Organization

  1. Use gofmt to format all go files before git commit.

Testing

  1. Use go test to test whether the Air can server properly.

AutoPush needs more control

the <link> tag has several variations which don't always need pushing for example with preload/favicon pushing can disturb caching and cause needless bandwidth consumption and sometimes in the worst cases duplicate requests, so there should be a bit more specificity and potentially a feature to exclude/omit certain paths from the push list, (immutable/async cached assets assets that are very big)

see transplacer's take on this matter.

Gzip Support and cache-control headers

It would be very nice to see a golang web framework handle gzip natively and do it well. There are various libraries and middlewares out there which purport a well adjusted and performant solution to serving gzipped content.

I've made a fairly primitive project some time ago, which provides an echo instance with the ability to read, monitor, cache and recache various static assets either within a specified folder or definitively located elsewhere; with this it would determine an asset's compress-ability and compress it thusly, serving it, thereby, only when a client's Accept-Encoding header indicates gzip support.

Desireable Features In a Gzipping Sollution:

  • - Cache Gzipped Assets:

    • In memory, with coffer potentially.
      • watched assets, should, on changes, (asynchronously) re-compress/update a memory/disk backed asset.ext(.gz)
    • On Disk, like some nginx/apache configs permit.
      • eg. route localhost/asset.txt -> first looks for - > ./assets/.cache/asset.txt.gz
    • Client Side, by setting and maintaining the correct cache-control and etag headers.
  • - Compress at the highest level when caching, but automatically scale down with dynamic content.


Air does not seem to handle caching headers, (to my knowledge, I may be wrong), as all my coffer cached assets seem to be missing their cache-control headers. While it would be possible to deliberately add such caching headers, it would certainly also have been nice had the air sub systems managed cache headers when it detected that the higher level user has not set any or has not deliberately disabled cache-control.

Add MsgPack support

vmihailenco/msgpack has a fairly decent and easy to use golang msgpack implementation it would be great to see native support in air, I've used echo and gin in the past and it would have been nice to see msgpack being handled natively the same way JSON is.

// WriteMsgPack responds to the client with the "application/msgpack" content v.
func (r *Response) WriteMsgPack(v interface{}) error {
	var (
		b   []byte
		err error
	)

	b, err = msgpack.Marshal(v)
	if err != nil {
		return err
	}

	r.Headers["content-type"] = &Header{
		Name:   "content-type",
		Values: []string{"application/msgpack"},
	}

	return r.WriteBlob(b)
}

Also maybe there is a way to stream json and msgpack.
Streaming might be more performant and memory efficient than writing blobs.
But I'm not sure how to do it right and handle stream failures properly.

I'm using these functions in my Gin application

// SendMsgpack send a msgpack encoded response with a status code
func SendMsgpack(c ctx, code int, msg interface{}) error {
	c.Status(code)
	c.Header("Content-Type", "application/msgpack")
	return msgpack.NewEncoder(c.Writer).Encode(msg)
}

// SendJSON send a json encoded response with a status code
func SendJSON(c ctx, code int, msg interface{}) error {
	c.Status(code)
	c.Header("Content-Type", "application/json")
	return json.NewEncoder(c.Writer).Encode(msg)
}

ps. air 很牛,真的,谢谢你创造它

Dependency Headaches: some things aren't importing for reasons unknown

Simply cannot import /text/langauge for some reason.

go version
     go version go1.11.2 windows/amd64

go get -u golang.org/x/text/language
     go: finding golang.org/x/text/language latest
     go get golang.org/x/text/language: no matching versions for query "latest"

on my DigitalOcean Debian server, there's been some trouble with these:

go: github.com/tdewolff/minify/[email protected]: go.mod has non-.../v2 module path "github.com/tdewolff/minify" (and .../v2/go.mod does not exist) at revision v2.3.7
go: error loading module requirements

though on my windows devbox it works fine.


on a side note, massive updates today, wow!
This project is growing and getting better everyday 😲, it's hard to keep up lol.
But it's all good, many of the changes in the last day have been breaking (to me at least), so
I'm going to stick to the vanilla version as it is and simply write my extentions
in an extention.go file as I see no reason to tediously duplicate all the awesome
progress and developments you're driving.

The only reason for my fork was to add a couple of convenience features, like:

  • native msgpack support in binder.go and response.go
  • req.Query("param") is a nice to have feature
  • .SetCookie(name, http.Cookie), or, gin style .SetCookie(name, all_the_params_laid_flat...)
  • req.Cookie(name) -> string, and, req.GetCookie(name) -> *Cookie
  • Coffer Gzip support, and Gzip support generally
  • Streaming, which got solved already, thanks 👍
  • Plain http middleware support
    • specifically: throttled, which could make for a nice gas
  • +Various Header methods that make life easier.
  • cache-control related concerns, autocert things
  • HostWhiteList stuff, redirecting localhost to the main domain when in debug mode which was annoying, I wish there was a toggle.

And I see you've added many of these features already, so I'm wondering if
perhaps we could reach consensus on some of these features so that they can
potentially be integrated and made official.

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.