github.com/mendersoftware/go-lib-micro@v0.0.0-20240304135804-e8e39c59b148/context/middleware.go (about) 1 // Copyright 2023 Northern.tech AS 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package context 15 16 import ( 17 "context" 18 19 "github.com/ant0ine/go-json-rest/rest" 20 21 "github.com/mendersoftware/go-lib-micro/log" 22 "github.com/mendersoftware/go-lib-micro/requestid" 23 "github.com/mendersoftware/go-lib-micro/requestlog" 24 ) 25 26 // RepackLoggerToContext can be used to attach a request specific logger 27 // assigned by RequestLogMiddleware to context ctx. The logger can later be 28 // accessed using log.FromContext(ctx). 29 func RepackLoggerToContext(ctx context.Context, r *rest.Request) context.Context { 30 return log.WithContext(ctx, 31 requestlog.GetRequestLogger(r)) 32 } 33 34 // RepackRequestIdToContext can be used to attach a request ID assigned by 35 // RequestIdMiddleware to context. Request ID can later be accessed using 36 // requestid.FromContext(ctx). 37 func RepackRequestIdToContext(ctx context.Context, r *rest.Request) context.Context { 38 return requestid.WithContext(ctx, 39 requestid.GetReqId(r)) 40 } 41 42 // UpdateContextFunc is a function that can update context ctx using data from 43 // rest.Request and return modified context. 44 type UpdateContextFunc func(ctx context.Context, r *rest.Request) context.Context 45 46 // UpdateContextMiddleware is a middleware that can be used to update 47 // http.Request context. The middleware will apply user provided context 48 // modifications listed in Updates. The middleware operates on rest.Request and 49 // context is owned/assigned to http.Request. Because of this a new rest.Request 50 // will be allocated before passing it further in the stack. 51 // 52 // When combined with RepackRequestIdToContext and RepackLoggerToContext, the 53 // middleware will populate http.Request context with both request ID and 54 // request specific logger, Later it is possible to call 55 // log.FromContext(r.Context()) to obtain context logger or 56 // requestid.FromContext(r.Context()) to get request ID. 57 type UpdateContextMiddleware struct { 58 Updates []UpdateContextFunc 59 } 60 61 func (ucmw *UpdateContextMiddleware) MiddlewareFunc(h rest.HandlerFunc) rest.HandlerFunc { 62 return func(w rest.ResponseWriter, r *rest.Request) { 63 64 ctx := r.Context() 65 for _, up := range ucmw.Updates { 66 ctx = up(ctx, r) 67 } 68 69 r.Request = r.WithContext(ctx) 70 71 h(w, r) 72 } 73 }