pomo_mondreganto
pomo_mondreganto

Reputation: 2074

http.Handler is not called in golang

I have the following middleware, first sets currentUser in gorilla/context to current user acquired from database, and the second checks if currentUser exists and redirects otherwise:

package main

import (
    "database/sql"
    "github.com/gorilla/context"
    "log"
    "net/http"
    "server/helpers"
)

func withCurrentUser(db *sql.DB, next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        userId := helpers.GetCurrentUserId(db, r)

        if userId == nil {
            next.ServeHTTP(w, r)
            return
        }

        row := db.QueryRow("SELECT username FROM User WHERE id=?", userId)
        var username string

        switch err := row.Scan(&username); err {
        case sql.ErrNoRows:
            next.ServeHTTP(w, r)
            return
        case nil:
            user := helpers.User{UserId: *userId, LoggedIn: true, Username: username}
            context.Set(r, "currentUser", user)
        default:
            log.Fatal(err)
        }

        next.ServeHTTP(w, r)
    })
}

func loginRequired(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        user, ok := context.Get(r, "currentUser").(helpers.User)
        log.Println(user, ok)
        if !ok {
            http.Redirect(w, r, "/login", 301)
            return
        }
        next.ServeHTTP(w, r)
    })
}

Then when I register a route that requires authenticated user, I do the following:

router.Handle("/create_post",
        withCurrentUser(db, loginRequired(http.HandlerFunc(createPostGet))),
    ).Methods(http.MethodGet)

Where createPostGet:

func createPostGet(w http.ResponseWriter, r *http.Request) {
    tmpl := template.Must(template.ParseFiles("templates/createPost.html"))
    user := context.Get(r, "currentUser").(helpers.User)
    _ = tmpl.Execute(w, helpers.FormStruct{CurrentUser: user})
}

My problem is: even if user is authenticated and context is populated correctly, this route always redirects to login. I tried setting breakpoints inside loginRequired and adding log.Println (as you can see in code), and that function doesn't seem to be even called (no breakpoints stop, no log output, too).

What's happening and how to make sure loginRequired is called every time and checks context properly?

UPD: It doesn't seem to persist, I recompiled the app a few times and now it's working. Anyway, what might be the reason for such behavior (I'm positive I saved everything the first time).

UPD 2: I found out that the problem is connected to browser caching, but I still have no idea why it happens. When I disable browser caching, everything works and function is called every time, but while browser cache is enabled, the function isn't called at all. Any ideas?

Upvotes: 0

Views: 804

Answers (1)

pomo_mondreganto
pomo_mondreganto

Reputation: 2074

OMG, that was stupid. I was using 301 redirect code in loginRequired, so redirect was permanent and browser didn't even make requests.

Upvotes: 2

Related Questions