-
-
Notifications
You must be signed in to change notification settings - Fork 993
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(middleware): add sunset/deprecation header middleware (#844)
- Loading branch information
1 parent
f4ab9b1
commit 3954a76
Showing
2 changed files
with
129 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package middleware | ||
|
||
import ( | ||
"net/http" | ||
"time" | ||
) | ||
|
||
// Sunset set Deprecation/Sunset header to response | ||
// This can be used to enable Sunset in a route or a route group | ||
// For more: https://www.rfc-editor.org/rfc/rfc8594.html | ||
func Sunset(sunsetAt time.Time, links ...string) func(http.Handler) http.Handler { | ||
return func(next http.Handler) http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
if !sunsetAt.IsZero() { | ||
w.Header().Set("Sunset", sunsetAt.Format(http.TimeFormat)) | ||
w.Header().Set("Deprecation", sunsetAt.Format(http.TimeFormat)) | ||
|
||
for _, link := range links { | ||
w.Header().Add("Link", link) | ||
} | ||
} | ||
next.ServeHTTP(w, r) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package middleware | ||
|
||
import ( | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
"time" | ||
|
||
"github.com/go-chi/chi/v5" | ||
) | ||
|
||
func TestSunset(t *testing.T) { | ||
|
||
t.Run("Sunset without link", func(t *testing.T) { | ||
req, _ := http.NewRequest("GET", "/", nil) | ||
w := httptest.NewRecorder() | ||
|
||
r := chi.NewRouter() | ||
|
||
sunsetAt := time.Date(2025, 12, 24, 10, 20, 0, 0, time.UTC) | ||
r.Use(Sunset(sunsetAt)) | ||
|
||
var sunset, deprecation string | ||
r.Get("/", func(w http.ResponseWriter, r *http.Request) { | ||
clonedHeader := w.Header().Clone() | ||
sunset = clonedHeader.Get("Sunset") | ||
deprecation = clonedHeader.Get("Deprecation") | ||
w.Write([]byte("I'll be unavailable soon")) | ||
}) | ||
r.ServeHTTP(w, req) | ||
|
||
if w.Code != 200 { | ||
t.Fatal("Response Code should be 200") | ||
} | ||
|
||
if sunset != "Wed, 24 Dec 2025 10:20:00 GMT" { | ||
t.Fatal("Test get sunset error.", sunset) | ||
} | ||
|
||
if deprecation != "Wed, 24 Dec 2025 10:20:00 GMT" { | ||
t.Fatal("Test get deprecation error.") | ||
} | ||
}) | ||
|
||
t.Run("Sunset with link", func(t *testing.T) { | ||
req, _ := http.NewRequest("GET", "/", nil) | ||
w := httptest.NewRecorder() | ||
|
||
r := chi.NewRouter() | ||
|
||
sunsetAt := time.Date(2025, 12, 24, 10, 20, 0, 0, time.UTC) | ||
deprecationLink := "https://example.com/v1/deprecation-details" | ||
r.Use(Sunset(sunsetAt, deprecationLink)) | ||
|
||
var sunset, deprecation, link string | ||
r.Get("/", func(w http.ResponseWriter, r *http.Request) { | ||
clonedHeader := w.Header().Clone() | ||
sunset = clonedHeader.Get("Sunset") | ||
deprecation = clonedHeader.Get("Deprecation") | ||
link = clonedHeader.Get("Link") | ||
|
||
w.Write([]byte("I'll be unavailable soon")) | ||
}) | ||
|
||
r.ServeHTTP(w, req) | ||
|
||
if w.Code != 200 { | ||
t.Fatal("Response Code should be 200") | ||
} | ||
|
||
if sunset != "Wed, 24 Dec 2025 10:20:00 GMT" { | ||
t.Fatal("Test get sunset error.", sunset) | ||
} | ||
|
||
if deprecation != "Wed, 24 Dec 2025 10:20:00 GMT" { | ||
t.Fatal("Test get deprecation error.") | ||
} | ||
|
||
if link != deprecationLink { | ||
t.Fatal("Test get deprecation link error.") | ||
} | ||
}) | ||
|
||
} | ||
|
||
/** | ||
EXAMPLE USAGES | ||
func main() { | ||
r := chi.NewRouter() | ||
sunsetAt := time.Date(2025, 12, 24, 10, 20, 0, 0, time.UTC) | ||
r.Use(middleware.Sunset(sunsetAt)) | ||
// can provide additional link for updated resource | ||
// r.Use(middleware.Sunset(sunsetAt, "https://example.com/v1/deprecation-details")) | ||
r.Get("/", func(w http.ResponseWriter, r *http.Request) { | ||
w.Write([]byte("This endpoint will be removed soon")) | ||
}) | ||
log.Println("Listening on port: 3000") | ||
http.ListenAndServe(":3000", r) | ||
} | ||
**/ |