@@ -31,7 +31,10 @@ var contextAdapterPool = sync.Pool{
3131 },
3232}
3333
34+ // acquireContextAdapter prepares a pooled adapter for one Echo request.
3435func acquireContextAdapter (c * echo.Context ) * contextAdapter {
36+ // The adapter is pooled because every request needs one, but the embedded
37+ // Echo pointers and cached derived state must be reset between requests.
3538 adapted := contextAdapterPool .Get ().(* contextAdapter )
3639 adapted .echo = c
3740 adapted .reusable = true
@@ -44,6 +47,7 @@ func acquireContextAdapter(c *echo.Context) *contextAdapter {
4447 return adapted
4548}
4649
50+ // releaseContextAdapter returns a reusable adapter to the pool after a request finishes.
4751func releaseContextAdapter (adapted * contextAdapter ) {
4852 if adapted == nil || ! adapted .reusable {
4953 return
@@ -58,6 +62,7 @@ func releaseContextAdapter(adapted *contextAdapter) {
5862 contextAdapterPool .Put (adapted )
5963}
6064
65+ // Context returns the effective request context, including any source-only fast-path state.
6166func (c * contextAdapter ) Context () context.Context {
6267 if c .context != nil {
6368 return c .context
@@ -67,6 +72,8 @@ func (c *contextAdapter) Context() context.Context {
6772 return base
6873 }
6974 if c .sourceContext == nil {
75+ // Source-only propagation is common on the hot path, so keep it as a
76+ // lightweight wrapper instead of forcing a request clone.
7077 c .sourceContext = sourceNameContext {
7178 Context : base ,
7279 source : c .sourceName ,
@@ -75,163 +82,201 @@ func (c *contextAdapter) Context() context.Context {
7582 return c .sourceContext
7683}
7784
85+ // Method returns the current request method.
7886func (c * contextAdapter ) Method () string {
7987 return c .echo .Request ().Method
8088}
8189
90+ // Path returns the matched route path.
8291func (c * contextAdapter ) Path () string {
8392 return c .echo .Path ()
8493}
8594
95+ // URI returns the current request URI.
8696func (c * contextAdapter ) URI () string {
8797 return c .echo .Request ().URL .RequestURI ()
8898}
8999
100+ // Scheme returns the resolved request scheme.
90101func (c * contextAdapter ) Scheme () string {
91102 return c .echo .Scheme ()
92103}
93104
105+ // Host returns the request host.
94106func (c * contextAdapter ) Host () string {
95107 return c .echo .Request ().Host
96108}
97109
110+ // Param returns a named route parameter.
98111func (c * contextAdapter ) Param (name string ) string {
99112 return c .echo .Param (name )
100113}
101114
115+ // Query returns a query parameter value.
102116func (c * contextAdapter ) Query (name string ) string {
103117 return c .echo .QueryParam (name )
104118}
105119
120+ // Header returns a request header value.
106121func (c * contextAdapter ) Header (name string ) string {
107122 return c .echo .Request ().Header .Get (name )
108123}
109124
125+ // Cookie returns a named request cookie.
110126func (c * contextAdapter ) Cookie (name string ) (* http.Cookie , error ) {
111127 return c .echo .Cookie (name )
112128}
113129
130+ // RealIP returns the best-effort client IP address.
114131func (c * contextAdapter ) RealIP () string {
115132 return c .echo .RealIP ()
116133}
117134
135+ // Request returns the request, rebinding its context only when needed.
118136func (c * contextAdapter ) Request () * http.Request {
119137 base := c .echo .Request ()
120138 if c .context == nil || base == nil {
121139 return base
122140 }
123141 if c .request == nil || c .request .Context () != c .context {
142+ // Only materialize a rebound request when a caller explicitly asks for it.
124143 c .request = base .WithContext (c .context )
125144 }
126145 return c .request
127146}
128147
148+ // RawRequest returns the underlying Echo request without rebinding.
129149func (c * contextAdapter ) RawRequest () * http.Request {
130150 if c == nil || c .echo == nil {
131151 return nil
132152 }
133153 return c .echo .Request ()
134154}
135155
156+ // SetRequest replaces the underlying request.
136157func (c * contextAdapter ) SetRequest (request * http.Request ) {
137158 c .echo .SetRequest (request )
138159 c .request = nil
139160}
140161
162+ // SetContext overrides the effective request context for subsequent Request and Context calls.
141163func (c * contextAdapter ) SetContext (ctx context.Context ) {
164+ // Any explicit context override supersedes the cheaper source-name fast path.
142165 c .context = ctx
143166 c .request = nil
144167 c .sourceName = ""
145168 c .sourceContext = nil
146169}
147170
171+ // SetAppSourceName records the application source name on the adapter fast path.
148172func (c * contextAdapter ) SetAppSourceName (source string ) {
149173 c .sourceName = source
150174 c .sourceContext = nil
151175}
152176
177+ // AppSourceName returns the application source name attached to the request.
153178func (c * contextAdapter ) AppSourceName () string {
154179 return c .sourceName
155180}
156181
182+ // Response returns the response adapter for the current request.
157183func (c * contextAdapter ) Response () web.Response {
158184 return & c .response
159185}
160186
187+ // ResponseWriter returns the active response writer.
161188func (c * contextAdapter ) ResponseWriter () http.ResponseWriter {
162189 return c .echo .Response ()
163190}
164191
192+ // SetResponseWriter replaces the active response writer.
165193func (c * contextAdapter ) SetResponseWriter (writer http.ResponseWriter ) {
166194 c .echo .SetResponse (writer )
167195 c .refreshResponse ()
168196}
169197
198+ // Bind decodes the request body into target using Echo's binder.
170199func (c * contextAdapter ) Bind (target any ) error {
171200 return c .echo .Bind (target )
172201}
173202
203+ // Set stores request-scoped data on the underlying Echo context.
174204func (c * contextAdapter ) Set (key string , value any ) {
175205 c .echo .Set (key , value )
176206}
177207
208+ // Get reads request-scoped data from the underlying Echo context.
178209func (c * contextAdapter ) Get (key string ) any {
179210 return c .echo .Get (key )
180211}
181212
213+ // AddHeader appends a response header value.
182214func (c * contextAdapter ) AddHeader (name string , value string ) {
183215 c .echo .Response ().Header ().Add (name , value )
184216}
185217
218+ // SetHeader sets a response header value.
186219func (c * contextAdapter ) SetHeader (name string , value string ) {
187220 c .echo .Response ().Header ().Set (name , value )
188221}
189222
223+ // SetCookie writes a response cookie.
190224func (c * contextAdapter ) SetCookie (cookie * http.Cookie ) {
191225 http .SetCookie (c .echo .Response (), cookie )
192226}
193227
228+ // JSON writes a JSON response.
194229func (c * contextAdapter ) JSON (code int , payload any ) error {
195230 return c .echo .JSON (code , payload )
196231}
197232
233+ // Blob writes a raw byte response with the provided content type.
198234func (c * contextAdapter ) Blob (code int , contentType string , body []byte ) error {
199235 return c .echo .Blob (code , contentType , body )
200236}
201237
238+ // File serves a file from disk.
202239func (c * contextAdapter ) File (path string ) error {
203240 http .ServeFile (c .echo .Response (), c .echo .Request (), path )
204241 return nil
205242}
206243
244+ // Text writes a plain-text response.
207245func (c * contextAdapter ) Text (code int , body string ) error {
208246 return c .echo .String (code , body )
209247}
210248
249+ // HTML writes an HTML response.
211250func (c * contextAdapter ) HTML (code int , body string ) error {
212251 return c .echo .HTML (code , body )
213252}
214253
254+ // NoContent writes an empty response with the provided status code.
215255func (c * contextAdapter ) NoContent (code int ) error {
216256 return c .echo .NoContent (code )
217257}
218258
259+ // Redirect sends an HTTP redirect response.
219260func (c * contextAdapter ) Redirect (code int , url string ) error {
220261 return c .echo .Redirect (code , url )
221262}
222263
264+ // StatusCode returns the response status code.
223265func (c * contextAdapter ) StatusCode () int {
224266 return c .response .StatusCode ()
225267}
226268
269+ // Native returns the underlying Echo context.
227270func (c * contextAdapter ) Native () any {
228271 return c .echo
229272}
230273
274+ // DisableReuse prevents the adapter from returning to the pool after use.
231275func (c * contextAdapter ) DisableReuse () {
232276 c .reusable = false
233277}
234278
279+ // refreshResponse resynchronizes cached response wrappers after writer swaps.
235280func (c * contextAdapter ) refreshResponse () {
236281 if c == nil || c .echo == nil {
237282 c .echoResponse = nil
@@ -257,25 +302,30 @@ type sourceNameContext struct {
257302 source string
258303}
259304
305+ // AppSourceName returns the app source name carried by this lightweight context wrapper.
260306func (c sourceNameContext ) AppSourceName () string {
261307 return c .source
262308}
263309
264310var _ web.Response = (* responseAdapter )(nil )
265311
312+ // Header returns the response header map.
266313func (r * responseAdapter ) Header () http.Header {
267314 return r .context .echo .Response ().Header ()
268315}
269316
317+ // Writer returns the active response writer.
270318func (r * responseAdapter ) Writer () http.ResponseWriter {
271319 return r .context .echo .Response ()
272320}
273321
322+ // SetWriter replaces the active response writer.
274323func (r * responseAdapter ) SetWriter (writer http.ResponseWriter ) {
275324 r .context .echo .SetResponse (writer )
276325 r .context .refreshResponse ()
277326}
278327
328+ // StatusCode returns the committed response status code.
279329func (r * responseAdapter ) StatusCode () int {
280330 response := r .currentResponse ()
281331 if response == nil {
@@ -284,6 +334,7 @@ func (r *responseAdapter) StatusCode() int {
284334 return response .Status
285335}
286336
337+ // Size returns the number of bytes written to the response.
287338func (r * responseAdapter ) Size () int64 {
288339 response := r .currentResponse ()
289340 if response == nil {
@@ -292,6 +343,7 @@ func (r *responseAdapter) Size() int64 {
292343 return response .Size
293344}
294345
346+ // Committed reports whether the response has been committed.
295347func (r * responseAdapter ) Committed () bool {
296348 response := r .currentResponse ()
297349 if response == nil {
@@ -300,10 +352,12 @@ func (r *responseAdapter) Committed() bool {
300352 return response .Committed
301353}
302354
355+ // Native returns the underlying Echo response writer.
303356func (r * responseAdapter ) Native () any {
304357 return r .context .echo .Response ()
305358}
306359
360+ // currentResponse returns the cached Echo response, refreshing it when needed.
307361func (r * responseAdapter ) currentResponse () * echo.Response {
308362 if r == nil || r .context == nil {
309363 return nil
0 commit comments