1616
1717package com .microsoft .playwright .impl ;
1818
19- import com .google .gson .JsonArray ;
20- import com .google .gson .JsonObject ;
2119import com .microsoft .playwright .PlaywrightException ;
2220
2321import java .net .MalformedURLException ;
22+ import java .net .URI ;
23+ import java .net .URISyntaxException ;
2424import java .net .URL ;
25- import java .util .Objects ;
2625import java .util .function .Predicate ;
2726import java .util .regex .Pattern ;
27+ import java .util .ArrayList ;
28+ import java .util .List ;
2829
2930import static com .microsoft .playwright .impl .Utils .globToRegex ;
3031import static com .microsoft .playwright .impl .Utils .toJsRegexFlags ;
3132
3233class UrlMatcher {
33- final Object rawSource ;
34- private final Predicate <String > predicate ;
35-
36- private static Predicate <String > toPredicate (Pattern pattern ) {
37- return s -> pattern .matcher (s ).find ();
38- }
39-
40- static UrlMatcher any () {
41- return new UrlMatcher ((Object ) null , null );
42- }
34+ private final URL baseURL ;
35+ public final String glob ;
36+ public final Pattern pattern ;
37+ public final Predicate <String > predicate ;
4338
4439 static UrlMatcher forOneOf (URL baseUrl , Object object ) {
4540 if (object == null ) {
46- return UrlMatcher . any ( );
41+ return new UrlMatcher ( baseUrl , ( String ) null );
4742 }
4843 if (object instanceof String ) {
4944 return new UrlMatcher (baseUrl , (String ) object );
@@ -58,6 +53,16 @@ static UrlMatcher forOneOf(URL baseUrl, Object object) {
5853 }
5954
6055 static String resolveUrl (URL baseUrl , String spec ) {
56+ try {
57+ URL specURL = new URL (spec );
58+ // We want to follow HTTP spec, so we enforce a slash if there is no path.
59+ if (specURL .getPath ().isEmpty ()) {
60+ spec = specURL .toString () + "/" ;
61+ }
62+ } catch (MalformedURLException e ) {
63+ // Ignore - we end up here if spec is e.g. a relative path.
64+ }
65+
6166 if (baseUrl == null ) {
6267 return spec ;
6368 }
@@ -68,50 +73,100 @@ static String resolveUrl(URL baseUrl, String spec) {
6873 }
6974 }
7075
71- UrlMatcher (URL base , String url ) {
72- this (url , toPredicate (Pattern .compile (globToRegex (resolveUrl (base , url )))).or (s -> url == null || url .equals (s )));
76+ static private String normaliseUrl (String url ) {
77+ URI parsedUrl ;
78+ try {
79+ parsedUrl = new URI (url );
80+ } catch (URISyntaxException e ) {
81+ return url ;
82+ }
83+ if (parsedUrl .getPath ().isEmpty ()) {
84+ try {
85+ return new URI (parsedUrl .getScheme (), parsedUrl .getAuthority (), "/" , parsedUrl .getQuery (), parsedUrl .getFragment ()).toString ();
86+ } catch (URISyntaxException e ) {
87+ return url ;
88+ }
89+ }
90+ return url ;
7391 }
7492
75- UrlMatcher (Pattern pattern ) {
76- this (pattern , toPredicate (pattern ));
93+ UrlMatcher (URL baseURL , String glob ) {
94+ this .baseURL = baseURL ;
95+ this .glob = glob ;
96+ this .pattern = null ;
97+ this .predicate = null ;
7798 }
78- UrlMatcher (Predicate <String > predicate ) {
79- this (predicate , predicate );
99+
100+ UrlMatcher (Pattern pattern ) {
101+ this .pattern = pattern ;
102+ this .baseURL = null ;
103+ this .glob = null ;
104+ this .predicate = null ;
80105 }
81106
82- private UrlMatcher (Object rawSource , Predicate <String > predicate ) {
83- this .rawSource = rawSource ;
107+ UrlMatcher (Predicate <String > predicate ) {
84108 this .predicate = predicate ;
109+ this .baseURL = null ;
110+ this .glob = null ;
111+ this .pattern = null ;
85112 }
86113
87114 boolean test (String value ) {
88- return predicate == null || predicate .test (value );
115+ return testImpl (baseURL , pattern , predicate , glob , value );
116+ }
117+
118+ private static boolean testImpl (URL baseURL , Pattern pattern , Predicate <String > predicate , String glob , String value ) {
119+ if (pattern != null ) {
120+ return pattern .matcher (value ).find ();
121+ }
122+ if (predicate != null ) {
123+ return predicate .test (value );
124+ }
125+ if (glob != null ) {
126+ if (!glob .startsWith ("*" )) {
127+ glob = normaliseUrl (glob );
128+ // Allow http(s) baseURL to match ws(s) urls.
129+ if (baseURL != null && Pattern .compile ("^https?://" ).matcher (baseURL .getProtocol ()).find () && Pattern .compile ("^wss?://" ).matcher (value ).find ()) {
130+ try {
131+ baseURL = new URL (baseURL .toString ().replaceFirst ("^http" , "ws" ));
132+ } catch (MalformedURLException e ) {
133+ // Handle exception
134+ }
135+ }
136+ glob = resolveUrl (baseURL , glob );
137+ }
138+ return Pattern .compile (globToRegex (glob )).matcher (value ).find ();
139+ }
140+ return true ;
89141 }
90142
91143 @ Override
92144 public boolean equals (Object o ) {
93145 if (this == o ) return true ;
94146 if (o == null || getClass () != o .getClass ()) return false ;
95147 UrlMatcher that = (UrlMatcher ) o ;
96- if (rawSource instanceof Pattern && that .rawSource instanceof Pattern ) {
97- Pattern a = (Pattern ) rawSource ;
98- Pattern b = (Pattern ) that .rawSource ;
99- return a .pattern ().equals (b .pattern ()) && a .flags () == b .flags ();
148+ List <Boolean > matches = new ArrayList <>();
149+ if (baseURL != null && that .baseURL != null ) {
150+ matches .add (baseURL .equals (that .baseURL ));
100151 }
101- return Objects .equals (rawSource , that .rawSource );
102- }
103-
104- @ Override
105- public int hashCode () {
106- return Objects .hash (rawSource );
152+ if (pattern != null && that .pattern != null ) {
153+ matches .add (pattern .pattern ().equals (that .pattern .pattern ()) && pattern .flags () == that .pattern .flags ());
154+ }
155+ if (predicate != null && that .predicate != null ) {
156+ matches .add (predicate .equals (that .predicate ));
157+ }
158+ if (glob != null && that .glob != null ) {
159+ matches .add (glob .equals (that .glob ));
160+ }
161+ return matches .stream ().allMatch (m -> m );
107162 }
108163
109164 @ Override
110165 public String toString () {
111- if (rawSource = = null )
112- return "<any>" ;
113- if (rawSource instanceof Predicate )
114- return "matching predicate" ;
115- return rawSource . toString ( );
166+ if (pattern ! = null )
167+ return String . format ( "<regex pattern= \" %s \" flags= \" %s \" >" , pattern . pattern (), toJsRegexFlags ( pattern )) ;
168+ if (predicate != null )
169+ return "< predicate> " ;
170+ return String . format ( "<glob pattern= \" %s \" >" , glob );
116171 }
117172}
0 commit comments