Skip to content

Commit

Permalink
Merge branch 'master' into v1
Browse files Browse the repository at this point in the history
  • Loading branch information
kataras committed Dec 5, 2019
2 parents e00a337 + ee2fdec commit c1c3728
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 25 deletions.
19 changes: 7 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
<strong>Fast trie implementation designed from scratch specifically for HTTP</strong>
</div>
<div align="center">
A <code>small and light</code> router for creating sturdy backend <a href="https://golang.org" alt="Go Programming Language">Go</a> applications
A <code>small and light</code> router for creating sturdy backend <a href="https://golang.org" alt="Go Programming Language">Go</a> applications. Production-level tested, muxie's capabilities live inside the well-tested <a href="https://iris-go.com">Iris </a> web framework.
</div>

<br />

<div align="center">
<!-- Release -->
<a href="https://github.com/kataras/muxie/releases">
<img src="https://img.shields.io/badge/release%20-v1.0.7-0077b3.svg?style=flat-squaree"
<img src="https://img.shields.io/badge/release%20-v1.0.8-0077b3.svg?style=flat-squaree"
alt="Release/stability" />
</a>
<!-- Godocs -->
Expand Down Expand Up @@ -51,17 +51,10 @@
</div>

[![Benchmark chart between muxie, httprouter, gin, gorilla mux, echo, vestigo and chi](_benchmarks/chart-17-oct-2018.png)](_benchmarks)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fkataras%2Fmuxie.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fkataras%2Fmuxie?ref=badge_shield)

_Last updated on October 17, 2018._ Click [here](_benchmarks/README.md) to read more details.

### Third-party source benchmarks

[![](https://github.com/kataras/iris/raw/master/_benchmarks/benchmarks_third_party_source_snapshot_go_23_october_2018.png)](https://github.com/the-benchmarker/web-frameworks#full-table)

As shown in the benchmarks (from a [third-party source](https://github.com/the-benchmarker)), Muxie is much faster than its alternatives out there with amazing performance, fastest net/http router ever created so far. View the results and read further details [here](https://github.com/the-benchmarker/web-frameworks/tree/934fdf16e13a1a922ee88e873ae76f28f52c189f#full-table).

_Last updated on October 23, 2018._

## Features

- __trie based:__ [performance](_benchmarks/README.md) and useness are first class citizens, Muxie is based on the prefix tree data structure, designed from scratch and built for HTTP, and it is among the fastest outhere, if not the fastest one
Expand All @@ -73,7 +66,7 @@ _Last updated on October 23, 2018._

## Technical Features

- [x] Closest Wildcard Resolution and Root wildcard (CWR)[*](_examples/3_root_wildcard_and_custom-404/main.go)
- [x] Closest Wildcard Resolution and Root wildcard (CWR)[*](_examples/3_root_wildcard_and_custom_404/main.go)
- [x] Parameterized Dynamic Path (named parameters with `:name` and wildcards with `*name`, can play all together for the same path prefix|suffix)[*](_examples/2_parameterized/main.go)
- [x] Standard handlers chain (`Pre(handlers).For(mainHandler)` for individual routes and `Mux#Use` for router)[*](_examples/6_middleware/main.go)
- [x] Register handlers by method(s) (`muxie.Methods()`)[*](_examples/7_by_methods/main.go)
Expand Down Expand Up @@ -128,4 +121,6 @@ Gerasimos Maropoulos ([@MakisMaropoulos](https://twitter.com/MakisMaropoulos))

## License

[MIT](https://tldrlegal.com/license/mit-license)
[MIT](https://tldrlegal.com/license/mit-license)

[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fkataras%2Fmuxie.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fkataras%2Fmuxie?ref=badge_large)
4 changes: 2 additions & 2 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ Source code and other details for the project are available at GitHub:
Current Version
1.0.7
1.0.8
Installation
The only requirement is the Go Programming Language
$ go get -u github.com/kataras/muxie
$ go get github.com/kataras/muxie
Examples
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
module github.com/kataras/muxie

go 1.13
12 changes: 2 additions & 10 deletions mux.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package muxie

import (
"html"
"io"
"net/http"
"strings"
"sync"
Expand Down Expand Up @@ -63,7 +61,7 @@ func (m *Mux) AddRequestHandler(requestHandler RequestHandler) {
m.requestHandlers = append(m.requestHandlers, requestHandler)
}

// HandleRequest adds a matcher and a (conditinal) handler to be executed when "matcher" passed.
// HandleRequest adds a matcher and a (conditional) handler to be executed when "matcher" passed.
// If the "matcher" passed then the "handler" will be executed
// and this Mux' routes will be ignored.
//
Expand Down Expand Up @@ -168,14 +166,8 @@ func (m *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
return
}
http.Redirect(w, r, url, http.StatusMovedPermanently)

// RFC2616 recommends that a short note "SHOULD" be included in the
// response because older user agents may not understand 301/307.
// Shouldn't send the response for POST or HEAD; that leaves GET.
if method == http.MethodGet {
io.WriteString(w, "<a href=\""+html.EscapeString(url)+"\">Moved Permanently</a>.\n")
}
http.Redirect(w, r, url, http.StatusMovedPermanently)
return
}
}
Expand Down
35 changes: 34 additions & 1 deletion mux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,51 @@ import (
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
)

func expect(t *testing.T, method, url string) *testie {
func expect(t *testing.T, method, url string, testieOptions ...func(*http.Request)) *testie {
req, err := http.NewRequest(method, url, nil)
if err != nil {
t.Fatal(err)
}

for _, opt := range testieOptions {
opt(req)
}

return testReq(t, req)
}

func withHeader(key string, value string) func(*http.Request) {
return func(r *http.Request) {
r.Header.Add(key, value)
}
}

func withURLParam(key string, value string) func(*http.Request) {
return func(r *http.Request) {
r.URL.Query().Add(key, value)
}
}

func withFormField(key string, value string) func(*http.Request) {
return func(r *http.Request) {
if r.Form == nil {
r.Form = make(url.Values)
}
r.Form.Add(key, value)

enc := strings.NewReader(r.Form.Encode())
r.Body = ioutil.NopCloser(enc)
r.ContentLength = int64(enc.Len())

r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
}
}

func expectWithBody(t *testing.T, method, url string, body string, headers http.Header) *testie {
req, err := http.NewRequest(method, url, bytes.NewBufferString(body))
if err != nil {
Expand Down
22 changes: 22 additions & 0 deletions params_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,25 @@ func (pw *paramsWriter) reset(w http.ResponseWriter) {
pw.ResponseWriter = w
pw.params = pw.params[0:0]
}

// Flusher indicates if `Flush` is supported by the client.
//
// The default HTTP/1.x and HTTP/2 ResponseWriter implementations
// support Flusher, but ResponseWriter wrappers may not. Handlers
// should always test for this ability at runtime.
//
// Note that even for ResponseWriters that support Flush,
// if the client is connected through an HTTP proxy,
// the buffered data may not reach the client until the response
// completes.
func (pw *paramsWriter) Flusher() (http.Flusher, bool) {
flusher, canFlush := pw.ResponseWriter.(http.Flusher)
return flusher, canFlush
}

// Flush sends any buffered data to the client.
func (pw *paramsWriter) Flush() {
if flusher, ok := pw.Flusher(); ok {
flusher.Flush()
}
}

0 comments on commit c1c3728

Please sign in to comment.