Skip to content

Commit

Permalink
revert prev commit changes and upload an example for #9
Browse files Browse the repository at this point in the history
  • Loading branch information
kataras committed Jul 23, 2020
1 parent 7eb75ba commit 88a0a6c
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 62 deletions.
47 changes: 47 additions & 0 deletions _examples/12_push/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Server push lets the server preemptively "push" website assets
// to the client without the user having explicitly asked for them.
// When used with care, we can send what we know the user is going
// to need for the page they're requesting.
package main

import (
"fmt"
"net/http"

"github.com/kataras/muxie"
)

func main() {
mux := muxie.NewMux()
mux.HandleFunc("/", pushHandler)
mux.HandleFunc("/main.js", simpleAssetHandler)

http.ListenAndServeTLS(":443", "mycert.crt", "mykey.key", mux)
}

func pushHandler(w http.ResponseWriter, r *http.Request) {
// 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 := w.(*muxie.Writer).ResponseWriter.(http.Pusher); ok {
err := pusher.Push(target, nil)
if err != nil {
if err == http.ErrNotSupported {
http.Error(w, "HTTP/2 push not supported", http.StatusHTTPVersionNotSupported)
} else {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
return
}
}

w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, `<html><body><script src="%s"></script></body></html>`, target)
}

func simpleAssetHandler(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./public/main.js")
}
31 changes: 31 additions & 0 deletions _examples/12_push/mycert.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIUfwMd9auWixp19UnXOmyxJ9Jkv7IwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA2MjUwOTUxNDdaFw0yMTA2
MjUwOTUxNDdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQDlVGyGAQ9uyfNbwZyrtYOSjLpxf5NpNToh2OzU7gy2
OexBji5lmWBQ3oYDG+FjAkbHORPzOMNpeMwje+IjGZBw8x6E+8WoGdSzbrEZ6pUV
wKJGKEuDlx6g6HEmtv3ZwgGe20gvPjjW+oCO888dwK/mbIHrHTq4nO3o0gAdAJwu
amn9BlHU5O4RW7BQ4tLF+j/fBCACWRG1NHXA0AT8eg544GyCdyteAH11oCDsHS8/
DAPsM6t+tZrMCIt9+9dzPdVoOmQNaMMrcz8eJohddRTK6zHe9ixZTt/soayOF7OS
QQeekbr3HPYhD450zRVplLMHx7wnph/+O+Po6bqDnUzdnkqAAwwymQapHMuHXZKN
rhdfKau3rVo1GeXLIRgeWLUoxFSm4TYshrgt+0AidLRH+dCY7MS9Ngga/sAK3vID
gSF75mFgOhY+q7nvY9Ecao6TnoNNRY29hUat4y0VwSyysUy887vHr6lMK5CrAT/l
Ch8fuu20HUCoiLwMJvA6+wpivZkuiIvWY7bVGYsEYrrW+bCNN9wCGYTZEyX++os9
v/38wdOqGUT00ewXkjIUFCWbrnxxSr98kF3w3wPf9K4Y40MNxeR90nyX4zjXGF1/
91msUh+iivsz9mcN9DK83fgTyOsoVLX5cm/L2UBwMacsfjBbN4djOc5IuYMar/VN
GQIDAQABo1MwUTAdBgNVHQ4EFgQUtkf+yAvqgZC8f22iJny9hFEDolMwHwYDVR0j
BBgwFoAUtkf+yAvqgZC8f22iJny9hFEDolMwDwYDVR0TAQH/BAUwAwEB/zANBgkq
hkiG9w0BAQsFAAOCAgEAE2QasBVru618rxupyJgEHw6r4iv7sz1Afz3Q5qJ4oSA9
xVsrVCjr3iHRFSw8Rf670E8Ffk/JjzS65mHw6zeZj/ANBKQWLjRlqzYXeetq5HzG
SIgaG7p1RFvvzz3+leFGzjinZ6sKbfB4OB72o2YN+fO8DsDxgGKll0W4KAazizSe
HY9Pgu437tWnwF16rFO3IL47n5HzYlRoGIPOpzFoNX5+fyn9GlnKEtONF2QBKTjY
rdjvqFRByDiC74d8z/Yx8IiDRn1mTcG90JLR9+c6M7fruha9Y/rJfw+4AhVh5ZDz
Bl9rGPjwEs5zwutYvVAJzs7AVcighYP1lHKoJ7DxBDQeyBsYlUNk2l6bmZgLgGUZ
+2OyWlqc/jD2GdDsIaZ4i7QqhTI/6aYZIf5zUkblKV1aMSaDulKxRv//OwW28Jax
9EEoV7VaFb3sOkB/tZGhusXeQVtdrhahT3KkZLNwmNXoXWKJ5LjeUlFWJyV6JbDe
y/PIWWCwWqyuFCSZS+Cg3RDgAzfSxkI8uVZ+IKKJS3UluDX45lxXtbRrvTQ+oDrA
6ga5c1Vz9C4kn1K5yW4d7QIvg6vPiy7gvl+//sz9oxUM3yswInDBY0HKLgT0Uq9b
YzLDh2RSaHsgHMPy2BKqR+q2N+lpg7inAWuJM1Huq6eHFqhiyQkzsfscBd1Dpm8=
-----END CERTIFICATE-----
52 changes: 52 additions & 0 deletions _examples/12_push/mykey.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDlVGyGAQ9uyfNb
wZyrtYOSjLpxf5NpNToh2OzU7gy2OexBji5lmWBQ3oYDG+FjAkbHORPzOMNpeMwj
e+IjGZBw8x6E+8WoGdSzbrEZ6pUVwKJGKEuDlx6g6HEmtv3ZwgGe20gvPjjW+oCO
888dwK/mbIHrHTq4nO3o0gAdAJwuamn9BlHU5O4RW7BQ4tLF+j/fBCACWRG1NHXA
0AT8eg544GyCdyteAH11oCDsHS8/DAPsM6t+tZrMCIt9+9dzPdVoOmQNaMMrcz8e
JohddRTK6zHe9ixZTt/soayOF7OSQQeekbr3HPYhD450zRVplLMHx7wnph/+O+Po
6bqDnUzdnkqAAwwymQapHMuHXZKNrhdfKau3rVo1GeXLIRgeWLUoxFSm4TYshrgt
+0AidLRH+dCY7MS9Ngga/sAK3vIDgSF75mFgOhY+q7nvY9Ecao6TnoNNRY29hUat
4y0VwSyysUy887vHr6lMK5CrAT/lCh8fuu20HUCoiLwMJvA6+wpivZkuiIvWY7bV
GYsEYrrW+bCNN9wCGYTZEyX++os9v/38wdOqGUT00ewXkjIUFCWbrnxxSr98kF3w
3wPf9K4Y40MNxeR90nyX4zjXGF1/91msUh+iivsz9mcN9DK83fgTyOsoVLX5cm/L
2UBwMacsfjBbN4djOc5IuYMar/VNGQIDAQABAoICAQCtWx1SSxjkcerxsLEDKApW
zOTfiUXgoOjZz0ZwS6b2VWDfyWAPU1r4ps39KaU+F+lzDhWjpYQqhbMjG7G9QMTs
bQvkEQLAaQ5duU5NPgQG1oCUsj8rMSBpGGz4jBnm834QHMk7VTjYYbKu3WTyo8cU
U2/+UDEkfxRlC+IkCmMFv1FxgMZ5PbktC/eDnYMhP2Pq7Q5ZWAVHymk9IMK0LHwm
Kdg842K4A3zTXwGkGwetDCMm+YQpG5TxqX/w82BRcCuTR5h8fnYSsWLEIvKwWyIl
ppcjaUnrFPG2yhxLqWUIKPpehuEjjhQMt9rDNoh6MHsJZZY5Dp5eq91EIvLoLQ99
hXBmD4P8LDop4r0jniPZJi/ACsaD0jBooA4525+Kouq7RP28Jp/pek7lVOOcBgRv
D3zyESbKfqoaOfyfQ2ff4sILnTAr4V2nq3ekphGEYJrWN0ZoADcLdnr1cZ8L+VBI
o/4mi5/3HID/UEDliHSa97hxxGBEqTto0ZuXuNwfwx5ho33uVT6zNwRgiJ62Bgu3
Fhk/wVGuZxWvb1KHUNInG9cvsslhO4Vu9wJvYj91BnRq36rsyKKid5DrU+PNgmog
lw3IXQpTojyRCYPuG9TKqEZ6b+so7GTKhBOjiwaupMOletVRGSAdbE81VN6HtxNW
aj39+FnxzMAlsieib+PBAQKCAQEA+t1fOYSaZBo7pZUmo2S0zulUEJjrYRGKJlWJ
4psWSwFu/7/3UL4q0RBQaSRew9u/YSpaNlBYfcpnFVOjiLwHq5Hx46Eq0BuKsNlJ
1/qxw9qjHqcrOre6K4/7NaWLPuM9fEmV+3MhFVXgv+WC5BHOowRTlOG30vIcC1J2
L5xsBUsxDDY13cD1bLKRmFcyMFM8y7wMZmo7H/WfVmyoPKQaC43pTcmIXH0Jr2Ws
Wsfh18mhjtamaOPEFx5K0x4d0PI8tW5ouiUUkVIDaue27XfS969qEChv768/44eX
WeqcekaG9jv2noMClt79rYd3Lne9HkgY6IT9FT+JqXfu+KYwuQKCAQEA6gYzUsGB
9GQO8DE8AYn7JwNOtg1X4zKakXiGxH+nuZb7wJjAeGdYqTHySxPBXg0A2nDwoyz5
4sAdLAr3FZoIvTzo7M5KIKFDzfyDmQDavhroH1mBAEiqKGNniP+RND3nWBBqDK1R
qcqbhI3Kj5Ycany6a4nP+hZRBIyT9sfJ0S0YruSY8IGXgDwhlJrZ7bsWMZylrgD/
1qnPL0KqVBY8YR8msRj88h72IlD5o0kwvisOIvyhA0YgwGBb6lg7A+DifiF03ZlS
2yELbIkKDVr+p3jC7MBh4B+OJY68AMl6wVjAaDM1AZnpjKE5YmZg5+Ks5823zILo
PrSB9hn0+DIPYQKCAQEAh9x+JuNmzhHa/dkiHNl8hpadHYQD7gUWwZ4P1/bQAv0a
xU2MvmDPRXxFYDv/SqlnI1NRmhq3YiDM5SLv7SyQJt4al4IAcsaHvTFgqaSuw3hU
YVR9uAYqwE7w6OPn3r4o3Xfoz05Ru4FP//1nfucZ9vVv4rC/4nGWuJcHRM+9PLy1
KnztfVR0VlL7QPrwRnW99kS4nnqn3K4khiTAlF73cAyCLsuXmydoqGIzDtMzv68G
XRpo82NvHmoccevcj/2w3T2XYECWvAEjsrEdQ8xiKBwLIAcWYEOUIUCcumiyKBKs
IwzkioI/U8AeuO0lobfdZ1n6i2sCuZA4mNxIQseWmQKCAQEA5YkfXdQeuq5JWJ1x
1bCYfjNoSHfd9CH2KSimRqVOxWGpm8Y3QeFbvNgYZjsCNlVauOZ9oA7FKfp0onY+
0xk56SKM83eCjW6fKrK6AKAt7LhHZDhNpxGek+6r5luE+FCfUGkJG1YD+x2WW/UW
8K6zQF8GGeQZ8Zlh7axUlIBxGpG43BGrUHpLNqPD7BXWGq6dnhufBYRFay8y34/r
sH3+yuPa92ki7/geQppZwCZRgLSKMRbIdoWaKhZZEQlpGOzCOiRmk9OGyRcoNVRU
X7UYgPqZdc1cMo/AxGWzULJNjMaYMZvIKcHkqOKZfkIcWlSictn7pMPhN1+k+NWM
yMORAQKCAQAyXl02h/c2ihx6cjKlnNeDr2ZfzkoiAvFuKaoAR+KVvb9F9X7ZgKSi
wudZyelTglIVCYXeRmG09uX3rNGCzFrweRwgn6x/8DnN5pMRJVZOXFdgR+V9uKep
K6F7DYbPyggvLOAsezB+09i9lwxM+XdA2whVpL5NFR1rGfFglnE1EQHcEvNONkcv
0h8x9cNSptJyRDLiTIKI9EhonuzwzkGpvjULQE8MLbT8PbjoLFINcE9ZWhwtyw0V
XO32KE8iLKt3KzHz9CfTRCI3M7DwD752AC6zRr8ZS/HXzs+5WTkdVVEtRC7Abd3y
W2TzuSMYNDu876twbTVQJED3mwOAQ3J7
-----END PRIVATE KEY-----
1 change: 1 addition & 0 deletions _examples/12_push/public/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
window.alert("javascript loaded");
4 changes: 2 additions & 2 deletions mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func NewMux() *Mux {
Routes: NewTrie(),
paramsPool: &sync.Pool{
New: func() interface{} {
return &paramsWriter{}
return &Writer{}
},
},
root: "",
Expand Down Expand Up @@ -187,7 +187,7 @@ func (m *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// and it will be compatible with net/http will be introduced to store the params at least,
// we don't want to add a third parameter or a global state to this library.

pw := m.paramsPool.Get().(*paramsWriter)
pw := m.paramsPool.Get().(*Writer)
pw.reset(w)
n := m.Routes.Search(path, pw)
if n != nil {
Expand Down
67 changes: 9 additions & 58 deletions params_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import "net/http"
//
// The function will do its job only if the given "w" http.ResponseWriter interface is an `ResponseWriter`.
func GetParam(w http.ResponseWriter, key string) string {
if store, ok := w.(ResponseWriter); ok {
if store, ok := w.(*Writer); ok {
return store.Get(key)
}

Expand All @@ -22,7 +22,7 @@ func GetParam(w http.ResponseWriter, key string) string {
//
// The function will do its job only if the given "w" http.ResponseWriter interface is an `ResponseWriter`.
func GetParams(w http.ResponseWriter) []ParamEntry {
if store, ok := w.(ResponseWriter); ok {
if store, ok := w.(*Writer); ok {
return store.GetAll()
}

Expand All @@ -33,7 +33,7 @@ func GetParams(w http.ResponseWriter) []ParamEntry {
// This is not commonly used by the end-developers,
// unless sharing values(string messages only) between handlers is absolutely necessary.
func SetParam(w http.ResponseWriter, key, value string) bool {
if store, ok := w.(ResponseWriter); ok {
if store, ok := w.(*Writer); ok {
store.Set(key, value)
return true
}
Expand All @@ -47,37 +47,18 @@ type ParamEntry struct {
Value string
}

// ResponseWriter is the muxie's specific ResponseWriter to hold the path parameters.
// Writer is the muxie's specific ResponseWriter to hold the path parameters.
// Usage: use this to cast a handler's `http.ResponseWriter` and pass it as an embedded parameter to custom response writer
// that will be passed to the next handler in the chain.
type ResponseWriter interface {
type Writer struct {
http.ResponseWriter
http.Flusher
http.Pusher
http.Hijacker
http.CloseNotifier

ParamsSetter
Get(string) string
GetAll() []ParamEntry
}

type paramsWriter struct {
http.ResponseWriter
http.Flusher
http.Pusher
http.Hijacker
http.CloseNotifier

params []ParamEntry
}

var _ ResponseWriter = (*paramsWriter)(nil)

// Set implements the `ParamsSetter` which `Trie#Search` needs to store the parameters, if any.
// These are decoupled because end-developers may want to use the trie to design a new Mux of their own
// or to store different kind of data inside it.
func (pw *paramsWriter) Set(key, value string) {
func (pw *Writer) Set(key, value string) {
if ln := len(pw.params); cap(pw.params) > ln {
pw.params = pw.params[:ln+1]
p := &pw.params[ln]
Expand All @@ -93,7 +74,7 @@ func (pw *paramsWriter) Set(key, value string) {
}

// Get returns the value of the associated parameter based on its key/name.
func (pw *paramsWriter) Get(key string) string {
func (pw *Writer) Get(key string) string {
n := len(pw.params)
for i := 0; i < n; i++ {
if kv := pw.params[i]; kv.Key == key {
Expand All @@ -105,41 +86,11 @@ func (pw *paramsWriter) Get(key string) string {
}

// GetAll returns all the path parameters keys-values.
func (pw *paramsWriter) GetAll() []ParamEntry {
func (pw *Writer) GetAll() []ParamEntry {
return pw.params
}

func (pw *paramsWriter) reset(w http.ResponseWriter) {
func (pw *Writer) reset(w http.ResponseWriter) {
pw.ResponseWriter = w

flusher, ok := w.(http.Flusher)
if !ok {
flusher = nil // make sure interface value is nil.
}

pusher, ok := w.(http.Pusher)
if !ok {
pusher = nil
}

hijacker, ok := w.(http.Hijacker)
if !ok {
hijacker = nil
}

// This interface is obselete by Go authors
// and we only capture it
// for compatible reasons. End-developers SHOULD replace
// the use of CloseNotifier with the: Request.Context().Done() channel.
closeNotifier, ok := w.(http.CloseNotifier)
if !ok {
closeNotifier = nil
}

pw.Flusher = flusher
pw.Pusher = pusher
pw.Hijacker = hijacker
pw.CloseNotifier = closeNotifier

pw.params = pw.params[0:0]
}
2 changes: 1 addition & 1 deletion trie_benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func BenchmarkTrieInsert(b *testing.B) {
func BenchmarkTrieSearch(b *testing.B) {
tree := NewTrie()
initTree(tree)
params := new(paramsWriter)
params := new(Writer)

b.ReportAllocs()
b.ResetTimer()
Expand Down
2 changes: 1 addition & 1 deletion trie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func testTrie(t *testing.T, oneByOne bool) {
if oneByOne {
tree.insert(tt.key, tt.routeName, nil, nil)
}
params := new(paramsWriter)
params := new(Writer)
for reqIdx, req := range tt.requests {
params.reset(nil)
n := tree.Search(req.path, params)
Expand Down

0 comments on commit 88a0a6c

Please sign in to comment.