Fixes two issues:
1. extractIP now handles RemoteAddr without port (#2757)
- Previously returned empty string for addresses like "192.168.1.1"
- Now validates with net.ParseIP and returns the IP directly
- Maintains full backwards compatibility for existing behavior
2. Response.Flush uses modern error handling (#2789)
- Replaces type assertion with http.NewResponseController
- Provides descriptive panic message with ResponseWriter type info
- Improves debugging experience when flushing is not supported
Both changes maintain full backwards compatibility while fixing edge cases.
Closes#2757Closes#2789🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* echo.context.cjson should encode the JSON before writing the status code #1334 :
`response.Write` automatically sets status to `200` if a response code wasn't committed yet. This is convenient, but it ignores the fact that `response.Status` is a public field that may be set separately/before `response.Write` has been called
A `response.Status` is by default `0`, or `200` if the response was reset, so `response.Write` should fallback to `200` only if a code wasn't set yet.
* echo.context.cjson should encode the JSON before writing the status code #1334 :
Writing the response code before encoding the payload is prone to error.
If JSON encoding fails, the response code is already committed, the server is able to only modify the response body to reflect the error and the user receives an awkward response where the status is successful but the body reports an error.
Instead - set the desired code on `c.response.Status`. If writing eventually takes place, the desired code is committed. If an error occurs, the server can still change the response.
This reintroduces support for Go modules, as v4.
CloseNotifier() is removed as it has been obsoleted, see https://golang.org/doc/go1.11#net/http
It was already NOT working (not sending signals) as of 1.11 the functionality was gone, we merely
deleted the functions that exposed it. If anyone still relies on it they should migrate to using
`c.Request().Context().Done()` instead.
Closes#1268, #1255