1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.proxyautoconfig;
16
17 import java.net.InetAddress;
18 import java.text.SimpleDateFormat;
19 import java.util.Calendar;
20 import java.util.Locale;
21 import java.util.TimeZone;
22
23 import org.apache.commons.lang3.StringUtils;
24 import org.htmlunit.javascript.HtmlUnitScriptable;
25 import org.htmlunit.javascript.JavaScriptEngine;
26 import org.htmlunit.javascript.configuration.JsxClass;
27 import org.htmlunit.javascript.configuration.JsxFunction;
28 import org.htmlunit.util.SubnetUtils;
29
30
31
32
33
34
35
36
37
38
39
40 @JsxClass
41 public final class ProxyAutoConfig extends HtmlUnitScriptable {
42
43 private static final String TIMEZONE_GMT = "GMT";
44
45 private ProxyAutoConfig() {
46 super();
47 }
48
49
50
51
52
53
54 @JsxFunction
55 public static boolean isPlainHostName(final String host) {
56 return host.indexOf('.') == -1;
57 }
58
59
60
61
62
63
64
65 @JsxFunction
66 public static boolean dnsDomainIs(final String host, final String domain) {
67 return host.endsWith(domain);
68 }
69
70
71
72
73
74
75
76
77
78 @JsxFunction
79 public static boolean localHostOrDomainIs(final String host, final String hostdom) {
80 return host.length() > 1 && host.equals(hostdom) || host.indexOf('.') == -1 && hostdom.startsWith(host);
81 }
82
83
84
85
86
87
88 @JsxFunction
89 public static boolean isResolvable(final String host) {
90 return dnsResolve(host) != null;
91 }
92
93
94
95
96
97
98
99
100
101
102 @JsxFunction
103 public static boolean isInNet(final String host, final String pattern, final String mask) {
104 final String dnsResolve = dnsResolve(host);
105 if (null == dnsResolve) {
106 return false;
107 }
108
109 final SubnetUtils subnetUtils = new SubnetUtils(pattern, mask);
110 return subnetUtils.isInRange(dnsResolve);
111 }
112
113
114
115
116
117
118 @JsxFunction
119 public static String dnsResolve(final String host) {
120 try {
121 return InetAddress.getByName(host).getHostAddress();
122 }
123 catch (final Exception e) {
124 return null;
125 }
126 }
127
128
129
130
131
132 @JsxFunction
133 public static String myIpAddress() {
134 try {
135 return InetAddress.getLocalHost().getHostAddress();
136 }
137 catch (final Exception e) {
138 throw JavaScriptEngine.throwAsScriptRuntimeEx(e);
139 }
140 }
141
142
143
144
145
146
147 @JsxFunction
148 public static int dnsDomainLevels(final String host) {
149 int levels = 0;
150 for (int i = host.length() - 1; i >= 0; i--) {
151 if (host.charAt(i) == '.') {
152 levels++;
153 }
154 }
155 return levels;
156 }
157
158
159
160
161
162
163
164 @JsxFunction
165 public static boolean shExpMatch(final String str, final String shexp) {
166 final String regexp = shexp.replace(".", "\\.").replace("*", ".*").replace("?", ".");
167 return str.matches(regexp);
168 }
169
170
171
172
173
174
175
176
177 @JsxFunction
178 public static boolean weekdayRange(final String wd1, Object wd2, final Object gmt) {
179 TimeZone timezone = TimeZone.getDefault();
180 if (TIMEZONE_GMT.equals(JavaScriptEngine.toString(gmt))
181 || TIMEZONE_GMT.equals(JavaScriptEngine.toString(wd2))) {
182 timezone = TimeZone.getTimeZone(TIMEZONE_GMT);
183 }
184 if (JavaScriptEngine.isUndefined(wd2) || TIMEZONE_GMT.equals(JavaScriptEngine.toString(wd2))) {
185 wd2 = wd1;
186 }
187 final Calendar calendar = Calendar.getInstance(timezone);
188 for (int i = 0; i < 7; i++) {
189 final String day = new SimpleDateFormat("EEE", Locale.ROOT)
190 .format(calendar.getTime()).toUpperCase(Locale.ROOT);
191 if (day.equals(wd2)) {
192 return true;
193 }
194 if (day.equals(wd1)) {
195 return i == 0;
196 }
197 calendar.add(Calendar.DAY_OF_WEEK, 1);
198 }
199 return false;
200 }
201
202
203
204
205
206
207
208
209
210
211
212
213 @JsxFunction
214 public static boolean dateRange(final String value1, final Object value2, final Object value3,
215 final Object value4, final Object value5, final Object value6, final Object value7) {
216 final Object[] values = {value1, value2, value3, value4, value5, value6, value7};
217 TimeZone timezone = TimeZone.getDefault();
218
219
220 int length;
221 for (length = values.length - 1; length >= 0; length--) {
222 if (TIMEZONE_GMT.equals(JavaScriptEngine.toString(values[length]))) {
223 timezone = TimeZone.getTimeZone(TIMEZONE_GMT);
224 break;
225 }
226 else if (!JavaScriptEngine.isUndefined(values[length])) {
227 length++;
228 break;
229 }
230 }
231
232 final int day1;
233 final int day2;
234 final int month1;
235 final int month2;
236 final int year1;
237 final int year2;
238 final Calendar cal1;
239 final Calendar cal2;
240 switch (length) {
241 case 1:
242 final int day = getSmallInt(value1);
243 final int month = dateRange_getMonth(value1);
244 final int year = dateRange_getYear(value1);
245 cal1 = dateRange_createCalendar(timezone, day, month, year);
246 cal2 = (Calendar) cal1.clone();
247 break;
248
249 case 2:
250 day1 = getSmallInt(value1);
251 month1 = dateRange_getMonth(value1);
252 year1 = dateRange_getYear(value1);
253 cal1 = dateRange_createCalendar(timezone, day1, month1, year1);
254 day2 = getSmallInt(value2);
255 month2 = dateRange_getMonth(value2);
256 year2 = dateRange_getYear(value2);
257 cal2 = dateRange_createCalendar(timezone, day2, month2, year2);
258 break;
259
260 case 4:
261 day1 = getSmallInt(value1);
262 if (day1 != -1) {
263 month1 = dateRange_getMonth(value2);
264 day2 = getSmallInt(value3);
265 month2 = dateRange_getMonth(value4);
266 cal1 = dateRange_createCalendar(timezone, day1, month1, -1);
267 cal2 = dateRange_createCalendar(timezone, day2, month2, -1);
268 }
269 else {
270 month1 = dateRange_getMonth(value1);
271 year1 = dateRange_getMonth(value2);
272 month2 = getSmallInt(value3);
273 year2 = dateRange_getMonth(value4);
274 cal1 = dateRange_createCalendar(timezone, -1, month1, year1);
275 cal2 = dateRange_createCalendar(timezone, -1, month2, year2);
276 }
277 break;
278
279 default:
280 day1 = getSmallInt(value1);
281 month1 = dateRange_getMonth(value2);
282 year1 = dateRange_getYear(value3);
283 day2 = getSmallInt(value4);
284 month2 = dateRange_getMonth(value5);
285 year2 = dateRange_getYear(value6);
286 cal1 = dateRange_createCalendar(timezone, day1, month1, year1);
287 cal2 = dateRange_createCalendar(timezone, day2, month2, year2);
288 }
289
290 final Calendar today = Calendar.getInstance(timezone);
291 today.set(Calendar.MILLISECOND, 0);
292 today.set(Calendar.SECOND, 0);
293 cal1.set(Calendar.MILLISECOND, 0);
294 cal1.set(Calendar.SECOND, 0);
295 cal2.set(Calendar.MILLISECOND, 0);
296 cal2.set(Calendar.SECOND, 0);
297 return today.equals(cal1) || (today.after(cal1) && today.before(cal2)) || today.equals(cal2);
298 }
299
300 private static Calendar dateRange_createCalendar(final TimeZone timezone,
301 final int day, final int month, final int year) {
302 final Calendar calendar = Calendar.getInstance(timezone);
303 if (day != -1) {
304 calendar.set(Calendar.DAY_OF_MONTH, day);
305 }
306 if (month != -1) {
307 calendar.set(Calendar.MONTH, month);
308 }
309 if (year != -1) {
310 calendar.set(Calendar.YEAR, year);
311 }
312 return calendar;
313 }
314
315 private static int getSmallInt(final Object object) {
316 final String s = JavaScriptEngine.toString(object);
317 if (Character.isDigit(s.charAt(0))) {
318 final int i = Integer.parseInt(s);
319 if (i < 70) {
320 return i;
321 }
322 }
323 return -1;
324 }
325
326 private static int dateRange_getMonth(final Object object) {
327 final String s = JavaScriptEngine.toString(object);
328 if (Character.isLetter(s.charAt(0))) {
329 try {
330 final Calendar cal = Calendar.getInstance(Locale.ROOT);
331 cal.clear();
332 cal.setTime(new SimpleDateFormat("MMM", Locale.ROOT).parse(s));
333 return cal.get(Calendar.MONTH);
334 }
335 catch (final Exception ignored) {
336
337 }
338 }
339 return -1;
340 }
341
342 private static int dateRange_getYear(final Object object) {
343 final String s = JavaScriptEngine.toString(object);
344 if (Character.isDigit(s.charAt(0))) {
345 final int i = Integer.parseInt(s);
346 if (i > 1000) {
347 return i;
348 }
349 }
350 return -1;
351 }
352
353
354
355
356
357
358
359
360
361
362
363
364 @JsxFunction
365 public static boolean timeRange(final String value1, final Object value2, final Object value3,
366 final Object value4, final Object value5, final Object value6, final Object value7) {
367 final Object[] values = {value1, value2, value3, value4, value5, value6, value7};
368 TimeZone timezone = TimeZone.getDefault();
369
370
371 int length;
372 for (length = values.length - 1; length >= 0; length--) {
373 if (TIMEZONE_GMT.equals(JavaScriptEngine.toString(values[length]))) {
374 timezone = TimeZone.getTimeZone(TIMEZONE_GMT);
375 break;
376 }
377 else if (!JavaScriptEngine.isUndefined(values[length])) {
378 length++;
379 break;
380 }
381 }
382
383 final int hour1;
384 final int hour2;
385 final int min1;
386 final int min2;
387 final int second1;
388 final int second2;
389 final Calendar cal1;
390 final Calendar cal2;
391 switch (length) {
392 case 1:
393 hour1 = getSmallInt(value1);
394 cal1 = timeRange_createCalendar(timezone, hour1, -1, -1);
395 cal2 = (Calendar) cal1.clone();
396 cal2.add(Calendar.HOUR_OF_DAY, 1);
397 break;
398
399 case 2:
400 hour1 = getSmallInt(value1);
401 cal1 = timeRange_createCalendar(timezone, hour1, -1, -1);
402 hour2 = getSmallInt(value2);
403 cal2 = timeRange_createCalendar(timezone, hour2, -1, -1);
404 break;
405
406 case 4:
407 hour1 = getSmallInt(value1);
408 min1 = getSmallInt(value2);
409 hour2 = getSmallInt(value3);
410 min2 = getSmallInt(value4);
411 cal1 = dateRange_createCalendar(timezone, hour1, min1, -1);
412 cal2 = dateRange_createCalendar(timezone, hour2, min2, -1);
413 break;
414
415 default:
416 hour1 = getSmallInt(value1);
417 min1 = getSmallInt(value2);
418 second1 = getSmallInt(value3);
419 hour2 = getSmallInt(value4);
420 min2 = getSmallInt(value5);
421 second2 = getSmallInt(value6);
422 cal1 = dateRange_createCalendar(timezone, hour1, min1, second1);
423 cal2 = dateRange_createCalendar(timezone, hour2, min2, second2);
424 }
425
426 final Calendar now = Calendar.getInstance(timezone);
427 return now.equals(cal1) || now.after(cal1) && now.before(cal2) || now.equals(cal2);
428 }
429
430 private static Calendar timeRange_createCalendar(final TimeZone timezone,
431 final int hour, final int minute, final int second) {
432 final Calendar calendar = Calendar.getInstance(timezone);
433 if (hour != -1) {
434 calendar.set(Calendar.HOUR_OF_DAY, hour);
435 }
436 if (minute != -1) {
437 calendar.set(Calendar.MINUTE, minute);
438 }
439 if (second != -1) {
440 calendar.set(Calendar.SECOND, second);
441 }
442 return calendar;
443 }
444
445
446
447
448
449
450 @JsxFunction(functionName = "convert_addr")
451 public static long convertAddr(final String ip) {
452 final String[] parts = StringUtils.split(ip, '.');
453
454 return
455 ((Integer.parseInt(parts[0]) & 0xff) << 24)
456 | ((Integer.parseInt(parts[1]) & 0xff) << 16)
457 | ((Integer.parseInt(parts[2]) & 0xff) << 8)
458 | (Integer.parseInt(parts[3]) & 0xff);
459 }
460 }