Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: go-chi/chi
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v5.0.10
Choose a base ref
...
head repository: go-chi/chi
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v5.0.11
Choose a head ref
  • 17 commits
  • 26 files changed
  • 12 contributors

Commits on Aug 8, 2023

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    bfe3393 View commit details
  2. Go 1.21 in ci (#838)

    pkieltyka authored Aug 8, 2023
    Copy the full SHA
    1129e36 View commit details

Commits on Oct 18, 2023

  1. remove mute conversion from Router to *Mux (#863)

    Co-authored-by: TheRandomCharacter <TheRandomCharacter@users.noreply.github.com>
    TheRandomCharacter and TheRandomCharacter authored Oct 18, 2023
    Copy the full SHA
    f250983 View commit details
  2. Removes ambiguity around "fresh middleware stack" in GoDoc (#862)

    Co-authored-by: TheRandomCharacter <TheRandomCharacter@users.noreply.github.com>
    TheRandomCharacter and TheRandomCharacter authored Oct 18, 2023
    Copy the full SHA
    834f94d View commit details
  3. Copy the full SHA
    779d661 View commit details
  4. Copy the full SHA
    355dd04 View commit details

Commits on Oct 19, 2023

  1. fix: #846 (#847)

    AthfanFasee authored Oct 19, 2023
    Copy the full SHA
    f4ab9b1 View commit details
  2. Copy the full SHA
    3954a76 View commit details
  3. Copy the full SHA
    247397c View commit details
  4. Copy the full SHA
    ecd1897 View commit details
  5. Copy the full SHA
    9920283 View commit details

Commits on Oct 21, 2023

  1. Copy the full SHA
    beeb541 View commit details

Commits on Oct 22, 2023

  1. Copy the full SHA
    58ca6d6 View commit details

Commits on Dec 17, 2023

  1. Copy the full SHA
    2452954 View commit details

Commits on Dec 20, 2023

  1. Copy the full SHA
    9dd8b4a View commit details
  2. Create SECURITY.md

    pkieltyka authored Dec 20, 2023
    Copy the full SHA
    87caec0 View commit details
  3. v5.0.11

    pkieltyka committed Dec 20, 2023
    Copy the full SHA
    fcdb132 View commit details
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -21,18 +21,20 @@ jobs:

strategy:
matrix:
go-version: [1.15.x, 1.16.x, 1.17.x, 1.18.x, 1.19.x, 1.20.x]
go-version: [1.15.x, 1.16.x, 1.17.x, 1.18.x, 1.19.x, 1.20.x, 1.21.x]
os: [ubuntu-latest, windows-latest]

runs-on: ${{ matrix.os }}

steps:
- name: Install Go
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
check-latest: true
cache: false
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: ${{ env.GOPATH }}/src/github.com/${{ github.repository }}
- name: Test
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Changelog

## v5.0.11 (2023-12-19)

- History of changes: see https://github.com/go-chi/chi/compare/v5.0.10...v5.0.11


## v5.0.10 (2023-07-13)

- Fixed small edge case in tests of v5.0.9 for older Go versions
- History of changes: see https://github.com/go-chi/chi/compare/v5.0.8...v5.0.10
- History of changes: see https://github.com/go-chi/chi/compare/v5.0.9...v5.0.10


## v5.0.9 (2023-07-13)
@@ -306,7 +311,7 @@ Cheers all, happy coding!
request-scoped values. We're very excited about the new context addition and are proud to
introduce chi v2, a minimal and powerful routing package for building large HTTP services,
with zero external dependencies. Chi focuses on idiomatic design and encourages the use of
stdlib HTTP handlers and middlwares.
stdlib HTTP handlers and middlewares.
- chi v2 deprecates its `chi.Handler` interface and requires `http.Handler` or `http.HandlerFunc`
- chi v2 stores URL routing parameters and patterns in the standard request context: `r.Context()`
- chi v2 lower-level routing context is accessible by `chi.RouteContext(r.Context()) *chi.Context`,
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -494,7 +494,7 @@ Copyright (c) 2015-present [Peter Kieltyka](https://github.com/pkieltyka)

Licensed under [MIT License](./LICENSE)

[GoDoc]: https://pkg.go.dev/github.com/go-chi/chi?tab=versions
[GoDoc]: https://pkg.go.dev/github.com/go-chi/chi/v5
[GoDoc Widget]: https://godoc.org/github.com/go-chi/chi?status.svg
[Travis]: https://travis-ci.org/go-chi/chi
[Travis Widget]: https://travis-ci.org/go-chi/chi.svg?branch=master
5 changes: 5 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Reporting Security Issues

We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.

To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/go-chi/chi/security/advisories/new) tab.
21 changes: 8 additions & 13 deletions _examples/fileserver/main.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
//
// FileServer
// ===========
// This example demonstrates how to serve static files from your filesystem.
//
//
// Boot the server:
// ----------------
// $ go run main.go
//
// $ go run main.go
//
// Client requests:
// ----------------
// $ curl http://localhost:3333/files/
// <pre>
// <a href="notes.txt">notes.txt</a>
// </pre>
//
// $ curl http://localhost:3333/files/notes.txt
// Notessszzz
// $ curl http://localhost:3333/files/
// <pre>
// <a href="notes.txt">notes.txt</a>
// </pre>
//
// $ curl http://localhost:3333/files/notes.txt
// Notessszzz
package main

import (
14 changes: 4 additions & 10 deletions _examples/limits/main.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
//
// Limits
// ======
// This example demonstrates the use of Timeout, and Throttle middlewares.
//
// Timeout:
// cancel a request if processing takes longer than 2.5 seconds,
// server will respond with a http.StatusGatewayTimeout.
//
// Throttle:
// limit the number of in-flight requests along a particular
// routing path and backlog the others.
// Timeout: cancel a request if processing takes longer than 2.5 seconds,
// server will respond with a http.StatusGatewayTimeout.
//
// Throttle: limit the number of in-flight requests along a particular
// routing path and backlog the others.
package main

import (
142 changes: 4 additions & 138 deletions _examples/logging/main.go
Original file line number Diff line number Diff line change
@@ -1,143 +1,9 @@
// Custom Structured Logger
// ========================
// This example demonstrates how to use middleware.RequestLogger,
// middleware.LogFormatter and middleware.LogEntry to build a structured
// logger using the preview version of the new log/slog package as the logging
// backend.
//
// Also: check out https://github.com/goware/httplog for an improved context
// logger with support for HTTP request logging, based on the example below.
package main

import (
"fmt"
"net/http"
"os"
"time"

"golang.org/x/exp/slog"

"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
// Please see https://github.com/go-chi/httplog for a complete package
// and example for writing a structured logger on chi built on
// the Go 1.21+ "log/slog" package.

func main() {
// Setup a JSON handler for the new log/slog library
slogJSONHandler := slog.HandlerOptions{
// Remove default time slog.Attr, we create our own later
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
if a.Key == slog.TimeKey {
return slog.Attr{}
}
return a
},
}.NewJSONHandler(os.Stdout)

// Routes
r := chi.NewRouter()
r.Use(middleware.RequestID)
r.Use(NewStructuredLogger(slogJSONHandler))
r.Use(middleware.Recoverer)

r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("welcome"))
})
r.Get("/wait", func(w http.ResponseWriter, r *http.Request) {
time.Sleep(1 * time.Second)
LogEntrySetField(r, "wait", true)
w.Write([]byte("hi"))
})
r.Get("/panic", func(w http.ResponseWriter, r *http.Request) {
panic("oops")
})
r.Get("/add_fields", func(w http.ResponseWriter, r *http.Request) {
LogEntrySetFields(r, map[string]interface{}{"foo": "bar", "bar": "foo"})
})
http.ListenAndServe(":3333", r)
}

// StructuredLogger is a simple, but powerful implementation of a custom structured
// logger backed on log/slog. I encourage users to copy it, adapt it and make it their
// own. Also take a look at https://github.com/go-chi/httplog for a dedicated pkg based
// on this work, designed for context-based http routers.

func NewStructuredLogger(handler slog.Handler) func(next http.Handler) http.Handler {
return middleware.RequestLogger(&StructuredLogger{Logger: handler})
}

type StructuredLogger struct {
Logger slog.Handler
}

func (l *StructuredLogger) NewLogEntry(r *http.Request) middleware.LogEntry {
var logFields []slog.Attr
logFields = append(logFields, slog.String("ts", time.Now().UTC().Format(time.RFC1123)))

if reqID := middleware.GetReqID(r.Context()); reqID != "" {
logFields = append(logFields, slog.String("req_id", reqID))
}

scheme := "http"
if r.TLS != nil {
scheme = "https"
}

handler := l.Logger.WithAttrs(append(logFields,
slog.String("http_scheme", scheme),
slog.String("http_proto", r.Proto),
slog.String("http_method", r.Method),
slog.String("remote_addr", r.RemoteAddr),
slog.String("user_agent", r.UserAgent()),
slog.String("uri", fmt.Sprintf("%s://%s%s", scheme, r.Host, r.RequestURI))))

entry := StructuredLoggerEntry{Logger: slog.New(handler)}

entry.Logger.LogAttrs(slog.LevelInfo, "request started")

return &entry
}

type StructuredLoggerEntry struct {
Logger *slog.Logger
}

func (l *StructuredLoggerEntry) Write(status, bytes int, header http.Header, elapsed time.Duration, extra interface{}) {
l.Logger.LogAttrs(slog.LevelInfo, "request complete",
slog.Int("resp_status", status),
slog.Int("resp_byte_length", bytes),
slog.Float64("resp_elapsed_ms", float64(elapsed.Nanoseconds())/1000000.0),
)
}

func (l *StructuredLoggerEntry) Panic(v interface{}, stack []byte) {
l.Logger.LogAttrs(slog.LevelInfo, "",
slog.String("stack", string(stack)),
slog.String("panic", fmt.Sprintf("%+v", v)),
)
}

// Helper methods used by the application to get the request-scoped
// logger entry and set additional fields between handlers.
//
// This is a useful pattern to use to set state on the entry as it
// passes through the handler chain, which at any point can be logged
// with a call to .Print(), .Info(), etc.

func GetLogEntry(r *http.Request) *slog.Logger {
entry := middleware.GetLogEntry(r).(*StructuredLoggerEntry)
return entry.Logger
}

func LogEntrySetField(r *http.Request, key string, value interface{}) {
if entry, ok := r.Context().Value(middleware.LogEntryCtxKey).(*StructuredLoggerEntry); ok {
entry.Logger = entry.Logger.With(key, value)
}
}

func LogEntrySetFields(r *http.Request, fields map[string]interface{}) {
if entry, ok := r.Context().Value(middleware.LogEntryCtxKey).(*StructuredLoggerEntry); ok {
for k, v := range fields {
entry.Logger = entry.Logger.With(k, v)
}
}
// See https://github.com/go-chi/httplog/blob/master/_example/main.go
}
40 changes: 18 additions & 22 deletions _examples/rest/main.go
Original file line number Diff line number Diff line change
@@ -1,42 +1,38 @@
//
// REST
// ====
// This example demonstrates a HTTP REST web service with some fixture data.
// Follow along the example and patterns.
//
// Also check routes.json for the generated docs from passing the -routes flag,
// to run yourself do: `go run . -routes`
//
// Boot the server:
// ----------------
// $ go run main.go
//
// $ go run main.go
//
// Client requests:
// ----------------
// $ curl http://localhost:3333/
// root.
//
// $ curl http://localhost:3333/articles
// [{"id":"1","title":"Hi"},{"id":"2","title":"sup"}]
// $ curl http://localhost:3333/
// root.
//
// $ curl http://localhost:3333/articles/1
// {"id":"1","title":"Hi"}
// $ curl http://localhost:3333/articles
// [{"id":"1","title":"Hi"},{"id":"2","title":"sup"}]
//
// $ curl -X DELETE http://localhost:3333/articles/1
// {"id":"1","title":"Hi"}
// $ curl http://localhost:3333/articles/1
// {"id":"1","title":"Hi"}
//
// $ curl http://localhost:3333/articles/1
// "Not Found"
// $ curl -X DELETE http://localhost:3333/articles/1
// {"id":"1","title":"Hi"}
//
// $ curl -X POST -d '{"id":"will-be-omitted","title":"awesomeness"}' http://localhost:3333/articles
// {"id":"97","title":"awesomeness"}
// $ curl http://localhost:3333/articles/1
// "Not Found"
//
// $ curl http://localhost:3333/articles/97
// {"id":"97","title":"awesomeness"}
// $ curl -X POST -d '{"id":"will-be-omitted","title":"awesomeness"}' http://localhost:3333/articles
// {"id":"97","title":"awesomeness"}
//
// $ curl http://localhost:3333/articles
// [{"id":"2","title":"sup"},{"id":"97","title":"awesomeness"}]
// $ curl http://localhost:3333/articles/97
// {"id":"97","title":"awesomeness"}
//
// $ curl http://localhost:3333/articles
// [{"id":"2","title":"sup"},{"id":"97","title":"awesomeness"}]
package main

import (
4 changes: 0 additions & 4 deletions _examples/todos-resource/main.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
//
// Todos Resource
// ==============
// This example demonstrates a project structure that defines a subrouter and its
// handlers on a struct, and mounting them as subrouters to a parent router.
// See also _examples/rest for an in-depth example of a REST service, and apply
// those same patterns to this structure.
//
package main

import (
6 changes: 1 addition & 5 deletions _examples/versions/main.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
//
// Versions
// ========
// This example demonstrates the use of the render subpackage, with
// a quick concept for how to support multiple api versions.
//
package main

import (
@@ -118,7 +114,7 @@ func getArticle(w http.ResponseWriter, r *http.Request) {
}

// Simulate some context values:
// 1. ?auth=true simluates authenticated session/user.
// 1. ?auth=true simulates authenticated session/user.
// 2. ?error=true simulates random error.
if r.URL.Query().Get("auth") != "" {
r = r.WithContext(context.WithValue(r.Context(), "auth", true))
Loading