@@ -45,7 +45,7 @@ func apiError(ctx context.Context, w http.ResponseWriter, r *http.Request, err e
4545 logger .Wf (ctx , "HTTP API error %+v" , err )
4646 w .Header ().Set ("Content-Type" , "text/plain; charset=utf-8" )
4747 w .WriteHeader (http .StatusInternalServerError )
48- fmt .Fprintln (w , fmt . Sprintf ( "%v" , err ) )
48+ fmt .Fprintf (w , "%v\n " , err )
4949}
5050
5151func apiCORS (ctx context.Context , w http.ResponseWriter , r * http.Request ) bool {
@@ -142,6 +142,20 @@ func isPeerClosedError(err error) bool {
142142 return false
143143}
144144
145+ // isClosedNetworkError indicates whether the error is due to a closed network connection.
146+ func isClosedNetworkError (err error ) bool {
147+ if err == nil {
148+ return false
149+ }
150+
151+ // Check for "use of closed network connection" error
152+ if netErr , ok := err .(* net.OpError ); ok {
153+ return netErr .Err .Error () == "use of closed network connection"
154+ }
155+
156+ return false
157+ }
158+
145159// convertURLToStreamURL convert the URL in HTTP request to special URLs. The unifiedURL is the URL
146160// in unified, foramt as scheme://vhost/app/stream without extensions. While the fullURL is the unifiedURL
147161// with extension.
@@ -263,7 +277,44 @@ func parseListenEndpoint(ep string) (protocol string, ip net.IP, port uint16, er
263277 }
264278 }
265279
266- // Must be protocol://ip:port schema.
280+ // Handle URL-style format: protocol://host:port or protocol://port
281+ if strings .Contains (ep , "://" ) {
282+ parts := strings .SplitN (ep , "://" , 2 )
283+ if len (parts ) != 2 {
284+ return "" , nil , 0 , errors .Errorf ("invalid endpoint %v" , ep )
285+ }
286+
287+ protocol = parts [0 ]
288+ hostPort := parts [1 ]
289+
290+ // Check if there's a port specified
291+ if strings .Contains (hostPort , ":" ) {
292+ // Format: protocol://host:port
293+ host , portStr , err := net .SplitHostPort (hostPort )
294+ if err != nil {
295+ return "" , nil , 0 , errors .Wrapf (err , "parse host:port %v" , hostPort )
296+ }
297+
298+ p , err := strconv .Atoi (portStr )
299+ if err != nil {
300+ return "" , nil , 0 , errors .Wrapf (err , "parse port %v" , portStr )
301+ }
302+
303+ if host != "" {
304+ ip = net .ParseIP (host )
305+ }
306+ return protocol , ip , uint16 (p ), nil
307+ } else {
308+ // Format: protocol://port
309+ p , err := strconv .Atoi (hostPort )
310+ if err != nil {
311+ return "" , nil , 0 , errors .Wrapf (err , "parse port %v" , hostPort )
312+ }
313+ return protocol , nil , uint16 (p ), nil
314+ }
315+ }
316+
317+ // Legacy format: protocol:ip:port
267318 parts := strings .Split (ep , ":" )
268319 if len (parts ) != 3 {
269320 return "" , nil , 0 , errors .Errorf ("invalid endpoint %v" , ep )
0 commit comments