@@ -5,7 +5,7 @@ const path = require('path');
5
5
const url = require ( 'url' ) ;
6
6
const http = require ( 'http' ) ;
7
7
const https = require ( 'https' ) ;
8
- const ip = require ( 'ip ' ) ;
8
+ const ipaddr = require ( 'ipaddr.js ' ) ;
9
9
const internalIp = require ( 'internal-ip' ) ;
10
10
const killable = require ( 'killable' ) ;
11
11
const chokidar = require ( 'chokidar' ) ;
@@ -592,33 +592,76 @@ class Server {
592
592
const prettyPrintUrl = ( newHostname ) =>
593
593
url . format ( { protocol, hostname : newHostname , port, pathname : '/' } ) ;
594
594
595
- let prettyHostname ;
596
- let lanUrlForTerminal ;
595
+ let localhostForTerminal ;
596
+ let networkUrlForTerminalIPv4 ;
597
+ let networkUrlForTerminalIPv6 ;
597
598
598
- if ( hostname === '0.0.0.0' || ip . isLoopback ( hostname ) ) {
599
- prettyHostname = 'localhost' ;
599
+ const parsedIP = ipaddr . parse ( hostname ) ;
600
600
601
- const localIP =
602
- hostname === '::' ? internalIp . v6 . sync ( ) : internalIp . v4 . sync ( ) ;
601
+ if ( parsedIP . range ( ) === 'unspecified' ) {
602
+ localhostForTerminal = prettyPrintUrl ( 'localhost' ) ;
603
603
604
- if ( localIP ) {
605
- lanUrlForTerminal = prettyPrintUrl ( localIP ) ;
604
+ const networkIPv4 = internalIp . v4 . sync ( ) ;
605
+
606
+ if ( networkIPv4 ) {
607
+ networkUrlForTerminalIPv4 = prettyPrintUrl ( networkIPv4 ) ;
608
+ }
609
+
610
+ if ( hostname === '::' ) {
611
+ const networkIPv6 = internalIp . v6 . sync ( ) ;
612
+
613
+ if ( networkIPv6 ) {
614
+ networkUrlForTerminalIPv6 = prettyPrintUrl ( networkIPv6 ) ;
615
+ }
606
616
}
607
617
} else {
608
- prettyHostname = hostname ;
609
- }
618
+ if ( parsedIP . kind ( ) === 'ipv6' ) {
619
+ if ( parsedIP . isIPv4MappedAddress ( ) ) {
620
+ networkUrlForTerminalIPv4 = prettyPrintUrl (
621
+ parsedIP . toIPv4Address ( ) . toString ( )
622
+ ) ;
623
+ }
624
+ } else {
625
+ networkUrlForTerminalIPv4 = prettyPrintUrl ( hostname ) ;
626
+ }
610
627
611
- const localUrlForTerminal = prettyPrintUrl ( prettyHostname ) ;
628
+ if ( parsedIP . kind ( ) === 'ipv6' ) {
629
+ networkUrlForTerminalIPv6 = prettyPrintUrl ( hostname ) ;
630
+ }
631
+ }
612
632
613
- if ( lanUrlForTerminal ) {
633
+ if ( localhostForTerminal ) {
614
634
this . logger . info ( 'Project is running at:' ) ;
615
- this . logger . info ( `Local: ${ colors . info ( useColor , localUrlForTerminal ) } ` ) ;
616
- this . logger . info (
617
- `On Your Network: ${ colors . info ( useColor , lanUrlForTerminal ) } `
618
- ) ;
635
+ this . logger . info ( `Local: ${ colors . info ( useColor , localhostForTerminal ) } ` ) ;
636
+
637
+ const networkUrlsForTerminal = [ ]
638
+ . concat (
639
+ networkUrlForTerminalIPv4
640
+ ? [ `${ colors . info ( useColor , networkUrlForTerminalIPv4 ) } (IPv4)` ]
641
+ : [ ]
642
+ )
643
+ . concat (
644
+ networkUrlForTerminalIPv6
645
+ ? [ `${ colors . info ( useColor , networkUrlForTerminalIPv6 ) } (IPv6)` ]
646
+ : [ ]
647
+ ) ;
648
+
649
+ this . logger . info ( `On Your Network: ${ networkUrlsForTerminal . join ( ', ' ) } ` ) ;
619
650
} else {
651
+ const networkUrlsForTerminal = [ ]
652
+ . concat (
653
+ networkUrlForTerminalIPv4
654
+ ? [ `${ colors . info ( useColor , networkUrlForTerminalIPv4 ) } (IPv4)` ]
655
+ : [ ]
656
+ )
657
+ . concat (
658
+ networkUrlForTerminalIPv6
659
+ ? [ `${ colors . info ( useColor , networkUrlForTerminalIPv6 ) } (IPv6)` ]
660
+ : [ ]
661
+ ) ;
662
+
620
663
this . logger . info (
621
- `Project is running at ${ colors . info ( useColor , localUrlForTerminal ) } `
664
+ `Project is running at ${ networkUrlsForTerminal . join ( ', ' ) } `
622
665
) ;
623
666
}
624
667
@@ -663,7 +706,12 @@ class Server {
663
706
}
664
707
665
708
if ( this . options . open || this . options . openPage ) {
666
- runOpen ( localUrlForTerminal , this . options , this . logger ) ;
709
+ const uri =
710
+ localhostForTerminal ||
711
+ networkUrlForTerminalIPv4 ||
712
+ networkUrlForTerminalIPv6 ;
713
+
714
+ runOpen ( uri , this . options , this . logger ) ;
667
715
}
668
716
}
669
717
@@ -804,6 +852,7 @@ class Server {
804
852
false ,
805
853
true
806
854
) . hostname ;
855
+
807
856
// always allow requests with explicit IPv4 or IPv6-address.
808
857
// A note on IPv6 addresses:
809
858
// hostHeader will always contain the brackets denoting
@@ -813,8 +862,8 @@ class Server {
813
862
// always allow localhost host, for convenience (hostname === 'localhost')
814
863
// allow hostname of listening address (hostname === this.hostname)
815
864
const isValidHostname =
816
- ip . isV4Format ( hostname ) ||
817
- ip . isV6Format ( hostname ) ||
865
+ ipaddr . IPv4 . isValid ( hostname ) ||
866
+ ipaddr . IPv6 . isValid ( hostname ) ||
818
867
hostname === 'localhost' ||
819
868
hostname === this . hostname ;
820
869
0 commit comments