• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KIO

  • kio
  • misc
  • kpac
script.cpp
Go to the documentation of this file.
1/*
2 Copyright (c) 2003 Malte Starostik <malte@kde.org>
3 Copyright (c) 2011 Dawit Alemayehu <adawit@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "script.h"
22
23#include <QtCore/QString>
24#include <QtCore/QRegExp>
25#include <QtCore/QDateTime>
26#include <QtCore/QTimer>
27#include <QtCore/QEventLoop>
28
29#include <QtNetwork/QHostInfo>
30#include <QtNetwork/QHostAddress>
31#include <QtNetwork/QNetworkInterface>
32
33#include <QtScript/QScriptValue>
34#include <QtScript/QScriptEngine>
35#include <QtScript/QScriptProgram>
36#include <QtScript/QScriptContextInfo>
37
38#include <kurl.h>
39#include <klocalizedstring.h>
40#include <kio/hostinfo_p.h>
41
42#define QL1S(x) QLatin1String(x)
43
44namespace
45{
46 static int findString (const QString& s, const char* const* values)
47 {
48 int index = 0;
49 const QString lower = s.toLower();
50 for (const char* const* p = values; *p; ++p, ++index) {
51 if (s.compare(QLatin1String(*p), Qt::CaseInsensitive) == 0) {
52 return index;
53 }
54 }
55 return -1;
56 }
57
58 static const QDateTime getTime (QScriptContext* context)
59 {
60 const QString tz = context->argument(context->argumentCount() - 1).toString();
61 if (tz.compare(QLatin1String("gmt"), Qt::CaseInsensitive) == 0) {
62 return QDateTime::currentDateTimeUtc();
63 }
64 return QDateTime::currentDateTime();
65 }
66
67 template <typename T>
68 static bool checkRange (T value, T min, T max)
69 {
70 return ((min <= max && value >= min && value <= max) ||
71 (min > max && (value <= min || value >= max)));
72 }
73
74 static bool isLocalHostAddress (const QHostAddress& address)
75 {
76 if (address == QHostAddress::LocalHost)
77 return true;
78
79 if (address == QHostAddress::LocalHostIPv6)
80 return true;
81
82 return false;
83 }
84
85 static bool isIPv6Address (const QHostAddress& address)
86 {
87 return address.protocol() == QAbstractSocket::IPv6Protocol;
88 }
89
90 static bool isIPv4Address (const QHostAddress& address)
91 {
92 return (address.protocol() == QAbstractSocket::IPv4Protocol);
93 }
94
95 static bool isSpecialAddress(const QHostAddress& address)
96 {
97 // Catch all the special addresses and return false.
98 if (address == QHostAddress::Null)
99 return true;
100
101 if (address == QHostAddress::Any)
102 return true;
103
104 if (address == QHostAddress::AnyIPv6)
105 return true;
106
107 if (address == QHostAddress::Broadcast)
108 return true;
109
110 return false;
111 }
112
113 static bool addressLessThanComparison(const QHostAddress& addr1, const QHostAddress& addr2)
114 {
115 if (addr1.protocol() == QAbstractSocket::IPv4Protocol &&
116 addr2.protocol() == QAbstractSocket::IPv4Protocol) {
117 return addr1.toIPv4Address() < addr2.toIPv4Address();
118 }
119
120 if (addr1.protocol() == QAbstractSocket::IPv6Protocol &&
121 addr2.protocol() == QAbstractSocket::IPv6Protocol) {
122 const Q_IPV6ADDR ipv6addr1 = addr1.toIPv6Address();
123 const Q_IPV6ADDR ipv6addr2 = addr2.toIPv6Address();
124 for (int i=0; i < 16; ++i) {
125 if (ipv6addr1[i] != ipv6addr2[i]) {
126 return ((ipv6addr1[i] & 0xff) - (ipv6addr2[i] & 0xff));
127 }
128 }
129 }
130
131 return false;
132 }
133
134 static QString addressListToString(const QList<QHostAddress>& addressList,
135 const QHash<QString, QString>& actualEntryMap)
136 {
137 QString result;
138 Q_FOREACH(const QHostAddress& address, addressList) {
139 if (!result.isEmpty()) {
140 result += QLatin1Char(';');
141 }
142 result += actualEntryMap.value(address.toString());
143 }
144 return result;
145 }
146
147 class Address
148 {
149 public:
150 struct Error {};
151 static Address resolve( const QString& host )
152 {
153 return Address( host );
154 }
155
156 QList<QHostAddress> addresses() const
157 {
158 return m_addressList;
159 }
160
161 QHostAddress address() const
162 {
163 if (m_addressList.isEmpty())
164 return QHostAddress();
165
166 return m_addressList.first();
167 }
168
169 private:
170 Address( const QString& host )
171 {
172 // Always try to see if it's already an IP first, to avoid Qt doing a
173 // needless reverse lookup
174 QHostAddress address ( host );
175 if ( address.isNull() ) {
176 QHostInfo hostInfo = KIO::HostInfo::lookupCachedHostInfoFor(host);
177 if (hostInfo.hostName().isEmpty() || hostInfo.error() != QHostInfo::NoError) {
178 hostInfo = QHostInfo::fromName(host);
179 KIO::HostInfo::cacheLookup(hostInfo);
180 }
181 m_addressList = hostInfo.addresses();
182 } else {
183 m_addressList.clear();
184 m_addressList.append(address);
185 }
186 }
187
188 QList<QHostAddress> m_addressList;
189 };
190
191
192 // isPlainHostName(host)
193 // @returns true if @p host doesn't contains a domain part
194 QScriptValue IsPlainHostName(QScriptContext* context, QScriptEngine* engine)
195 {
196 if (context->argumentCount() != 1) {
197 return engine->undefinedValue();
198 }
199 return engine->toScriptValue(context->argument(0).toString().indexOf(QLatin1Char('.')) == -1);
200 }
201
202 // dnsDomainIs(host, domain)
203 // @returns true if the domain part of @p host matches @p domain
204 QScriptValue DNSDomainIs (QScriptContext* context, QScriptEngine* engine)
205 {
206 if (context->argumentCount() != 2) {
207 return engine->undefinedValue();
208 }
209
210 const QString host = context->argument(0).toString();
211 const QString domain = context->argument(1).toString();
212 return engine->toScriptValue(host.endsWith(domain, Qt::CaseInsensitive));
213 }
214
215 // localHostOrDomainIs(host, fqdn)
216 // @returns true if @p host is unqualified or equals @p fqdn
217 QScriptValue LocalHostOrDomainIs (QScriptContext* context, QScriptEngine* engine)
218 {
219 if (context->argumentCount() != 2) {
220 return engine->undefinedValue();
221 }
222
223 const QString host = context->argument(0).toString();
224 if (!host.contains(QLatin1Char('.'))) {
225 return engine->toScriptValue(true);
226 }
227 const QString fqdn = context->argument(1).toString();
228 return engine->toScriptValue((host.compare(fqdn, Qt::CaseInsensitive) == 0));
229 }
230
231 // isResolvable(host)
232 // @returns true if host is resolvable to a IPv4 address.
233 QScriptValue IsResolvable (QScriptContext* context, QScriptEngine* engine)
234 {
235 if (context->argumentCount() != 1) {
236 return engine->undefinedValue();
237 }
238
239 try {
240 const Address info = Address::resolve(context->argument(0).toString());
241 bool hasResolvableIPv4Address = false;
242
243 Q_FOREACH(const QHostAddress& address, info.addresses()) {
244 if (!isSpecialAddress(address) && isIPv4Address(address)) {
245 hasResolvableIPv4Address = true;
246 break;
247 }
248 }
249
250 return engine->toScriptValue(hasResolvableIPv4Address);
251 }
252 catch (const Address::Error&) {
253 return engine->toScriptValue(false);
254 }
255 }
256
257 // isInNet(host, subnet, mask)
258 // @returns true if the IPv4 address of host is within the specified subnet
259 // and mask, false otherwise.
260 QScriptValue IsInNet (QScriptContext* context, QScriptEngine* engine)
261 {
262 if (context->argumentCount() != 3) {
263 return engine->undefinedValue();
264 }
265
266 try {
267 const Address info = Address::resolve(context->argument(0).toString());
268 bool isInSubNet = false;
269 QString subnetStr = context->argument(1).toString();
270 subnetStr += QLatin1Char('/');
271 subnetStr += context->argument(2).toString();
272 const QPair<QHostAddress, int> subnet = QHostAddress::parseSubnet(subnetStr);
273 Q_FOREACH(const QHostAddress& address, info.addresses()) {
274 if (!isSpecialAddress(address) && isIPv4Address(address) && address.isInSubnet(subnet)) {
275 isInSubNet = true;
276 break;
277 }
278 }
279 return engine->toScriptValue(isInSubNet);
280 }
281 catch (const Address::Error&) {
282 return engine->toScriptValue(false);
283 }
284 }
285
286 // dnsResolve(host)
287 // @returns the IPv4 address for host or an empty string if host is not resolvable.
288 QScriptValue DNSResolve (QScriptContext* context, QScriptEngine* engine)
289 {
290 if (context->argumentCount() != 1) {
291 return engine->undefinedValue();
292 }
293
294 try {
295 const Address info = Address::resolve(context->argument(0).toString());
296 QString resolvedAddress (QLatin1String(""));
297 Q_FOREACH(const QHostAddress& address, info.addresses()) {
298 if (!isSpecialAddress(address) && isIPv4Address(address)) {
299 resolvedAddress = address.toString();
300 break;
301 }
302 }
303 return engine->toScriptValue(resolvedAddress);
304 }
305 catch (const Address::Error&) {
306 return engine->toScriptValue(QString(QLatin1String("")));
307 }
308 }
309
310 // myIpAddress()
311 // @returns the local machine's IPv4 address. Note that this will return
312 // the address for the first interfaces that match its criteria even if the
313 // machine has multiple interfaces.
314 QScriptValue MyIpAddress (QScriptContext* context, QScriptEngine* engine)
315 {
316 if (context->argumentCount()) {
317 return engine->undefinedValue();
318 }
319
320 QString ipAddress;
321 const QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
322 Q_FOREACH(const QHostAddress address, addresses) {
323 if (isIPv4Address(address) && !isSpecialAddress(address) && !isLocalHostAddress(address)) {
324 ipAddress = address.toString();
325 break;
326 }
327 }
328
329 return engine->toScriptValue(ipAddress);
330 }
331
332 // dnsDomainLevels(host)
333 // @returns the number of dots ('.') in @p host
334 QScriptValue DNSDomainLevels (QScriptContext* context, QScriptEngine* engine)
335 {
336 if (context->argumentCount() != 1) {
337 return engine->undefinedValue();
338 }
339
340 const QString host = context->argument(0).toString();
341 if (host.isNull()) {
342 return engine->toScriptValue(0);
343 }
344
345 return engine->toScriptValue(host.count(QLatin1Char('.')));
346 }
347
348 // shExpMatch(str, pattern)
349 // @returns true if @p str matches the shell @p pattern
350 QScriptValue ShExpMatch (QScriptContext* context, QScriptEngine* engine)
351 {
352 if (context->argumentCount() != 2) {
353 return engine->undefinedValue();
354 }
355
356 QRegExp pattern(context->argument(1).toString(), Qt::CaseSensitive, QRegExp::Wildcard);
357 return engine->toScriptValue(pattern.exactMatch(context->argument(0).toString()));
358 }
359
360 // weekdayRange(day [, "GMT" ])
361 // weekdayRange(day1, day2 [, "GMT" ])
362 // @returns true if the current day equals day or between day1 and day2 resp.
363 // If the last argument is "GMT", GMT timezone is used, otherwise local time
364 QScriptValue WeekdayRange (QScriptContext* context, QScriptEngine* engine)
365 {
366 if (context->argumentCount() < 1 || context->argumentCount() > 3) {
367 return engine->undefinedValue();
368 }
369
370 static const char* const days[] = { "sun", "mon", "tue", "wed", "thu", "fri", "sat", 0 };
371
372 const int d1 = findString(context->argument(0).toString(), days);
373 if (d1 == -1) {
374 return engine->undefinedValue();
375 }
376
377 int d2 = findString(context->argument(1).toString(), days);
378 if (d2 == -1) {
379 d2 = d1;
380 }
381
382 // Adjust the days of week coming from QDateTime since it starts
383 // counting with Monday as 1 and ends with Sunday as day 7.
384 int dayOfWeek = getTime(context).date().dayOfWeek();
385 if (dayOfWeek == 7) {
386 dayOfWeek = 0;
387 }
388 return engine->toScriptValue(checkRange(dayOfWeek, d1, d2));
389 }
390
391 // dateRange(day [, "GMT" ])
392 // dateRange(day1, day2 [, "GMT" ])
393 // dateRange(month [, "GMT" ])
394 // dateRange(month1, month2 [, "GMT" ])
395 // dateRange(year [, "GMT" ])
396 // dateRange(year1, year2 [, "GMT" ])
397 // dateRange(day1, month1, day2, month2 [, "GMT" ])
398 // dateRange(month1, year1, month2, year2 [, "GMT" ])
399 // dateRange(day1, month1, year1, day2, month2, year2 [, "GMT" ])
400 // @returns true if the current date (GMT or local time according to
401 // presence of "GMT" as last argument) is within the given range
402 QScriptValue DateRange (QScriptContext* context, QScriptEngine* engine)
403 {
404 if (context->argumentCount() < 1 || context->argumentCount() > 7) {
405 return engine->undefinedValue();
406 }
407
408 static const char* const months[] = { "jan", "feb", "mar", "apr", "may", "jun",
409 "jul", "aug", "sep", "oct", "nov", "dec", 0 };
410
411 QVector<int> values;
412 for (int i = 0; i < context->argumentCount(); ++i)
413 {
414 int value = -1;
415 if (context->argument(i).isNumber()) {
416 value = context->argument(i).toInt32();
417 } else {
418 // QDate starts counting months from 1, so we add 1 here.
419 value = findString(context->argument(i).toString(), months) + 1;
420 }
421
422 if (value > 0) {
423 values.append(value);
424 } else {
425 break;
426 }
427 }
428
429 const QDate now = getTime(context).date();
430
431 // day1, month1, year1, day2, month2, year2
432 if (values.size() == 6) {
433 const QDate d1 (values[2], values[1], values[0]);
434 const QDate d2 (values[5], values[4], values[3]);
435 return engine->toScriptValue(checkRange(now, d1, d2));
436 }
437 // day1, month1, day2, month2
438 else if (values.size() == 4 && values[ 1 ] < 13 && values[ 3 ] < 13) {
439 const QDate d1 (now.year(), values[1], values[0]);
440 const QDate d2 (now.year(), values[3], values[2]);
441 return engine->toScriptValue(checkRange(now, d1, d2));
442 }
443 // month1, year1, month2, year2
444 else if (values.size() == 4) {
445 const QDate d1 (values[1], values[0], now.day());
446 const QDate d2 (values[3], values[2], now.day());
447 return engine->toScriptValue(checkRange(now, d1, d2));
448 }
449 // year1, year2
450 else if (values.size() == 2 && values[0] >= 1000 && values[1] >= 1000) {
451 return engine->toScriptValue(checkRange(now.year(), values[0], values[1]));
452 }
453 // day1, day2
454 else if (values.size() == 2 && context->argument(0).isNumber() && context->argument(1).isNumber()) {
455 return engine->toScriptValue(checkRange(now.day(), values[0], values[1]));
456 }
457 // month1, month2
458 else if (values.size() == 2) {
459 return engine->toScriptValue(checkRange(now.month(), values[0], values[1]));
460 }
461 // year
462 else if (values.size() == 1 && values[ 0 ] >= 1000) {
463 return engine->toScriptValue(checkRange(now.year(), values[0], values[0]));
464 }
465 // day
466 else if (values.size() == 1 && context->argument(0).isNumber()) {
467 return engine->toScriptValue(checkRange(now.day(), values[0], values[0]));
468 }
469 // month
470 else if (values.size() == 1) {
471 return engine->toScriptValue(checkRange(now.month(), values[0], values[0]));
472 }
473
474 return engine->undefinedValue();
475 }
476
477 // timeRange(hour [, "GMT" ])
478 // timeRange(hour1, hour2 [, "GMT" ])
479 // timeRange(hour1, min1, hour2, min2 [, "GMT" ])
480 // timeRange(hour1, min1, sec1, hour2, min2, sec2 [, "GMT" ])
481 // @returns true if the current time (GMT or local based on presence
482 // of "GMT" argument) is within the given range
483 QScriptValue TimeRange (QScriptContext* context, QScriptEngine* engine)
484 {
485 if (context->argumentCount() < 1 || context->argumentCount() > 7) {
486 return engine->undefinedValue();
487 }
488
489 QVector<int> values;
490 for (int i = 0; i < context->argumentCount(); ++i) {
491 if (!context->argument(i).isNumber()) {
492 break;
493 }
494 values.append(context->argument(i).toNumber());
495 }
496
497 const QTime now = getTime(context).time();
498
499 // hour1, min1, sec1, hour2, min2, sec2
500 if (values.size() == 6) {
501 const QTime t1 (values[0], values[1], values[2]);
502 const QTime t2 (values[3], values[4], values[5]);
503 return engine->toScriptValue(checkRange(now, t1, t2));
504 }
505 // hour1, min1, hour2, min2
506 else if (values.size() == 4) {
507 const QTime t1 (values[0], values[1]);
508 const QTime t2 (values[2], values[3]);
509 return engine->toScriptValue(checkRange(now, t1, t2));
510 }
511 // hour1, hour2
512 else if (values.size() == 2) {
513 return engine->toScriptValue(checkRange(now.hour(), values[0], values[1]));
514 }
515 // hour
516 else if (values.size() == 1) {
517 return engine->toScriptValue(checkRange(now.hour(), values[0], values[0]));
518 }
519
520 return engine->undefinedValue();
521 }
522
523
524 /*
525 * Implementation of Microsoft's IPv6 Extension for PAC
526 *
527 * Documentation:
528 * http://msdn.microsoft.com/en-us/library/gg308477(v=vs.85).aspx
529 * http://msdn.microsoft.com/en-us/library/gg308478(v=vs.85).aspx
530 * http://msdn.microsoft.com/en-us/library/gg308474(v=vs.85).aspx
531 * http://blogs.msdn.com/b/wndp/archive/2006/07/13/ipv6-pac-extensions-v0-9.aspx
532 */
533
534 // isResolvableEx(host)
535 // @returns true if host is resolvable to an IPv4 or IPv6 address.
536 QScriptValue IsResolvableEx (QScriptContext* context, QScriptEngine* engine)
537 {
538 if (context->argumentCount() != 1) {
539 return engine->undefinedValue();
540 }
541
542 try {
543 const Address info = Address::resolve(context->argument(0).toString());
544 bool hasResolvableIPAddress = false;
545 Q_FOREACH(const QHostAddress& address, info.addresses()) {
546 if (isIPv4Address(address) || isIPv6Address(address)) {
547 hasResolvableIPAddress = true;
548 break;
549 }
550 }
551 return engine->toScriptValue(hasResolvableIPAddress);
552 }
553 catch (const Address::Error&) {
554 return engine->toScriptValue(false);
555 }
556 }
557
558 // isInNetEx(ipAddress, ipPrefix )
559 // @returns true if ipAddress is within the specified ipPrefix.
560 QScriptValue IsInNetEx (QScriptContext* context, QScriptEngine* engine)
561 {
562 if (context->argumentCount() != 2) {
563 return engine->undefinedValue();
564 }
565
566 try {
567 const Address info = Address::resolve(context->argument(0).toString());
568 bool isInSubNet = false;
569 const QString subnetStr = context->argument(1).toString();
570 const QPair<QHostAddress, int> subnet = QHostAddress::parseSubnet(subnetStr);
571
572 Q_FOREACH(const QHostAddress& address, info.addresses()) {
573 if (isSpecialAddress(address)) {
574 continue;
575 }
576
577 if (address.isInSubnet(subnet)) {
578 isInSubNet = true;
579 break;
580 }
581 }
582 return engine->toScriptValue(isInSubNet);
583 }
584 catch (const Address::Error&) {
585 return engine->toScriptValue(false);
586 }
587 }
588
589 // dnsResolveEx(host)
590 // @returns a semi-colon delimited string containing IPv6 and IPv4 addresses
591 // for host or an empty string if host is not resolvable.
592 QScriptValue DNSResolveEx (QScriptContext* context, QScriptEngine* engine)
593 {
594 if (context->argumentCount() != 1) {
595 return engine->undefinedValue();
596 }
597
598 try {
599 const Address info = Address::resolve (context->argument(0).toString());
600
601 QStringList addressList;
602 QString resolvedAddress (QLatin1String(""));
603
604 Q_FOREACH(const QHostAddress& address, info.addresses()) {
605 if (!isSpecialAddress(address)) {
606 addressList << address.toString();
607 }
608 }
609 if (!addressList.isEmpty()) {
610 resolvedAddress = addressList.join(QLatin1String(";"));
611 }
612
613 return engine->toScriptValue(resolvedAddress);
614 }
615 catch (const Address::Error&) {
616 return engine->toScriptValue(QString(QLatin1String("")));
617 }
618 }
619
620 // myIpAddressEx()
621 // @returns a semi-colon delimited string containing all IP addresses for localhost (IPv6 and/or IPv4),
622 // or an empty string if unable to resolve localhost to an IP address.
623 QScriptValue MyIpAddressEx (QScriptContext* context, QScriptEngine* engine)
624 {
625 if (context->argumentCount()) {
626 return engine->undefinedValue();
627 }
628
629 QStringList ipAddressList;
630 const QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
631 Q_FOREACH(const QHostAddress address, addresses) {
632 if (!isSpecialAddress(address) && !isLocalHostAddress(address)) {
633 ipAddressList << address.toString();
634 }
635 }
636
637 return engine->toScriptValue(ipAddressList.join(QLatin1String(";")));
638 }
639
640 // sortIpAddressList(ipAddressList)
641 // @returns a sorted ipAddressList. If both IPv4 and IPv6 addresses are present in
642 // the list. The sorted IPv6 addresses will precede the sorted IPv4 addresses.
643 QScriptValue SortIpAddressList(QScriptContext* context, QScriptEngine* engine)
644 {
645 if (context->argumentCount() != 1) {
646 return engine->undefinedValue();
647 }
648
649 QHash<QString, QString> actualEntryMap;
650 QList<QHostAddress> ipV4List, ipV6List;
651 const QStringList ipAddressList = context->argument(0).toString().split(QLatin1Char(';'));
652
653 Q_FOREACH(const QString& ipAddress, ipAddressList) {
654 QHostAddress address(ipAddress);
655 switch (address.protocol()) {
656 case QAbstractSocket::IPv4Protocol:
657 ipV4List << address;
658 actualEntryMap.insert(address.toString(), ipAddress);
659 break;
660 case QAbstractSocket::IPv6Protocol:
661 ipV6List << address;
662 actualEntryMap.insert(address.toString(), ipAddress);
663 break;
664 default:
665 break;
666 }
667 }
668
669 QString sortedAddress (QLatin1String(""));
670
671 if (!ipV6List.isEmpty()) {
672 qSort(ipV6List.begin(), ipV6List.end(), addressLessThanComparison);
673 sortedAddress += addressListToString(ipV6List, actualEntryMap);
674 }
675
676 if (!ipV4List.isEmpty()) {
677 qSort(ipV4List.begin(), ipV4List.end(), addressLessThanComparison);
678 if (!sortedAddress.isEmpty()) {
679 sortedAddress += QLatin1Char(';');
680 }
681 sortedAddress += addressListToString(ipV4List, actualEntryMap);
682 }
683
684 return engine->toScriptValue(sortedAddress);
685
686 }
687
688 // getClientVersion
689 // @return the version number of this engine for future extension. We too start
690 // this at version 1.0.
691 QScriptValue GetClientVersion (QScriptContext* context, QScriptEngine* engine)
692 {
693 if (context->argumentCount()) {
694 return engine->undefinedValue();
695 }
696
697 const QString version (QLatin1String("1.0"));
698 return engine->toScriptValue(version);
699 }
700
701 void registerFunctions(QScriptEngine* engine)
702 {
703 QScriptValue value = engine->globalObject();
704 value.setProperty(QL1S("isPlainHostName"), engine->newFunction(IsPlainHostName));
705 value.setProperty(QL1S("dnsDomainIs"), engine->newFunction(DNSDomainIs));
706 value.setProperty(QL1S("localHostOrDomainIs"), engine->newFunction(LocalHostOrDomainIs));
707 value.setProperty(QL1S("isResolvable"), engine->newFunction(IsResolvable));
708 value.setProperty(QL1S("isInNet"), engine->newFunction(IsInNet));
709 value.setProperty(QL1S("dnsResolve"), engine->newFunction(DNSResolve));
710 value.setProperty(QL1S("myIpAddress"), engine->newFunction(MyIpAddress));
711 value.setProperty(QL1S("dnsDomainLevels"), engine->newFunction(DNSDomainLevels));
712 value.setProperty(QL1S("shExpMatch"), engine->newFunction(ShExpMatch));
713 value.setProperty(QL1S("weekdayRange"), engine->newFunction(WeekdayRange));
714 value.setProperty(QL1S("dateRange"), engine->newFunction(DateRange));
715 value.setProperty(QL1S("timeRange"), engine->newFunction(TimeRange));
716
717 // Microsoft's IPv6 PAC Extensions...
718 value.setProperty(QL1S("isResolvableEx"), engine->newFunction(IsResolvableEx));
719 value.setProperty(QL1S("isInNetEx"), engine->newFunction(IsInNetEx));
720 value.setProperty(QL1S("dnsResolveEx"), engine->newFunction(DNSResolveEx));
721 value.setProperty(QL1S("myIpAddressEx"), engine->newFunction(MyIpAddressEx));
722 value.setProperty(QL1S("sortIpAddressList"), engine->newFunction(SortIpAddressList));
723 value.setProperty(QL1S("getClientVersion"), engine->newFunction(GetClientVersion));
724 }
725}
726
727namespace KPAC
728{
729 Script::Script(const QString& code)
730 {
731 m_engine = new QScriptEngine;
732 registerFunctions(m_engine);
733
734 QScriptProgram program (code);
735 const QScriptValue result = m_engine->evaluate(program);
736 if (m_engine->hasUncaughtException() || result.isError())
737 throw Error(m_engine->uncaughtException().toString());
738 }
739
740 Script::~Script()
741 {
742 delete m_engine;
743 }
744
745 QString Script::evaluate(const KUrl& url)
746 {
747 QScriptValue func = m_engine->globalObject().property(QL1S("FindProxyForURL"));
748
749 if (!func.isValid()) {
750 func = m_engine->globalObject().property(QL1S("FindProxyForURLEx"));
751 if (!func.isValid()) {
752 throw Error(i18n("Could not find 'FindProxyForURL' or 'FindProxyForURLEx'"));
753 return QString();
754 }
755 }
756
757 KUrl cleanUrl = url;
758 cleanUrl.setUserInfo(QString());
759 if (cleanUrl.scheme().toLower() == QLatin1String("https")) {
760 cleanUrl.setPath(QString());
761 cleanUrl.setQuery(QString());
762 }
763
764 QScriptValueList args;
765 args << cleanUrl.url();
766 args << cleanUrl.host();
767
768 QScriptValue result = func.call(QScriptValue(), args);
769 if (result.isError()) {
770 throw Error(i18n("Got an invalid reply when calling %1", func.toString()));
771 }
772
773 return result.toString();
774 }
775}
776
777// vim: ts=4 sw=4 et
QL1S
#define QL1S(x)
Definition: accessmanager.cpp:51
KPAC::Script::Error
Definition: script.h:36
KPAC::Script::Script
Script(const QString &code)
Definition: script.cpp:729
KPAC::Script::~Script
~Script()
Definition: script.cpp:740
KPAC::Script::evaluate
QString evaluate(const KUrl &)
Definition: script.cpp:745
KUrl
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::setPath
void setPath(const QString &path)
KUrl::setQuery
void setQuery(const QString &query)
QHash
QList
QPair
hostinfo_p.h
klocalizedstring.h
i18n
QString i18n(const char *text)
T
#define T
kurl.h
KIO::HostInfo::lookupCachedHostInfoFor
QHostInfo lookupCachedHostInfoFor(const QString &hostName)
Definition: hostinfo.cpp:282
KIO::HostInfo::cacheLookup
void cacheLookup(const QHostInfo &info)
Definition: hostinfo.cpp:287
KPAC
Definition: discovery.cpp:58
Address
Address
QL1S
#define QL1S(x)
Definition: script.cpp:42
script.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal