kataras / kataras/iris

http2 push in a dedicated handler

Open
#1,777 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
25.6k
Forks
2.4k
PR merge metrics
No merged PRs in 30d

Description

Hi,

Given one of my handlers is rendering a `ctx.View`, I would like to push the assets called by my HTML page.

In the `_example/response-writer/htt2push` package, the push is made in the same handler that render the HTML :

```golang
func pushHandler(ctx iris.Context) {
// The target must either be an absolute path (like "/path") or an absolute
// URL that contains a valid host and the same scheme as the parent request.
// If the target is a path, it will inherit the scheme and host of the
// parent request.
target := "/main.js"

if pusher, ok := ctx.ResponseWriter().Naive().(http.Pusher); ok {
err := pusher.Push(target, nil)
if err != nil {
if err == iris.ErrPushNotSupported {
ctx.StopWithText(iris.StatusHTTPVersionNotSupported, "HTTP/2 push not supported.")
} else {
ctx.StopWithError(iris.StatusInternalServerError, err)
}
return
}
}

ctx.HTML(``, target)
}
```

I would like to "extract" the logic that "push" the target in a separate handler. However, I found out that is doesn't work as I could expect. Here is an example that doesn't work :

```golang
package main

import (
"net/http"

"github.com/kataras/iris/v12"
)

const(
target = "/main.js"
)

func main() {
app := iris.New()
app.Get("/", pushHandler, index)
app.Get("/main.js", simpleAssetHandler)

app.Run(iris.TLS(":443", "mycert.crt", "mykey.key"))
}

func index(ctx iris.Context) {
ctx.HTML(``, target)
}

func pushHandler(ctx iris.Context) {
if pusher, ok := ctx.ResponseWriter().Naive().(http.Pusher); ok {
err := pusher.Push(target, nil)
if err != nil {
if err == iris.ErrPushNotSupported {
ctx.StopWithText(iris.StatusHTTPVersionNotSupported, "HTTP/2 push not supported.")
} else {
ctx.StopWithError(iris.StatusInternalServerError, err)
}
return
}
}
}

func simpleAssetHandler(ctx iris.Context) {
ctx.ServeFile("./public/main.js")
}
```

For some reason I don't understand, the returned page is blank. It's like something went wrong but I don't have any error message. At first, I thought it could be the use of `.Naive()` that was somehow messing it up. I thought maybe this method returns the original `ResponseWriter` which could mean : a copy of the original response-writer, before anything was written in it, instead of a pointer.

But then... This code works :

```golang
func main() {
app := iris.New()
app.Get("/", index)
app.Get("/main.js", simpleAssetHandler)

app.Run(iris.TLS(":443", "mycert.crt", "mykey.key"))
}

func index(ctx iris.Context) {
pushHandler(ctx)
ctx.HTML(``, target)
}
```

In my understanding, handlers are stacked the same way they are declared and then executed in this order. And since `iris.Context` is a pointer to `context.Context` calling a `func(iris.Context)` either in route declaration or in the handler attached to this route should be the same as both refer to the same object thx to pointers.

Could you help me with that? Am I missing something or is there something wrong?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.