~ubuntu-branches/ubuntu/quantal/kde4libs/quantal

« back to all changes in this revision

Viewing changes to .pc/kubuntu_useragent.diff/kio/kio/kprotocolmanager.cpp

  • Committer: Package Import Robot
  • Author(s): Felix Geyer, Philip Muškovac, Jonathan Thomas, Felix Geyer
  • Date: 2011-05-29 17:19:55 UTC
  • mfrom: (1.14.5 upstream) (0.1.19 sid)
  • Revision ID: package-import@ubuntu.com-20110529171955-nodep1593tuwyu6k
Tags: 4:4.6.3-1ubuntu1
[ Philip Muškovac]
* Drop kubuntu_83_fix_solid_network_status.diff
* Update Vcs links as the branch is owned by kubuntu-packagers now

[ Jonathan Thomas ]
* Drop kubuntu_06_user_disk_mounting. We no longer compile the hal
  backend, so this patch is useless.

[ Felix Geyer ]
* Merge from Debian unstable, remaining changes:
  - no build-dep on libaspell-dev
  - no build-dep on libfam-dev
  - kdelibs5-data: don't install kspell_aspell.desktop and
    usr/lib/kde4/kspell_aspell.so
  - kdelibs5-dev: don't install preparetips
  - Pass -DKDESU_USE_SUDO_DEFAULT=true to configure
  - dh_fixperms: exclude /usr/lib/kde4/libexec/fileshareset
  - set export KUBUNTU_DESKTOP_POT=kdelibs
  - don't apply use_dejavu_as_default_font.diff
  - don't apply kconf_update_migrate_from_kde3_icon_theme.diff
    - kdelibs5-data.install: drop usr/share/kde4/apps/kconf_update/kdeui.upd
  - don't build depend on libglu1-mesa-dev, not needed due to
    kubuntu_no_direct_gl_usage.diff
  - Add kdelibs5-data.links: link from /usr/share/doc/kde4 to kde for
    backwards compatible with old docs location
  - Keep the kdelibs5 transitional package
  - kdelibs5-dev.install: install ksambasharedata.h
  - kdelibs5-plugins: recommend ttf-dejavu-core instead of ttf-dejavu to save
    CD space.
* Add Breaks in addition to Replaces for moving files between packages.
* Drop no longer needed Breaks and Replaces.
* Completely drop kubuntu_51_launchpad_integration.diff and
  kubuntu_68_remove_applet_confirmation.diff.
  + Also drop the launchpad and kubuntu icons.
* Remove sequence numbers from kubuntu patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of the KDE libraries
 
2
   Copyright (C) 1999 Torben Weis <weis@kde.org>
 
3
   Copyright (C) 2000- Waldo Bastain <bastain@kde.org>
 
4
   Copyright (C) 2000- Dawit Alemayehu <adawit@kde.org>
 
5
   Copyright (C) 2008 Jarosław Staniek <staniek@kde.org>
 
6
 
 
7
   This library is free software; you can redistribute it and/or
 
8
   modify it under the terms of the GNU Library General Public
 
9
   License version 2 as published by the Free Software Foundation.
 
10
 
 
11
   This library is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
   Library General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU Library General Public License
 
17
   along with this library; see the file COPYING.LIB.  If not, write to
 
18
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
19
   Boston, MA 02110-1301, USA.
 
20
*/
 
21
 
 
22
#include "kprotocolmanager.h"
 
23
 
 
24
#include <string.h>
 
25
#include <unistd.h>
 
26
#include <sys/utsname.h>
 
27
 
 
28
#include <QtCore/QCoreApplication>
 
29
#include <QtCore/QStringBuilder>
 
30
#include <QtNetwork/QSslSocket>
 
31
#include <QtDBus/QtDBus>
 
32
 
 
33
#include <kdeversion.h>
 
34
#include <kdebug.h>
 
35
#include <kglobal.h>
 
36
#include <klocale.h>
 
37
#include <kconfiggroup.h>
 
38
#include <ksharedconfig.h>
 
39
#include <kstandarddirs.h>
 
40
#include <kstringhandler.h>
 
41
#include <kurl.h>
 
42
#include <kmimetypetrader.h>
 
43
#include <kio/slaveconfig.h>
 
44
#include <kio/ioslave_defaults.h>
 
45
#include <kio/http_slave_defaults.h>
 
46
#include <kprotocolinfofactory.h>
 
47
 
 
48
#define QL1S(x)   QLatin1String(x)
 
49
#define QL1C(x)   QLatin1Char(x)
 
50
 
 
51
class
 
52
KProtocolManagerPrivate
 
53
{
 
54
public:
 
55
   KProtocolManagerPrivate();
 
56
 
 
57
   ~KProtocolManagerPrivate();
 
58
 
 
59
   KSharedConfig::Ptr config;
 
60
   KSharedConfig::Ptr http_config;
 
61
   KUrl url;
 
62
   QString protocol;
 
63
   QString proxy;
 
64
   QString modifiers;
 
65
   QString useragent;
 
66
 
 
67
    QMap<QString /*mimetype*/, QString /*protocol*/> protocolForArchiveMimetypes;
 
68
};
 
69
 
 
70
K_GLOBAL_STATIC(KProtocolManagerPrivate, kProtocolManagerPrivate)
 
71
 
 
72
KProtocolManagerPrivate::KProtocolManagerPrivate()
 
73
{
 
74
    // post routine since KConfig::sync() breaks if called too late
 
75
    qAddPostRoutine(kProtocolManagerPrivate.destroy);
 
76
}
 
77
 
 
78
KProtocolManagerPrivate::~KProtocolManagerPrivate()
 
79
{
 
80
    qRemovePostRoutine(kProtocolManagerPrivate.destroy);
 
81
}
 
82
 
 
83
 
 
84
// DEFAULT USERAGENT STRING
 
85
#define CFG_DEFAULT_UAGENT(X) \
 
86
QL1S("Mozilla/5.0 (compatible; Konqueror/") % \
 
87
QString::number(KDE::versionMajor()) % QL1C('.') % QString::number(KDE::versionMinor()) % \
 
88
X % QL1S(") KHTML/") % \
 
89
QString::number(KDE::versionMajor()) % QL1C('.') % QString::number(KDE::versionMinor()) % \
 
90
QL1C('.') % QString::number(KDE::versionRelease()) % QL1S(" (like Gecko)")
 
91
 
 
92
#define PRIVATE_DATA \
 
93
KProtocolManagerPrivate *d = kProtocolManagerPrivate
 
94
 
 
95
void KProtocolManager::reparseConfiguration()
 
96
{
 
97
    PRIVATE_DATA;
 
98
    if (d->http_config) {
 
99
        d->http_config->reparseConfiguration();
 
100
    }
 
101
    if (d->config) {
 
102
        d->config->reparseConfiguration();
 
103
    }
 
104
    d->protocol.clear();
 
105
    d->proxy.clear();
 
106
    d->modifiers.clear();
 
107
    d->useragent.clear();
 
108
    d->url.clear();
 
109
 
 
110
  // Force the slave config to re-read its config...
 
111
  KIO::SlaveConfig::self()->reset ();
 
112
}
 
113
 
 
114
KSharedConfig::Ptr KProtocolManager::config()
 
115
{
 
116
    PRIVATE_DATA;
 
117
  if (!d->config)
 
118
  {
 
119
     d->config = KSharedConfig::openConfig("kioslaverc", KConfig::NoGlobals);
 
120
  }
 
121
  return d->config;
 
122
}
 
123
 
 
124
static KConfigGroup http_config()
 
125
{
 
126
    PRIVATE_DATA;
 
127
  if (!d->http_config) {
 
128
     d->http_config = KSharedConfig::openConfig("kio_httprc", KConfig::NoGlobals);
 
129
  }
 
130
  return KConfigGroup(d->http_config, QString());
 
131
}
 
132
 
 
133
/*=============================== TIMEOUT SETTINGS ==========================*/
 
134
 
 
135
int KProtocolManager::readTimeout()
 
136
{
 
137
  KConfigGroup cg( config(), QString() );
 
138
  int val = cg.readEntry( "ReadTimeout", DEFAULT_READ_TIMEOUT );
 
139
  return qMax(MIN_TIMEOUT_VALUE, val);
 
140
}
 
141
 
 
142
int KProtocolManager::connectTimeout()
 
143
{
 
144
  KConfigGroup cg( config(), QString() );
 
145
  int val = cg.readEntry( "ConnectTimeout", DEFAULT_CONNECT_TIMEOUT );
 
146
  return qMax(MIN_TIMEOUT_VALUE, val);
 
147
}
 
148
 
 
149
int KProtocolManager::proxyConnectTimeout()
 
150
{
 
151
  KConfigGroup cg( config(), QString() );
 
152
  int val = cg.readEntry( "ProxyConnectTimeout", DEFAULT_PROXY_CONNECT_TIMEOUT );
 
153
  return qMax(MIN_TIMEOUT_VALUE, val);
 
154
}
 
155
 
 
156
int KProtocolManager::responseTimeout()
 
157
{
 
158
  KConfigGroup cg( config(), QString() );
 
159
  int val = cg.readEntry( "ResponseTimeout", DEFAULT_RESPONSE_TIMEOUT );
 
160
  return qMax(MIN_TIMEOUT_VALUE, val);
 
161
}
 
162
 
 
163
/*========================== PROXY SETTINGS =================================*/
 
164
 
 
165
bool KProtocolManager::useProxy()
 
166
{
 
167
  return proxyType() != NoProxy;
 
168
}
 
169
 
 
170
bool KProtocolManager::useReverseProxy()
 
171
{
 
172
  KConfigGroup cg(config(), "Proxy Settings" );
 
173
  return cg.readEntry("ReversedException", false);
 
174
}
 
175
 
 
176
KProtocolManager::ProxyType KProtocolManager::proxyType()
 
177
{
 
178
  KConfigGroup cg(config(), "Proxy Settings" );
 
179
  return static_cast<ProxyType>(cg.readEntry( "ProxyType" , 0));
 
180
}
 
181
 
 
182
KProtocolManager::ProxyAuthMode KProtocolManager::proxyAuthMode()
 
183
{
 
184
  KConfigGroup cg(config(), "Proxy Settings" );
 
185
  return static_cast<ProxyAuthMode>(cg.readEntry( "AuthMode" , 0));
 
186
}
 
187
 
 
188
/*========================== CACHING =====================================*/
 
189
 
 
190
bool KProtocolManager::useCache()
 
191
{
 
192
  return http_config().readEntry( "UseCache", true );
 
193
}
 
194
 
 
195
KIO::CacheControl KProtocolManager::cacheControl()
 
196
{
 
197
  QString tmp = http_config().readEntry("cache");
 
198
  if (tmp.isEmpty())
 
199
    return DEFAULT_CACHE_CONTROL;
 
200
  return KIO::parseCacheControl(tmp);
 
201
}
 
202
 
 
203
QString KProtocolManager::cacheDir()
 
204
{
 
205
  return http_config().readPathEntry("CacheDir", KGlobal::dirs()->saveLocation("cache","http"));
 
206
}
 
207
 
 
208
int KProtocolManager::maxCacheAge()
 
209
{
 
210
  return http_config().readEntry( "MaxCacheAge", DEFAULT_MAX_CACHE_AGE ); // 14 days
 
211
}
 
212
 
 
213
int KProtocolManager::maxCacheSize()
 
214
{
 
215
  return http_config().readEntry( "MaxCacheSize", DEFAULT_MAX_CACHE_SIZE ); // 5 MB
 
216
}
 
217
 
 
218
QString KProtocolManager::noProxyFor()
 
219
{
 
220
  KProtocolManager::ProxyType type = proxyType();
 
221
 
 
222
  QString noProxy = config()->group("Proxy Settings").readEntry( "NoProxyFor" );
 
223
  if (type == EnvVarProxy)
 
224
    noProxy = QString::fromLocal8Bit(qgetenv(noProxy.toLocal8Bit()));
 
225
 
 
226
  return noProxy;
 
227
}
 
228
 
 
229
QString KProtocolManager::proxyFor( const QString& protocol )
 
230
{
 
231
  QString key = protocol.toLower();
 
232
 
 
233
  if (key == QL1S("webdav"))
 
234
    key = QL1S("http");
 
235
  else if (key == QL1S("webdavs"))
 
236
    key = QL1S("https");
 
237
 
 
238
  key += QL1S("Proxy");
 
239
 
 
240
  return config()->group("Proxy Settings").readEntry(key, QString());
 
241
}
 
242
 
 
243
QString KProtocolManager::proxyForUrl( const KUrl &url )
 
244
{
 
245
  QString proxy;
 
246
  ProxyType pt = proxyType();
 
247
 
 
248
  switch (pt)
 
249
  {
 
250
      case PACProxy:
 
251
      case WPADProxy:
 
252
          if (!url.host().isEmpty())
 
253
          {
 
254
            KUrl u (url);
 
255
            QString p = u.protocol().toLower();
 
256
 
 
257
            // webdav is a KDE specific protocol. Look up proxy
 
258
            // information using HTTP instead...
 
259
            if (p == QL1S("webdav"))
 
260
            {
 
261
              p = QL1S("http");
 
262
              u.setProtocol(p);
 
263
            }
 
264
            else if (p == QL1S("webdavs"))
 
265
            {
 
266
              p = QL1S("https");
 
267
              u.setProtocol(p);
 
268
            }
 
269
 
 
270
            if (p.startsWith(QL1S("http")) || p.startsWith(QL1S("ftp")))
 
271
            {
 
272
              QDBusReply<QString> reply = QDBusInterface(QL1S("org.kde.kded"),
 
273
                                                         QL1S("/modules/proxyscout"),
 
274
                                                         QL1S("org.kde.KPAC.ProxyScout"))
 
275
                                          .call(QL1S("proxyForUrl"), u.url() );
 
276
              proxy = reply;
 
277
            }
 
278
          }
 
279
          break;
 
280
      case EnvVarProxy:
 
281
          proxy = QString::fromLocal8Bit(qgetenv(proxyFor(url.protocol()).toLocal8Bit())).trimmed();
 
282
          break;
 
283
      case ManualProxy:
 
284
          proxy = proxyFor( url.protocol() );
 
285
          break;
 
286
      case NoProxy:
 
287
      default:
 
288
          break;
 
289
  }
 
290
 
 
291
  return (proxy.isEmpty() ? QL1S("DIRECT") : proxy);
 
292
}
 
293
 
 
294
void KProtocolManager::badProxy( const QString &proxy )
 
295
{
 
296
  QDBusInterface( QL1S("org.kde.kded"), QL1S("/modules/proxyscout"))
 
297
      .call(QL1S("blackListProxy"), proxy);
 
298
}
 
299
 
 
300
/*
 
301
    Domain suffix match. E.g. return true if host is "cuzco.inka.de" and
 
302
    nplist is "inka.de,hadiko.de" or if host is "localhost" and nplist is
 
303
    "localhost".
 
304
*/
 
305
static bool revmatch(const char *host, const char *nplist)
 
306
{
 
307
  if (host == 0)
 
308
    return false;
 
309
 
 
310
  const char *hptr = host + strlen( host ) - 1;
 
311
  const char *nptr = nplist + strlen( nplist ) - 1;
 
312
  const char *shptr = hptr;
 
313
 
 
314
  while ( nptr >= nplist )
 
315
  {
 
316
    if ( *hptr != *nptr )
 
317
    {
 
318
      hptr = shptr;
 
319
 
 
320
      // Try to find another domain or host in the list
 
321
      while(--nptr>=nplist && *nptr!=',' && *nptr!=' ') ;
 
322
 
 
323
      // Strip out multiple spaces and commas
 
324
      while(--nptr>=nplist && (*nptr==',' || *nptr==' ')) ;
 
325
    }
 
326
    else
 
327
    {
 
328
      if ( nptr==nplist || nptr[-1]==',' || nptr[-1]==' ')
 
329
        return true;
 
330
      if ( nptr[-1]=='/' && hptr == host ) // "bugs.kde.org" vs "http://bugs.kde.org", the config UI says URLs are ok
 
331
        return true;
 
332
      if ( hptr == host ) // e.g. revmatch("bugs.kde.org","mybugs.kde.org")
 
333
        return false;
 
334
 
 
335
      hptr--;
 
336
      nptr--;
 
337
    }
 
338
  }
 
339
 
 
340
  return false;
 
341
}
 
342
 
 
343
QString KProtocolManager::slaveProtocol(const KUrl &url, QString &proxy)
 
344
{
 
345
  if (url.hasSubUrl()) // We don't want the suburl's protocol
 
346
  {
 
347
     KUrl::List list = KUrl::split(url);
 
348
     KUrl l = list.last();
 
349
     return slaveProtocol(l, proxy);
 
350
  }
 
351
 
 
352
    PRIVATE_DATA;
 
353
  if (d->url == url)
 
354
  {
 
355
     proxy = d->proxy;
 
356
     return d->protocol;
 
357
  }
 
358
 
 
359
  if (useProxy())
 
360
  {
 
361
     proxy = proxyForUrl(url);
 
362
     if ((proxy != "DIRECT") && (!proxy.isEmpty()))
 
363
     {
 
364
        bool isRevMatch = false;
 
365
        KProtocolManager::ProxyType type = proxyType();
 
366
        bool useRevProxy = ((type == ManualProxy) && useReverseProxy());
 
367
 
 
368
        QString noProxy;
 
369
        // Check no proxy information iff the proxy type is either
 
370
        // manual or environment variable based...
 
371
        if ( (type == ManualProxy) || (type == EnvVarProxy) )
 
372
          noProxy = noProxyFor();
 
373
 
 
374
        if (!noProxy.isEmpty())
 
375
        {
 
376
           QString qhost = url.host().toLower();
 
377
           QByteArray host = qhost.toLatin1();
 
378
           QString qno_proxy = noProxy.trimmed().toLower();
 
379
           const QByteArray no_proxy = qno_proxy.toLatin1();
 
380
           isRevMatch = revmatch(host, no_proxy);
 
381
 
 
382
           // If no match is found and the request url has a port
 
383
           // number, try the combination of "host:port". This allows
 
384
           // users to enter host:port in the No-proxy-For list.
 
385
           if (!isRevMatch && url.port() > 0)
 
386
           {
 
387
              qhost += QL1C(':');
 
388
              qhost += QString::number(url.port());
 
389
              host = qhost.toLatin1();
 
390
              isRevMatch = revmatch (host, no_proxy);
 
391
           }
 
392
 
 
393
           // If the hostname does not contain a dot, check if
 
394
           // <local> is part of noProxy.
 
395
           if (!isRevMatch && !host.isEmpty() && (strchr(host, '.') == NULL))
 
396
              isRevMatch = revmatch("<local>", no_proxy);
 
397
        }
 
398
 
 
399
        if ( (!useRevProxy && !isRevMatch) || (useRevProxy && isRevMatch) )
 
400
        {
 
401
           d->url = proxy;
 
402
           if (d->url.isValid() && !d->url.protocol().isEmpty())
 
403
           {
 
404
              // The idea behind slave protocols is not applicable to http
 
405
              // and webdav protocols.
 
406
              const QString protocol = url.protocol().toLower();
 
407
              if (protocol.startsWith(QL1S("http")) || protocol.startsWith(QL1S("webdav")) ||
 
408
                  !KProtocolInfo::isKnownProtocol(protocol))
 
409
                d->protocol = protocol;
 
410
              else
 
411
              {
 
412
                d->protocol = d->url.protocol();
 
413
                kDebug () << "slaveProtocol: " << d->protocol;
 
414
              }
 
415
 
 
416
              d->url = url;
 
417
              d->proxy = proxy;
 
418
              return d->protocol;
 
419
           }
 
420
        }
 
421
     }
 
422
  }
 
423
 
 
424
  d->url = url;
 
425
  d->proxy.clear(); proxy.clear();
 
426
  d->protocol = url.protocol();
 
427
  return d->protocol;
 
428
}
 
429
 
 
430
/*================================= USER-AGENT SETTINGS =====================*/
 
431
 
 
432
QString KProtocolManager::userAgentForHost( const QString& hostname )
 
433
{
 
434
  const QString sendUserAgent = KIO::SlaveConfig::self()->configData("http", hostname.toLower(), "SendUserAgent").toLower();
 
435
  if (sendUserAgent == QL1S("false"))
 
436
     return QString();
 
437
 
 
438
  const QString useragent = KIO::SlaveConfig::self()->configData("http", hostname.toLower(), "UserAgent");
 
439
 
 
440
  // Return the default user-agent if none is specified
 
441
  // for the requested host.
 
442
  if (useragent.isEmpty())
 
443
    return defaultUserAgent();
 
444
 
 
445
  return useragent;
 
446
}
 
447
 
 
448
QString KProtocolManager::defaultUserAgent( )
 
449
{
 
450
  const QString modifiers = KIO::SlaveConfig::self()->configData("http", QString(), "UserAgentKeys");
 
451
  return defaultUserAgent(modifiers);
 
452
}
 
453
 
 
454
static QString defaultUserAgentFromPreferredService()
 
455
{
 
456
  QString agentStr;
 
457
 
 
458
  // Check if the default COMPONENT contains a custom default UA string...
 
459
  KService::Ptr service = KMimeTypeTrader::self()->preferredService(QL1S("text/html"),
 
460
                                                      QL1S("KParts/ReadOnlyPart"));
 
461
  if (service && service->showInKDE())
 
462
    agentStr = service->property(QL1S("X-KDE-Default-UserAgent"),
 
463
                                 QVariant::String).toString();
 
464
  return agentStr;
 
465
}
 
466
 
 
467
QString KProtocolManager::defaultUserAgent( const QString &_modifiers )
 
468
{
 
469
    PRIVATE_DATA;
 
470
  QString modifiers = _modifiers.toLower();
 
471
  if (modifiers.isEmpty())
 
472
    modifiers = DEFAULT_USER_AGENT_KEYS;
 
473
 
 
474
  if (d->modifiers == modifiers && !d->useragent.isEmpty())
 
475
    return d->useragent;
 
476
 
 
477
  d->modifiers = modifiers;
 
478
 
 
479
  /*
 
480
     The following code attempts to determine the default user agent string
 
481
     from the 'X-KDE-UA-DEFAULT-STRING' property of the desktop file
 
482
     for the preferred service that was configured to handle the 'text/html'
 
483
     mime type. If the prefered service's desktop file does not specify this
 
484
     property, the long standing default user agent string will be used.
 
485
     The following keyword placeholders are automatically converted when the
 
486
     user agent string is read from the property:
 
487
 
 
488
     %SECURITY%      Expands to"U" when SSL is supported, "N" otherwise.
 
489
     %OSNAME%        Expands to operating system name, e.g. Linux.
 
490
     %OSVERSION%     Expands to operating system version, e.g. 2.6.32
 
491
     %SYSTYPE%       Expands to machine or system type, e.g. i386
 
492
     %PLATFORM%      Expands to windowing system, e.g. X11 on Unix/Linux.
 
493
     %LANGUAGE%      Expands to default language in use, e.g. en-US.
 
494
     %APPVERSION%    Expands to QCoreApplication applicationName()/applicationVerison(),
 
495
                     e.g. Konqueror/4.5.0. If application name and/or application version
 
496
                     number are not set, then "KDE" and the runtime KDE version numbers
 
497
                     are used respectively.
 
498
 
 
499
     All of the keywords are handled case-insensitively.
 
500
  */
 
501
 
 
502
  QString systemName, systemVersion, machine, supp;
 
503
  const bool sysInfoFound = getSystemNameVersionAndMachine( systemName, systemVersion, machine );
 
504
  QString agentStr = defaultUserAgentFromPreferredService();
 
505
 
 
506
  if (agentStr.isEmpty())
 
507
  {
 
508
    if (sysInfoFound)
 
509
    {
 
510
      if( modifiers.contains('o') )
 
511
      {
 
512
        supp += QL1S("; ");
 
513
        supp += systemName;
 
514
        if ( modifiers.contains('v') )
 
515
        {
 
516
          supp += QL1C(' ');
 
517
          supp += systemVersion;
 
518
        }
 
519
      }
 
520
#ifdef Q_WS_X11
 
521
      if( modifiers.contains('p') )
 
522
        supp += QL1S("; X11");
 
523
#endif
 
524
      if( modifiers.contains('m') )
 
525
      {
 
526
        supp += QL1S("; ");
 
527
        supp += machine;
 
528
      }
 
529
      if( modifiers.contains('l') )
 
530
      {
 
531
        supp += QL1S("; ");
 
532
        supp += KGlobal::locale()->language();
 
533
      }
 
534
    }
 
535
 
 
536
    d->useragent = CFG_DEFAULT_UAGENT(supp);
 
537
  }
 
538
  else
 
539
  {
 
540
    QString appName = QCoreApplication::applicationName();
 
541
    if (appName.isEmpty() || appName.startsWith(QL1S("kcmshell"), Qt::CaseInsensitive))
 
542
      appName = QL1S ("KDE");
 
543
 
 
544
    QString appVersion = QCoreApplication::applicationVersion();
 
545
    if (appVersion.isEmpty())
 
546
      appVersion += (QString::number(KDE::versionMajor()) % QL1C('.') %
 
547
                     QString::number(KDE::versionMinor()) % QL1C('.') %
 
548
                     QString::number(KDE::versionRelease()));
 
549
 
 
550
    appName += QL1C('/') % appVersion;
 
551
 
 
552
    agentStr.replace(QL1S("%appversion%"), appName, Qt::CaseInsensitive);
 
553
 
 
554
    if (QSslSocket::supportsSsl())
 
555
      agentStr.replace(QL1S("%security%"), QL1S("U"), Qt::CaseInsensitive);
 
556
    else
 
557
      agentStr.replace(QL1S("%security%"), QL1S("N"), Qt::CaseInsensitive);
 
558
 
 
559
    if (sysInfoFound)
 
560
    {
 
561
      if (modifiers.contains('o'))
 
562
      {
 
563
        agentStr.replace(QL1S("%osname%"), systemName, Qt::CaseInsensitive);
 
564
        if (modifiers.contains('v'))
 
565
            agentStr.replace(QL1S("%osversion%"), systemVersion, Qt::CaseInsensitive);
 
566
        else
 
567
            agentStr.remove(QL1S("%osversion%"), Qt::CaseInsensitive);
 
568
      }
 
569
      else
 
570
      {
 
571
         agentStr.remove(QL1S("%osname%"), Qt::CaseInsensitive);
 
572
         agentStr.remove(QL1S("%osversion%"), Qt::CaseInsensitive);
 
573
      }
 
574
 
 
575
      if (modifiers.contains('p'))
 
576
#if defined(Q_WS_X11)
 
577
        agentStr.replace(QL1S("%platform%"), QL1S("X11"), Qt::CaseInsensitive);
 
578
#elif defined(Q_WS_MAC)
 
579
        agentStr.replace(QL1S("%platform%"), QL1S("Macintosh"), Qt::CaseInsensitive);
 
580
#elif defined(Q_WS_WIN)
 
581
        agentStr.replace(QL1S("%platform%"), QL1S("Windows"), Qt::CaseInsensitive);
 
582
#elif defined (Q_WS_S60)
 
583
        agentStr.replace(QL1S("%platform%"), QL1S("Symbian"), Qt::CaseInsensitive);
 
584
#endif
 
585
      else
 
586
        agentStr.remove(QL1S("%platform%"), Qt::CaseInsensitive);
 
587
 
 
588
      if (modifiers.contains('m'))
 
589
        agentStr.replace(QL1S("%systype%"), machine, Qt::CaseInsensitive);
 
590
      else
 
591
        agentStr.remove(QL1S("%systype%"), Qt::CaseInsensitive);
 
592
 
 
593
      if (modifiers.contains('l'))
 
594
        agentStr.replace(QL1S("%language%"), KGlobal::locale()->language(), Qt::CaseInsensitive);
 
595
      else
 
596
        agentStr.remove(QL1S("%language%"), Qt::CaseInsensitive);
 
597
 
 
598
      // Clean up unnecessary separators that could be left over from the
 
599
      // possible keyword removal above...
 
600
      agentStr.replace(QRegExp("[(]\\s*[;]\\s*"), QL1S("("));
 
601
      agentStr.replace(QRegExp("[;]\\s*[;]\\s*"), QL1S(";"));
 
602
      agentStr.replace(QRegExp("\\s*[;]\\s*[)]"), QL1S(")"));
 
603
    }
 
604
    else
 
605
    {
 
606
      agentStr.remove(QL1S("%osname%"));
 
607
      agentStr.remove(QL1S("%osversion%"));
 
608
      agentStr.remove(QL1S("%platform%"));
 
609
      agentStr.remove(QL1S("%systype%"));
 
610
      agentStr.remove(QL1S("%language%"));
 
611
    }
 
612
 
 
613
    d->useragent = agentStr.simplified();
 
614
  }
 
615
 
 
616
  //kDebug() << "USERAGENT STRING:" << d->useragent;
 
617
  return d->useragent;
 
618
}
 
619
 
 
620
QString KProtocolManager::userAgentForApplication( const QString &appName, const QString& appVersion,
 
621
  const QStringList& extraInfo )
 
622
{
 
623
  QString systemName, systemVersion, machine, info;
 
624
 
 
625
  if (getSystemNameVersionAndMachine( systemName, systemVersion, machine ))
 
626
  {
 
627
    info +=  systemName;
 
628
    info += QL1C('/');
 
629
    info += systemVersion;
 
630
    info += QL1S("; ");
 
631
  }
 
632
 
 
633
  info += QL1S("KDE/");
 
634
  info += QString::number(KDE::versionMajor());
 
635
  info += QL1C('.');
 
636
  info += QString::number(KDE::versionMinor());
 
637
  info += QL1C('.');
 
638
  info += QString::number(KDE::versionRelease());
 
639
 
 
640
  if (!machine.isEmpty())
 
641
  {
 
642
    info += QL1S("; ");
 
643
    info += machine;
 
644
  }
 
645
 
 
646
  info += QL1S("; ");
 
647
  info += extraInfo.join(QL1S("; "));
 
648
 
 
649
  return (appName % QL1C('/') % appVersion % QL1S(" (") % info % QL1C(')'));
 
650
}
 
651
 
 
652
bool KProtocolManager::getSystemNameVersionAndMachine(
 
653
  QString& systemName, QString& systemVersion, QString& machine )
 
654
{
 
655
  struct utsname unameBuf;
 
656
  if ( 0 != uname( &unameBuf ) )
 
657
    return false;
 
658
#if defined(Q_WS_WIN) && !defined(_WIN32_WCE)
 
659
  // we do not use unameBuf.sysname information constructed in kdewin32
 
660
  // because we want to get separate name and version
 
661
  systemName = QL1S( "Windows" );
 
662
  OSVERSIONINFOEX versioninfo;
 
663
  ZeroMemory(&versioninfo, sizeof(OSVERSIONINFOEX));
 
664
  // try calling GetVersionEx using the OSVERSIONINFOEX, if that fails, try using the OSVERSIONINFO
 
665
  versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
 
666
  bool ok = GetVersionEx( (OSVERSIONINFO *) &versioninfo );
 
667
  if ( !ok ) {
 
668
    versioninfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
 
669
    ok = GetVersionEx( (OSVERSIONINFO *) &versioninfo );
 
670
  }
 
671
  if ( ok )
 
672
    systemVersion = (QString::number(versioninfo.dwMajorVersion) %
 
673
                     QL1C('.') % QString::number(versioninfo.dwMinorVersion));
 
674
#else
 
675
  systemName = unameBuf.sysname;
 
676
  systemVersion = unameBuf.release;
 
677
#endif
 
678
  machine = unameBuf.machine;
 
679
  return true;
 
680
}
 
681
 
 
682
QString KProtocolManager::acceptLanguagesHeader()
 
683
{
 
684
  static const QString &english = KGlobal::staticQString("en");
 
685
 
 
686
  // User's desktop language preference.
 
687
  QStringList languageList = KGlobal::locale()->languageList();
 
688
 
 
689
  // Replace possible "C" in the language list with "en", unless "en" is
 
690
  // already pressent. This is to keep user's priorities in order.
 
691
  // If afterwards "en" is still not present, append it.
 
692
  int idx = languageList.indexOf(QString::fromLatin1("C"));
 
693
  if (idx != -1)
 
694
  {
 
695
    if (languageList.contains(english))
 
696
      languageList.removeAt(idx);
 
697
    else
 
698
      languageList[idx] = english;
 
699
  }
 
700
  if (!languageList.contains(english))
 
701
    languageList += english;
 
702
 
 
703
  // Some languages may have web codes different from locale codes,
 
704
  // read them from the config and insert in proper order.
 
705
  KConfig acclangConf("accept-languages.codes", KConfig::NoGlobals);
 
706
  KConfigGroup replacementCodes(&acclangConf, "ReplacementCodes");
 
707
  QStringList languageListFinal;
 
708
  Q_FOREACH (const QString &lang, languageList)
 
709
  {
 
710
    const QStringList langs = replacementCodes.readEntry(lang, QStringList());
 
711
    if (langs.isEmpty())
 
712
      languageListFinal += lang;
 
713
    else
 
714
      languageListFinal += langs;
 
715
  }
 
716
 
 
717
  // The header is composed of comma separated languages, with an optional
 
718
  // associated priority estimate (q=1..0) defaulting to 1.
 
719
  // As our language tags are already sorted by priority, we'll just decrease
 
720
  // the value evenly
 
721
  int prio = 10;
 
722
  QString header;
 
723
  Q_FOREACH (const QString &lang,languageListFinal) {
 
724
      header += lang;
 
725
      if (prio < 10) {
 
726
          header += QL1S(";q=0.");
 
727
          header += QString::number(prio);
 
728
      }
 
729
      // do not add cosmetic whitespace in here : it is less compatible (#220677)
 
730
      header += QL1S(",");
 
731
      if (prio > 1)
 
732
          --prio;
 
733
  }
 
734
  header.chop(1);
 
735
 
 
736
  // Some of the languages may have country specifier delimited by
 
737
  // underscore, or modifier delimited by at-sign.
 
738
  // The header should use dashes instead.
 
739
  header.replace('_', '-');
 
740
  header.replace('@', '-');
 
741
 
 
742
  return header;
 
743
}
 
744
 
 
745
/*==================================== OTHERS ===============================*/
 
746
 
 
747
bool KProtocolManager::markPartial()
 
748
{
 
749
  return config()->group(QByteArray()).readEntry( "MarkPartial", true );
 
750
}
 
751
 
 
752
int KProtocolManager::minimumKeepSize()
 
753
{
 
754
    return config()->group(QByteArray()).readEntry( "MinimumKeepSize",
 
755
                                                DEFAULT_MINIMUM_KEEP_SIZE ); // 5000 byte
 
756
}
 
757
 
 
758
bool KProtocolManager::autoResume()
 
759
{
 
760
  return config()->group(QByteArray()).readEntry( "AutoResume", false );
 
761
}
 
762
 
 
763
bool KProtocolManager::persistentConnections()
 
764
{
 
765
  return config()->group(QByteArray()).readEntry( "PersistentConnections", true );
 
766
}
 
767
 
 
768
bool KProtocolManager::persistentProxyConnection()
 
769
{
 
770
  return config()->group(QByteArray()).readEntry( "PersistentProxyConnection", false );
 
771
}
 
772
 
 
773
QString KProtocolManager::proxyConfigScript()
 
774
{
 
775
  return config()->group("Proxy Settings").readEntry( "Proxy Config Script" );
 
776
}
 
777
 
 
778
/* =========================== PROTOCOL CAPABILITIES ============== */
 
779
 
 
780
static KProtocolInfo::Ptr findProtocol(const KUrl &url)
 
781
{
 
782
   QString protocol = url.protocol();
 
783
 
 
784
   if ( !KProtocolInfo::proxiedBy( protocol ).isEmpty() )
 
785
   {
 
786
      QString dummy;
 
787
      protocol = KProtocolManager::slaveProtocol(url, dummy);
 
788
   }
 
789
 
 
790
   return KProtocolInfoFactory::self()->findProtocol(protocol);
 
791
}
 
792
 
 
793
 
 
794
KProtocolInfo::Type KProtocolManager::inputType( const KUrl &url )
 
795
{
 
796
  KProtocolInfo::Ptr prot = findProtocol(url);
 
797
  if ( !prot )
 
798
    return KProtocolInfo::T_NONE;
 
799
 
 
800
  return prot->m_inputType;
 
801
}
 
802
 
 
803
KProtocolInfo::Type KProtocolManager::outputType( const KUrl &url )
 
804
{
 
805
  KProtocolInfo::Ptr prot = findProtocol(url);
 
806
  if ( !prot )
 
807
    return KProtocolInfo::T_NONE;
 
808
 
 
809
  return prot->m_outputType;
 
810
}
 
811
 
 
812
 
 
813
bool KProtocolManager::isSourceProtocol( const KUrl &url )
 
814
{
 
815
  KProtocolInfo::Ptr prot = findProtocol(url);
 
816
  if ( !prot )
 
817
    return false;
 
818
 
 
819
  return prot->m_isSourceProtocol;
 
820
}
 
821
 
 
822
bool KProtocolManager::supportsListing( const KUrl &url )
 
823
{
 
824
  KProtocolInfo::Ptr prot = findProtocol(url);
 
825
  if ( !prot )
 
826
    return false;
 
827
 
 
828
  return prot->m_supportsListing;
 
829
}
 
830
 
 
831
QStringList KProtocolManager::listing( const KUrl &url )
 
832
{
 
833
  KProtocolInfo::Ptr prot = findProtocol(url);
 
834
  if ( !prot )
 
835
    return QStringList();
 
836
 
 
837
  return prot->m_listing;
 
838
}
 
839
 
 
840
bool KProtocolManager::supportsReading( const KUrl &url )
 
841
{
 
842
  KProtocolInfo::Ptr prot = findProtocol(url);
 
843
  if ( !prot )
 
844
    return false;
 
845
 
 
846
  return prot->m_supportsReading;
 
847
}
 
848
 
 
849
bool KProtocolManager::supportsWriting( const KUrl &url )
 
850
{
 
851
  KProtocolInfo::Ptr prot = findProtocol(url);
 
852
  if ( !prot )
 
853
    return false;
 
854
 
 
855
  return prot->m_supportsWriting;
 
856
}
 
857
 
 
858
bool KProtocolManager::supportsMakeDir( const KUrl &url )
 
859
{
 
860
  KProtocolInfo::Ptr prot = findProtocol(url);
 
861
  if ( !prot )
 
862
    return false;
 
863
 
 
864
  return prot->m_supportsMakeDir;
 
865
}
 
866
 
 
867
bool KProtocolManager::supportsDeleting( const KUrl &url )
 
868
{
 
869
  KProtocolInfo::Ptr prot = findProtocol(url);
 
870
  if ( !prot )
 
871
    return false;
 
872
 
 
873
  return prot->m_supportsDeleting;
 
874
}
 
875
 
 
876
bool KProtocolManager::supportsLinking( const KUrl &url )
 
877
{
 
878
  KProtocolInfo::Ptr prot = findProtocol(url);
 
879
  if ( !prot )
 
880
    return false;
 
881
 
 
882
  return prot->m_supportsLinking;
 
883
}
 
884
 
 
885
bool KProtocolManager::supportsMoving( const KUrl &url )
 
886
{
 
887
  KProtocolInfo::Ptr prot = findProtocol(url);
 
888
  if ( !prot )
 
889
    return false;
 
890
 
 
891
  return prot->m_supportsMoving;
 
892
}
 
893
 
 
894
bool KProtocolManager::supportsOpening( const KUrl &url )
 
895
{
 
896
  KProtocolInfo::Ptr prot = findProtocol(url);
 
897
  if ( !prot )
 
898
    return false;
 
899
 
 
900
  return prot->m_supportsOpening;
 
901
}
 
902
 
 
903
bool KProtocolManager::canCopyFromFile( const KUrl &url )
 
904
{
 
905
  KProtocolInfo::Ptr prot = findProtocol(url);
 
906
  if ( !prot )
 
907
    return false;
 
908
 
 
909
  return prot->m_canCopyFromFile;
 
910
}
 
911
 
 
912
 
 
913
bool KProtocolManager::canCopyToFile( const KUrl &url )
 
914
{
 
915
  KProtocolInfo::Ptr prot = findProtocol(url);
 
916
  if ( !prot )
 
917
    return false;
 
918
 
 
919
  return prot->m_canCopyToFile;
 
920
}
 
921
 
 
922
bool KProtocolManager::canRenameFromFile( const KUrl &url )
 
923
{
 
924
  KProtocolInfo::Ptr prot = findProtocol(url);
 
925
  if ( !prot )
 
926
    return false;
 
927
 
 
928
  return prot->canRenameFromFile();
 
929
}
 
930
 
 
931
 
 
932
bool KProtocolManager::canRenameToFile( const KUrl &url )
 
933
{
 
934
  KProtocolInfo::Ptr prot = findProtocol(url);
 
935
  if ( !prot )
 
936
    return false;
 
937
 
 
938
  return prot->canRenameToFile();
 
939
}
 
940
 
 
941
bool KProtocolManager::canDeleteRecursive( const KUrl &url )
 
942
{
 
943
  KProtocolInfo::Ptr prot = findProtocol(url);
 
944
  if ( !prot )
 
945
    return false;
 
946
 
 
947
  return prot->canDeleteRecursive();
 
948
}
 
949
 
 
950
KProtocolInfo::FileNameUsedForCopying KProtocolManager::fileNameUsedForCopying( const KUrl &url )
 
951
{
 
952
  KProtocolInfo::Ptr prot = findProtocol(url);
 
953
  if ( !prot )
 
954
    return KProtocolInfo::FromUrl;
 
955
 
 
956
  return prot->fileNameUsedForCopying();
 
957
}
 
958
 
 
959
QString KProtocolManager::defaultMimetype( const KUrl &url )
 
960
{
 
961
  KProtocolInfo::Ptr prot = findProtocol(url);
 
962
  if ( !prot )
 
963
    return QString();
 
964
 
 
965
  return prot->m_defaultMimetype;
 
966
}
 
967
 
 
968
QString KProtocolManager::protocolForArchiveMimetype( const QString& mimeType )
 
969
{
 
970
    PRIVATE_DATA;
 
971
    if (d->protocolForArchiveMimetypes.isEmpty()) {
 
972
        const KProtocolInfo::List allProtocols = KProtocolInfoFactory::self()->allProtocols();
 
973
        for (KProtocolInfo::List::const_iterator it = allProtocols.begin();
 
974
             it != allProtocols.end(); ++it) {
 
975
            const QStringList archiveMimetypes = (*it)->archiveMimeTypes();
 
976
            Q_FOREACH(const QString& mime, archiveMimetypes) {
 
977
                d->protocolForArchiveMimetypes.insert(mime, (*it)->name());
 
978
            }
 
979
        }
 
980
    }
 
981
    return d->protocolForArchiveMimetypes.value(mimeType);
 
982
}
 
983
 
 
984
#undef PRIVATE_DATA