# HTTP/2 Push + Embedded + Cache and Compression

Welcome to the File Server section that can boost your web application's performance to the next level. Enable HTTP/2 **Push**, serve **embedded** files with their **compressed** contents pre-**cached**.

This is a unique feature that you won't find in any other backend web framework as of 2023.

> Please read the previous File Server's sections first and read the [Introduction to HTTP/2](https://developers.google.com/web/fundamentals/performance/http2) by Google LLC to learn about the benefits of using HTTP/2.

## Introduction

The `DirOptions` contains the `PushTargets` and `PushTargetsRegexp` fields to enable and customize automatic push assets (css, javascript, images) of Index pages.

The `PushTargets` field is a map of filenames to be served without additional client's requests (HTTP/2 Push) when a specific request relative path hits an Index.

Example, to serve a specific favicon, javascript and css assets when the client hits the root path *(and /index.html*):

```go
var opts = iris.DirOptions{
    IndexName: "index.html",
    PushTargets: map[string][]string{
        "/": {
            "favicon.ico",
            "js/main.js",
            "css/main.css",
        },
    },
}

app.HandleDir("/", iris.Dir("./assets"), opts)
```

Alternatively the `PushTargetsRegexp` field can be used instead (recommended), to automatically serve common assets based on a regular expression:

```go
var opts = iris.DirOptions{
    IndexName: "index.html",
    PushTargetsRegexp: map[string]*regexp.Regexp{
        "/": iris.MatchCommonAssets,
    },
}

app.HandleDir("/", iris.Dir("./assets"), opts)
```

> The `iris.MatchCommonAssets` is just a regular expression which matches javascript, css, ico, png, ttf, svg, webp and gif file types.

## Example

We've learn about Embedded files, Memory Cache (with pre-compressed contents) and Push Targets. Now it is time to combine all prior knowedge we got from this File Server chapter to create and run a simple web server which serves index files and their assets pushed through HTTP/2, both index and assets will be served from memory cache and pre-compressed contents will be written to the clients based on their accepted content encoding header.

We will use both **go-bindata and Iris Memory Cache** to serve **pre-compressed** data from **embedded** files of our executable Program. The assets directory of this exercise can be found [here](https://github.com/kataras/iris/tree/main/_examples/file-server/http2push/assets). In the end, we'll need to deploy just the executable file(and the generated tls keys, although you can pass [public and private key Go generated values](https://github.com/kataras/iris/blob/e41e861c4c0d9be9dd4c88f7e06c2732b52ba60d/core/host/supervisor.go#L278-L281) there as well), assets phyisical folder is not required after forth step.

**1.** Create a directory to host the Iris web server.

**1.** This web server SHOULD be served under TLS in order for HTTP/2 Push to work. Generate keys for your local web server. For the sake of simplicity, in this example we will use the [mycert.crt](https://raw.githubusercontent.com/kataras/iris/main/_examples/file-server/http2push/mycert.crt) and [mykey.key](https://raw.githubusercontent.com/kataras/iris/main/_examples/file-server/http2push/mykey.key) files. Place them inside the project's folder.

**2.** Download the example [assets folder](https://github.com/kataras/iris/tree/main/_examples/file-server/http2push/assets) and place it to the project's folder.

**3.** Install go bindata, open and terminal and execute the following command:

```sh
$ go get -u github.com/go-bindata/go-bindata/...
```

**4.** Use go-bindata to generate a compatible `http.FileServer` to pass into `Party.HandleDir`:

```sh
$ go-bindata -nomemcopy -fs -prefix "assets" ./assets/...
```

**5.** Create a `main.go` file and copy-paste the following code:

```go
package main

import (
	"regexp"

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

var opts = iris.DirOptions{
	IndexName: "index.html",
	PushTargetsRegexp: map[string]*regexp.Regexp{
		"/":              iris.MatchCommonAssets,
		"/app2/app2app3": iris.MatchCommonAssets,
	},
	ShowList: true,
	Cache: iris.DirCacheOptions{
		Enable:         true,
		CompressIgnore: iris.MatchImagesAssets,
		Encodings:       []string{"gzip", "deflate", "br", "snappy"},
        // Compress files equal or larger than 50 bytes.
        CompressMinSize: 50,
		Verbose:         1,
	},
}

func main() {
	app := iris.New()
	app.HandleDir("/public", AssetFile(), opts)
	app.Run(iris.TLS(":443", "mycert.crt", "mykey.key"))
}
```

**6.** Open a terminal and execute `go build` or `go run .`

**7.** Open a browser or use any http client and navigate through:

* <https://127.0.0.1/public>
* <https://127.0.0.1/public/app2>
* <https://127.0.0.1/public/app2/app2app3>
* <https://127.0.0.1/public/app2/app2app3/dirs>

That's all.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://iris-go.gitbook.io/iris/file-server/http2push-embedded-compression.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
