24
loading...
This website collects cookies to deliver better user experience
Accept
header is an essential part of HTTP and especially REST communication.Accept
header, either I'm.Accept
header is a simple list of mime types (application/json
, text/html
, etc.) or wildcard rules (*/*
, application/*
, etc.) that a client supports.Accept
header, the client expects to respond with one of the matched mime types from the header.q
, that defines order of rules to choose the best option for a client, for example: */*;q=0.1, application/json; q=1, application/xml; q=0.8
.charset
. If a client sets some charset
, it expects to receive a response encoded.Accept
header parser,
symbol;q
parameter to sort;Accept
rules from the Accept
header and find the best result for either for client and server.Accept
header by yourself;Accept
header supporting.http.HandlerFunc
type;header := r.Header.Get("Accept")
// Parse Accept header to build needed rules for matching.
ah := mimeheader.ParseAcceptHeader(header)
// We do not need default mime type.
mh, mtype, m := ah.Negotiate(acceptMimeTypes, "")
if !m {
// If not matched accept mim type, return 406.
rw.WriteHeader(http.StatusNotAcceptable)
return
}
// Add matched mime type to context.
ctx := context.WithValue(r.Context(), "resp_content_type", mtype)
// Add charset, if exists.
chs, ok := mh.Params["charset"]
if ok {
ctx = context.WithValue(ctx, "resp_charset", chs)
}
// Parse Accept header to build needed rules for matching.
ah := mimeheader.ParseAcceptHeader(header)
// We do not need default mime type.
mh, mtype, m := ah.Negotiate(acceptMimeTypes, "")
package main
import (
"context"
"log"
"net/http"
"github.com/aohorodnyk/mimeheader"
)
func main() {
r := http.NewServeMux()
r.HandleFunc("/", acceptHeaderMiddleware([]string{"application/json", "text/html"})(handlerTestFunc))
err := http.ListenAndServe(":8080", r)
if err != nil {
log.Fatalln(err)
}
}
func acceptHeaderMiddleware(acceptMimeTypes []string) func(http.HandlerFunc) http.HandlerFunc {
return func(next http.HandlerFunc) http.HandlerFunc {
return func(rw http.ResponseWriter, r *http.Request) {
header := r.Header.Get("Accept")
ah := mimeheader.ParseAcceptHeader(header)
// We do not need default mime type.
mh, mtype, m := ah.Negotiate(acceptMimeTypes, "")
if !m {
// If not matched accept mim type, return 406.
rw.WriteHeader(http.StatusNotAcceptable)
return
}
// Add matched mime type to context.
ctx := context.WithValue(r.Context(), "resp_content_type", mtype)
// Add charset, if set
chs, ok := mh.Params["charset"]
if ok {
ctx = context.WithValue(ctx, "resp_charset", chs)
}
// New requet from new context.
rc := r.WithContext(ctx)
// Call next middleware or handler.
next(rw, rc)
}
}
}
func handlerTestFunc(rw http.ResponseWriter, r *http.Request) {
mtype := r.Context().Value("resp_content_type").(string)
charset, _ := r.Context().Value("resp_charset").(string)
rw.Write([]byte(mtype + ":" + charset))
}
GET http://localhost:8080/
Accept: text/*; q=0.9,application/json; q=1;
#HTTP/1.1 200 OK
#Date: Sat, 03 Jul 2021 23:55:41 GMT
#Content-Length: 17
#Content-Type: text/plain; charset=utf-8
#
#application/json:
###
GET http://localhost:8080/
Accept: text/*; q=1,application/json; q=1; charset=utf-8bm;
#HTTP/1.1 200 OK
#Date: Sat, 03 Jul 2021 23:56:14 GMT
#Content-Length: 24
#Content-Type: text/plain; charset=utf-8
#
#application/json:utf-8bm
###
GET http://localhost:8080/
Accept: text/html; charset=utf-8; q=1,application/*; q=1; charset=cp1251;
#HTTP/1.1 200 OK
#Date: Sat, 03 Jul 2021 23:54:20 GMT
#Content-Length: 14
#Content-Type: text/plain; charset=utf-8
#
#text/html:utf-8
###
GET http://localhost:8080/
Accept: text/*; q=1,application/*; q=0.9;
#HTTP/1.1 200 OK
#Date: Sat, 03 Jul 2021 23:56:33 GMT
#Content-Length: 10
#Content-Type: text/plain; charset=utf-8
#
#text/html:
###
GET http://localhost:8080/
Accept: text/plain; q=1,application/xml; q=1;
# HTTP/1.1 406 Not Acceptable
# Date: Sat, 03 Jul 2021 19:17:28 GMT
# Content-Length: 0
# Connection: close
Accept
header even if this feature is not implemented in the current framework.Accept
header or mime types in general, you could try mimeheader library. I believe it will help with the task.