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

KIO

  • sources
  • kde-4.14
  • kdelibs
  • 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 
44 namespace
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 
727 namespace 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
KPAC::Script::evaluate
QString evaluate(const KUrl &)
Definition: script.cpp:745
i18n
QString i18n(const char *text)
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QHash::insert
iterator insert(const Key &key, const T &value)
QHostAddress
kurl.h
QVector::append
void append(const T &value)
T
#define T
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QHostAddress::parseSubnet
QPair< QHostAddress, int > parseSubnet(const QString &subnet)
QScriptValue
QL1S
#define QL1S(x)
Definition: script.cpp:42
QUrl::host
QString host() const
QScriptEngine::evaluate
QScriptValue evaluate(const QString &program, const QString &fileName, int lineNumber)
QScriptValue::isNumber
bool isNumber() const
QScriptEngine::hasUncaughtException
bool hasUncaughtException() const
QHostAddress::toString
QString toString() const
QStringList::join
QString join(const QString &separator) const
KPAC::Script::~Script
~Script()
Definition: script.cpp:740
QDate::month
int month() const
QScriptContext::argumentCount
int argumentCount() const
QTime
script.h
QScriptValue::call
QScriptValue call(const QScriptValue &thisObject, const QScriptValueList &args)
QScriptValue::toString
QString toString() const
KUrl
KUrl::setQuery
void setQuery(const QString &query)
QString::isNull
bool isNull() const
QNetworkInterface::allAddresses
QList< QHostAddress > allAddresses()
KUrl::setPath
void setPath(const QString &path)
QRegExp
QScriptEngine
QScriptEngine::toScriptValue
QScriptValue toScriptValue(const T &value)
QScriptEngine::uncaughtException
QScriptValue uncaughtException() const
KImageIO::pattern
QString pattern(Mode mode=Reading)
Returns a list of patterns of all KImageIO supported formats.
Definition: kimageio.cpp:16
QHash< QString, QString >
Address
QList::isEmpty
bool isEmpty() const
QString::isEmpty
bool isEmpty() const
QDate::day
int day() const
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
QDate
QDate::year
int year() const
QString
QList
QScriptContext
QUrl::scheme
QString scheme() const
QScriptValue::property
QScriptValue property(const QString &name, const ResolveFlags &mode) const
QStringList
QPair
QTime::hour
int hour() const
KPAC::Script::Error
Definition: script.h:35
QScriptProgram
QList::end
iterator end()
QString::toLower
QString toLower() const
QHash::value
const T value(const Key &key) const
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QLatin1Char
KIO::HostInfo::cacheLookup
void cacheLookup(const QHostInfo &info)
Definition: hostinfo.cpp:287
QHostAddress::toIPv4Address
quint32 toIPv4Address() const
QHostAddress::toIPv6Address
Q_IPV6ADDR toIPv6Address() const
QHostInfo::fromName
QHostInfo fromName(const QString &name)
QScriptValue::toInt32
qint32 toInt32() const
QDateTime::currentDateTime
QDateTime currentDateTime()
QHostInfo::addresses
QList< QHostAddress > addresses() const
QVector
QLatin1String
klocalizedstring.h
QHostAddress::protocol
QAbstractSocket::NetworkLayerProtocol protocol() const
version
unsigned int version()
QString::count
int count() const
QScriptValue::isValid
bool isValid() const
QScriptValue::isError
bool isError() const
KIO::HostInfo::lookupCachedHostInfoFor
QHostInfo lookupCachedHostInfoFor(const QString &hostName)
Definition: hostinfo.cpp:282
QScriptContext::argument
QScriptValue argument(int index) const
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
KPAC::Script::Script
Script(const QString &code)
Definition: script.cpp:729
hostinfo_p.h
QHostAddress::isNull
bool isNull() const
QHostInfo::error
HostInfoError error() const
QVector::size
int size() const
QUrl::setUserInfo
void setUserInfo(const QString &userInfo)
QScriptEngine::undefinedValue
QScriptValue undefinedValue()
QScriptEngine::newFunction
QScriptValue newFunction(FunctionSignature fun, int length)
QScriptEngine::globalObject
QScriptValue globalObject() const
QString::compare
int compare(const QString &other) const
QHostInfo
QHostAddress::isInSubnet
bool isInSubnet(const QHostAddress &subnet, int netmask) const
QList::begin
iterator begin()
QDateTime::currentDateTimeUtc
QDateTime currentDateTimeUtc()
QDateTime
QScriptValue::toNumber
qsreal toNumber() const
QHostInfo::hostName
QString hostName() const
QScriptValue::setProperty
void setProperty(const QString &name, const QScriptValue &value, const PropertyFlags &flags)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:24:53 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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