Giter VIP home page Giter VIP logo

goji's People

Contributors

a-palchikov avatar bartle-stripe avatar codahale avatar ebroder avatar elithrar avatar haraldnordgren avatar joliv avatar mattn avatar meowgorithm avatar mmcgrana avatar moeryomenko avatar nickpresta avatar nullstyle avatar ruiaaperes avatar saj1th avatar satoshun avatar smith-30 avatar tamaoo avatar tesujimath avatar wangjohn avatar zenazn 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  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

goji's Issues

How to restart with Einhorn

When using Einhorn I know we can specify a PID file to write to such as "einhorn -e einhorn.pid ./main" but whenever I kill that PID the entire process dies.

How do I get the PID of the worker and not the master so I can do "kill -USR2 PID"

Use middleware to call controllers and pass context into them

In my middleware I call controllers like this:

controllers.XXXCtrl(c, w, r);

...then in my controller I would like to get db connection form the context

db, _ := c.Env["db"].(database.DB)

...but c.Env["db"] is missing

any better idea how to make it work?

log duplicate

such as following:

2014/08/20 17:20:25.099016 [PC-CORP/O6smW20tuK-000001] Started GET "/admin/" from [::1]:35653
2014/08/20 17:20:25.099016 [PC-CORP/O6smW20tuK-000001] Started GET "/admin/" from [::1]:35653
2014/08/20 17:20:25.101017 [PC-CORP/O6smW20tuK-000001] Returning 200 in 2.001ms
2014/08/20 17:20:25.101017 [PC-CORP/O6smW20tuK-000001] Returning 200 in 2.001ms

Middleware

Hi,

Do you have plans for other middleware? Sessions, OAuth2, ...

I am learning so I am not much help, but it would be nice if you could provide some more common middleware like martini?

Thanks

Auto reload for goji?

I know there are a lot of tools around for this. Not many of them work though. I was wondering with graceful shutdown and reloading built-in, will there ever be a dev mode for reloading server when files change.

"StrictSlash" Mode

gorilla/mux provides a StrictSlash method that redirects routes missing a trailing slash to one with a slash (or vice versa), primarily for SEO and secondly for browser history clarity.

It would be nice if Goji could provide a similar feature as part of its own router.

Route groups

Hi,

Is there a way to define route groups similar to Martini?

m.Group("/books", func(r martini.Router) {
    r.Get("/:id", GetBooks)
    r.Post("/new", NewBook)
    r.Put("/update/:id", UpdateBook)
    r.Delete("/delete/:id", DeleteBook)
})

By the way, goji looks really great!

Make mux.Use Variadic

Instead of having multiple subrouter.Use(SomeMiddleware) calls, it may be a worthwhile turning it into Use(middleware interface{], middleware ...interface{}).

The order of middleware passed to Use would define the ordering (from first -> last) when applied to the router.

r := web.New()
r.Use(middleware.Recovery)
r.Get("/", ShowIndex)

admin := web.New()
r.Handle("/administrate/*", admin)
admin.Use(middleware.Logger)
admin.Use(AdminOnly)
admin.Use(nosurf.NewPure)
admin.Use(gorillacontext.ClearHandler)

// ... would instead just be:
admin.Use(middleware.Logger, AdminOnly, nosurf.NewPure, gorillacontext.ClearHandler)

Potential downsides may be the interaction with middleware inherited from the parent router (in this case, the panic recovery middleware) — one solution would be to make the parent middleware first (implicitly).

This should not be an API breaking change either.

announce on golang nuts

I know there was a reddit and hackernews post, but you could announce this on Golang nuts too. Help spread the word :).

mux in a global state

Just rising a concern real quick (I'm sorta new to Go, so bear with me ;)).

I noticed that the mux in default.go is global. My concern is if one of my dependencies uses mux, can they expose routes to my app? How potentially "unsafe" is it since the goji mux is global?

Is it safer just to usegithub.com/zenazn/goji/web directly?

PS. great work.

Avoiding waitForSignal side-effects?

Currently there is waitForSignal call from an init() in the goji/graceful package:

https://github.com/zenazn/goji/blob/f70d2a33c1813a235a0f5f84bb5c2ce80aef57c3/graceful/signal.go#L29-32

This is somewhat troublesome for an app I'm building that has both "web" and "background worker" processes, where both are run out of the same main package (via a command-line switch). Because the goji/graceful package is imported by this main package, the corresponding goji/graceful init function is called for the web processes - which is fine - but also for the worker process. This results in an unwanted signal handler being installed for the worker processes and associated signal-related logging coming out of that worker process.

It's not a huge deal, but would be nice to fix if possible. Is there any way we could move this waitForSignal call to a site that would be explicitly called by processes using the package, like graceful.Serve(l)?

In the meantime, I'm calling graceful.ResetSignals() in the worker process case as a workaround.

Custom Handlers

No doubt I'm missing something simple: how do I satisfy the web.Handler interface? I have a common pattern that I use to simplify my app handlers so I don't have to explicitly call an error handler over and over and explicitly return nothing.

Contrived/example:

type appHandler func(web.C, http.ResponseWriter, *http.Request) *appError

type appError struct {
    Code  int
    Error error
}

// This is the hold up as I need to support the request context (without it, this works fine)
func (fn appHandler) ServeHTTP(c web.C, w http.ResponseWriter, r *http.Request) {
    if e := fn(c, w, r); e != nil {
        switch e.Code {
        case http.StatusOK:
            break
        case http.StatusBadRequest:
            ...
        case http.StatusNotFound:
            http.NotFound(w, r)
        case http.StatusInternalServerError:
            ...
        default:
            ...
        }
    }
}

func myHandler(c web.C, w http.ResponseWriter, r *http.Request) *appError {
    // do things
    return &appError{200, nil} // or return nil
}

"MISSING" text is appended in the middle of my json response

getting something like this on my json response :
"Description":"Firing more than 1 weapon in a turn will increase all damage by 5 / 10 / 15 / 20%!"(MISSING)

it only appears on goji, tried to query the json request using another golang framework, it works fine for them.
is there some issue with goji?

help getting started with goji

Apologies if I am being a noob / novice, but I am just getting started with Go.

I'm trying to run the sample programme and I am getting an error.

Here is the contents of hello.go:

package main

import (
        "fmt"
        "net/http"

        "github.com/zenazn/goji"
        "github.com/zenazn/goji/web"
)

func hello(c web.C, w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, %s!", c.URLParams["name"])
}

func main() {
        goji.Get("/hello/:name", hello)
        goji.Serve()
}

hello.go:7:9: cannot find package "github.com/zenazn/goji" in any of:
/usr/local/go/src/pkg/github.com/zenazn/goji (from $GOROOT)
/Users/Irfan/Projects/Go/src/github.com/zenazn/goji (from $GOPATH)
hello.go:8:9: cannot find package "github.com/zenazn/goji/web" in any of:
/usr/local/go/src/pkg/github.com/zenazn/goji/web (from $GOROOT)
/Users/Irfan/Projects/Go/src/github.com/zenazn/goji/web (from $GOPATH)

What am I doing wrong?

Only use middleware on certain routes

Hey there. New to Goji (and Go too, a little) and I'm curious if I can have middleware that runs on some routes and not others? For instance, I want some endpoints (most) to require authentication and a few to be public. An auth middleware makes sense, but how can I selectively use it?

Thanks. loving Goji so far!

Error handling

Hello there !

I like goji, it's all simple and light and I have a question : How would you do simple error handling ?
Like, may be in this post : http://blog.golang.org/error-handling-and-go ?
Having some handler funcs that look like this :

func viewStuff(w http.ResponseWriter, r *http.Request) *appError

With appError looking like this :

type appError struct {
    Error   error
    Message string
    Code    int
}

So then in the handler I could :

if err := datastore.Get(c, key, record); err != nil {
    return &appError{err, "Record not found", 404}
}

Thanks !

API Stability

Is there a plan of commit to a stable API moving forward—at least for the core packages?

I can understand if the middleware package may change down the track and/or breaking changes made when absolutely needed.

Multiple goji instances

I didn't find any documentation on how to run multiple goji instances within the same go program. That would be a nice addition, even if just documented here on this issue.

Question about web.C documentation

In the documentation for web.C it states the following:

If you are closing over a context (especially relevant for middleware), you should not close over either the URLParams or Env objects, instead accessing them through the context whenever they are required.

Could somebody post a small example of a middleware function that violates this edict? I want to make sure I understand the implications of this correctly. Does failing to follow this advice result in the possibility of variables in Env bleeding across requests?

Subrouter returning 200 OK instead of 404

Hi,

I'm trying to nut out an issue where a sub-router w/ some middleware applied is returning a 200 OK status instead of 404 Not Found.

The relevant routes—the route returning 200 (when it should not) is the /administrate/dashboard route. r.Handle is part of the top-level router (r := web.New()).

    // Admin dashboard
    admin := web.New()
    // Log all admin requests separately from the downstream server.
    admin.Use(middleware.Logger)
    admin.Use(AdminOnly)

    r.Handle("/administrate/*", admin)
    // admin.Get("/administrate/dashboard", appHandler(adminDashboardHandler))
    // admin.Get("/administrate/edit/:id", appHandler(adminEditHandler))

Here's the middleware:

// AdminOnly is a middleware that checks the userID in the session is an admin (boolean).
// It does not set any 'admin' flags in the session itself (it checks on each request).
func AdminOnly(c *web.C, h http.Handler) http.Handler {
    fn := appHandler(func(c web.C, w http.ResponseWriter, r *http.Request) (int, error) {
        session, err := store.Get(r, "workwithgo")
        if err != nil {
            return 500, err
        }

        // Re-direct to the login page if no ID is found in the session.
        id, ok := session.Values["userID"].(string)
        if !ok {
            http.Redirect(w, r, loginURL, http.StatusFound)
            return 302, nil
        }

        // Lookup the id from the session
        user := models.User{Id: id}
        admin, err := user.IsAdmin()
        if err != nil {
            return 500, nil
        }

        // Return 200 (and proceed) if the user is an administrator.
        if admin == true {
            log.Println("admin == true")
            return 200, nil
        }

        // Return a HTTP 401 if the user is NOT an administrator.
        return http.StatusUnauthorized, fmt.Errorf("User ID %q is not authorized to login", user.Id)
    })

    return fn
}

I believe the issue is triggered by if admin == true block: instead of raising a 404 on the wrapped handler (which is commented out at the moment), it just renders an empty body with a 200 OK status header.

Hitting any sub-route that is wrapped by the middleware exhibits the same issue.

The ServeHTTPC method on the custom handler type does not do anything fancy with a 200 status - it only does something when err != nil, so it should not be interfering.

// Allows appHandler to satisfy http.Handler
func (ah appHandler) ServeHTTPC(c web.C, w http.ResponseWriter, r *http.Request) {
    if status, err := ah(c, w, r); err != nil {
        switch status {
        case http.StatusNotFound:
                     ...
                     // More cases
                }
        }
}

Ultimately, I want to apply the middleware to the subrouter and have it 404 (as it should) when routes don't exist. For routes that do, the middleware should just do its job and pass requests through to the next handler in the chain.

Problem in importing github.com/zenazn/goji

Hi All,

I'm pretty new here and new to goji and even new to golang. I trying to execute the simple example program provided in the goji website but getting compilation error "can't find import: "github.com/zenazn/goji"".
I have downloaded "github.com/zenazn/goji" using "go get" command but after executing the command i didn't get any message in the CLI so i'm not sure if the download was successfully but i see some directories/files in my GOPATH. And following is my go env output

root@ubuntu:# go version
go version go1.3 linux/amd64
root@ubuntu:
# go env
GOARCH="amd64"
GOBIN=""
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/jennshan/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"

Any pointers to fix my goji installation would be helpful.

Many Thanks,
Jenni Reuben

HTTP 405 Method Not Allowed

When a path matches but the method doesn't, I'd like to respond with a custom MethodNotAllowed handler. Is this something you'd consider?

Add comparison to sibling projects?

At first glance, this appears to be quite similar to gocraft-web. I was curious what spurred the decision to start a new project and how it differs from some similar libraries?

There's also martini and revel, among several others, but gocraft-web seems to be pretty close in API and design, particularly with its use of web contexts. Several of these projects are mentioned on the home page but it's not clear which unique feature desires sparked goji.

It would be helpful to give a high-level overview of the differences (for example einhorn + systemd are new, while it appears nested routing is exclusive to gocraft).

c.URLParams available in middleware?

I'm trying to access c.URLParams in a middleware function of mine, however c.URLParams doesn't seem to be initiated. I am either doing something wrong on my end or maybe URLParams is initiated after all the middleware calls. Anyone able to clarify.

Issue with Windows build.

I get the following error while building on windows

# github.com/zenazn/goji/bind
..\..\zenazn\goji\bind\einhorn.go:40: cannot use fd (type int) as type syscall.H
andle in function argument
..\..\zenazn\goji\bind\systemd.go:28: cannot use systemdMinFd + i (type int) as
type syscall.Handle in function argument
# github.com/zenazn/goji/graceful
..\..\zenazn\goji\graceful\einhorn.go:21: undefined: syscall.SIGUSR2

run goji web app as background process

im surprised with the lack of detailed coverage on how to run golang web app in the background process i.e. when i close my ssh window it doesnt go down together with it.
and a good tool to just do a simple start, stop, AND RESTART!

how do we do it with goji? running it as a background process using supservisord seems fine with centos but the during restart, the program will just hang.
and using einhorn. i can start it. but cant restart it...
the einhorn only claimed "You can also seamlessly restart your workers without dropping any requests" but never document the HOW part.

im seriously frustrated with the current condition. golang is so beautiful n powerful n yet the deployment is a bitch.

Cannot Use in Google App Engine Due to Unsafe Package

I would like to use Goji for a project hosted on Google App Engine. Unfortunately, Google App Engine does not support the unsafe package (link).

Is it possible to refactor the router to not have to use the unsafe package? This would open Gojil up for developers on Google App Engine.

Passing Configuration to Middleware

I'm looking to contribute some middleware—specifically CSRF protection (which I am comfortable in writing out) and possibly some BasicAuth and NoCache middleware.

The CSRF middleware of course needs a session store to store the "real" token to compare with the masked token from form data and/or the request header. I'll wrap gorilla/sessions and look to allowing a package user to provide their own sessions.Store, else it defaults to a sessions.CookieStore.

Is there a preferred/idiomatic way to provide an exported configuration struct, initialise it and pass it to the middleware handler?

My current approach would be something like this:

type CSRFOptions struct {
      Store *sessions.Store
      Options *sessions.Options
      CookieName string
}

func NewCSRFOptions(store *sessions.Store, opts *sessions.Options, name string) *CSRFOptions {
     c := &CSRFOptions{
         ...
     }
     return &c
}

func (c *CSRFOptions) CSRF(c web.C, h http.Handler) http.Handler {
    ...
}

...

store := NewCSRFOptions(myStore, myOpts, "_csrftoken")

...

goji.Use(store.CSRF)

Do you have a preference for an alternate approach and/or is this compatible with Goji's middleware interfaces? Perhaps a CSRFDefaults() *CSRFOptions function that makes it easier to get started with?

How to use with einhorn

Whenever I try to run Goji under Einhorn I always get the bindErr: "bind: could not bind einhorn@%d: not running under einhorn"

Any examples on how to run it successfully?

serving parts of a page / creating an html document

Is it possible to serve parts of html and build a page using goji?

For example if I wanted to serve the of results.html, write , and then in a for loop write contents of the body of that page, and then . Or will I have to use standard Golang features like:

func viewHandler(w http.ResponseWriter, r *http.Request) {
    title := r.URL.Path[len("/view/"):]
    p, _ := loadPage(title)
    fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body)
}

Add an option that makes logger.go fetch the ip in X-Real-IP

Hi,

After building my application, and putting it under a nginx proxy_pass, I saw that the ip logged was always localhost. After looking at the source, I saw that you use r.RemoteAddr(), which is good for non-proxy use.

Could there be a way to implement goji looking at the headers to get the real ip?

Thanks,

Strange "dup: bad file descriptor" error with Einhorn

I try to use Goji with Einhorn and it shows this:

2014/06/11 02:42:50 graceful: Einhorn detected, adding SIGUSR2 handler
2014/06/11 02:42:50 dup: bad file descriptor
[MASTER 11532] INFO: ===> Exited worker 11778 before it was ACKed

dup: bad file descriptor error appears.

Sometimes Einhorn starts normally (and I don't know why exactly - I tried to remove some libraries and it works but then after some time this error appears again):

[MASTER 14292] INFO: [client 2:11] client connected
2014/06/11 02:50:12 bind: ACKing to einhorn

But when I use "upgrade" from einhornsh it shows:

2014/06/11 02:51:00 graceful: Einhorn detected, adding SIGUSR2 handler
2014/06/11 02:51:00 dup: bad file descriptor
[MASTER 14292] INFO: ===> Exited worker 14399 before it was ACKed
[MASTER 14292] INFO: Last spinup was 3.754994809s ago, and spinup_interval is 2.25s, so spinning up a new process (there have been 2 consecutive unacked worker deaths)

Command: go build && einhorn -b 127.0.0.1:8000 -m manual -n 2 ./app
System: Ubuntu 13.10
Non-standard packages:
"launchpad.net/goamz/aws"
"launchpad.net/goamz/s3"
"github.com/twinj/uuid"

Ubuntu install errors

Perhaps this is known, but when trying to install on Ubuntu I got the following:

github.com/zenazn/goji/graceful

/usr/lib/go/src/pkg/github.com/zenazn/goji/graceful/middleware.go:38: undefined: http.CloseNotifier
/usr/lib/go/src/pkg/github.com/zenazn/goji/graceful/middleware.go:93: undefined: http.CloseNotifier
/usr/lib/go/src/pkg/github.com/zenazn/goji/graceful/middleware.go:118: undefined: http.CloseNotifier
/usr/lib/go/src/pkg/github.com/zenazn/goji/graceful/signal.go:50: undefined: signal.Stop

github.com/zenazn/goji/web

/usr/lib/go/src/pkg/github.com/zenazn/goji/web/middleware.go:198: syntax error: unexpected :, expecting ]

rest extensions in urls

Hello,

I'd like to have extensions types for my routes, but with only one Handler.

/stuff -> render default type [html]
/stuff.json -> marshal my data to json
/stuff.html -> render a template showing data
/stuff.xml -> marshal my data to xml
/stuff.jsonp -> marshal my data to jsonp with my default param or the one provided

But if I do

goji.Get("/stuff:_format", getStuff )

The only way it will match is by curling stuff/json and it won't match on stuff or stuff.json .

I havent tried goji.Get("/stuff/:id:_format", getStuff )

I could do :
goji.Get("/stuff.json", getJsonStuff )
goji.Get("/stuff.html", getHtmlStuff )
With handlers wrapping my real controller
But that seems wrong and repetitive, isn't it ?

Is Goji going to support that kind of url matching, may be it already does ? ( I could try to contribute with - still my low go skills - if needed! )

Cheers !

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.