kde-core-devel@kde.org
[Top] [All Lists]

[patch] KProtocolManager (kio/kio) extensions for application-specific u

Subject: [patch] KProtocolManager (kio/kio) extensions for application-specific user agent string
From: JarosÅaw Staniek
Date: Wed, 06 Feb 2008 14:34:59 +0100

Hello
For review;

- only adds 'X11' bit for 'p' key in "static QString KProtocolManager::defaultUserAgent(const QString &keys)" for X11-based targets

- adds
 static QString KProtocolManager::userAgentForApplication(
    const QString &appName,
    const QString& appVersion, const QStringList& extraInfo = QStringList() );
 for the application's user-agent string other than web browser (think of
 KMail/KNode/Mailody..)

- adds static bool getSystemNameVersionAndMachine(
     QString& systemName, QString& systemVersion, QString& machine );
  (returns nicely splitted system name, version and machine type, for example
  "Windows", "5.1", "i686"; also more useful for various sysinfo reporting)


The result in KMail is then user agent string like
KMail/1.9.50 (Windows/5.0; KDE/3.97.1; i686; svn-762186; 2008-01-15)
delivered by this code:

  QStringList extraInfo;
#if defined KMAIL_SVN_REVISION_STRING && defined KMAIL_SVN_LAST_CHANGE
  extraInfo << KMAIL_SVN_REVISION_STRING << KMAIL_SVN_LAST_CHANGE;
#endif
  setHeaderField("User-Agent",
    KProtocolManager::userAgentForApplication(
      "KMail", KMAIL_VERSION, extraInfo )
  );

--
regards / pozdrawiam, Jaroslaw Staniek
 Sponsored by OpenOffice Polska (http://www.openoffice.com.pl/en) to work on
 Kexi & KOffice (http://www.kexi.pl/en, http://www.koffice.org/kexi)
 KDE Libraries for MS Windows (http://windows.kde.org)
Index: kio/kio/kprotocolmanager.h
===================================================================
--- kio/kio/kprotocolmanager.h  (revision 768586)
+++ kio/kio/kprotocolmanager.h  (working copy)
@@ -64,19 +64,20 @@
 
 
   /**
-   * Returns the default user-agent string.
+   * Returns the default user-agent string used for web browsing.
    *
    * @return the default user-agent string
    */
   static QString defaultUserAgent();
 
   /**
-   * Returns the default user-agent value.
+   * Returns the default user-agent value used for web browsing, for example
+   * "Mozilla/5.0 (compatible; Konqueror/4.0; Linux; X11; i686; en_US) 
KHTML/4.0.1 (like Gecko)"
    *
    * @param keys can be any of the following:
    * @li 'o'   Show OS
    * @li 'v'   Show OS Version
-   * @li 'p'   Show platform
+   * @li 'p'   Show platform (only for X11)
    * @li 'm'   Show machine architecture
    * @li 'l'   Show language
    * @return the default user-agent value with the given @p keys
@@ -84,7 +85,22 @@
   static QString defaultUserAgent(const QString &keys);
 
   /**
-   * Returns the userAgent string configured for the
+   * Returns the application's user-agent string.
+   * Example string is "KMail/1.9.50 (Windows/6.0; KDE/3.97.1; i686; 
svn-762186; 2008-01-15)",
+   * where "KMail" is the @p appName parameter, "1.9.50" is the @p appVersion 
parameter,
+   * "Windows/6.0; KDE/3.97.1; i686" part is added automatically and 
"svn-762186; 2008-01-15"
+   * is provided by @p extraInfo list.
+   *
+   * @param appName name of the application
+   * @param appVersion name of the application
+   * @param extraInfo a list of elements that will be appended to the string 
as extra information
+   * @return the application's user-agent string
+   */
+  static QString userAgentForApplication( const QString &appName, const 
QString& appVersion, 
+    const QStringList& extraInfo = QStringList() );
+
+  /**
+   * Returns the user-agent string configured for the
    * specified host.
    *
    * If hostname is not found or is empty (i.e. "" or
@@ -92,11 +108,24 @@
    * user agent.
    *
    * @param hostname name of the host
-   * @return specified userAgent string
+   * @return specified user-agent string
    */
   static QString userAgentForHost( const QString &hostname );
 
+  /*
+   * Returns system name, version and machine type, for example "Windows", 
"5.1", "i686".
+   * This information can be used for constructing custom user-agent strings.
+   *
+   * @param systemName system name
+   * @param systemVersion system version
+   * @param machine machine type
 
+   * @return true if system name, version and machine type has been provided
+   */
+  static bool getSystemNameVersionAndMachine(
+    QString& systemName, QString& systemVersion, QString& machine );
+
+
 /*=========================== TIMEOUT CONFIG ================================*/
 
 
Index: kio/kio/kprotocolmanager.cpp
===================================================================
--- kio/kio/kprotocolmanager.cpp        (revision 768586)
+++ kio/kio/kprotocolmanager.cpp        (working copy)
@@ -21,6 +21,7 @@
 #include "kprotocolmanager.h"
 
 #include <string.h>
+#include <unistd.h>
 #include <sys/utsname.h>
 #include <QtCore/QCoreApplication>
 #include <QtDBus/QtDBus>
@@ -70,6 +71,7 @@
     qRemovePostRoutine(kProtocolManagerPrivate.destroy);
 }
 
+// user agent, e.g. KMail/1.9.50 (Windows/5.0; KDE/3.97.1; i686; svn-762186; 
2008-01-15)
 
 // DEFAULT USERAGENT STRING
 #define CFG_DEFAULT_UAGENT(X) \
@@ -441,23 +443,24 @@
   if (d->modifiers == modifiers)
      return d->useragent;
 
-  QString supp;
-  struct utsname nam;
-  if( uname(&nam) >= 0 )
+  QString systemName, systemVersion, machine, supp;
+  if (getSystemNameVersionAndMachine( systemName, systemVersion, machine ))
   {
     if( modifiers.contains('o') )
     {
-      supp += QString("; %1").arg(nam.sysname);
+      supp += QString("; %1").arg(systemName);
       if ( modifiers.contains('v') )
-        supp += QString(" %1").arg(nam.release);
+        supp += QString(" %1").arg(systemVersion);
     }
+#ifdef Q_WS_X11
     if( modifiers.contains('p') )
     {
-      supp += QLatin1String("; X11");  // TODO: determine this valye instead 
of hardcoding...
+      supp += QLatin1String("; X11");
     }
+#endif
     if( modifiers.contains('m') )
     {
-      supp += QString("; %1").arg(nam.machine);
+      supp += QString("; %1").arg(machine);
     }
     if( modifiers.contains('l') )
     {
@@ -469,6 +472,51 @@
   return d->useragent;
 }
 
+QString KProtocolManager::userAgentForApplication( const QString &appName, 
const QString& appVersion, 
+  const QStringList& extraInfo )
+{
+  QString systemName, systemVersion, machine;
+  QStringList info;
+  if (getSystemNameVersionAndMachine( systemName, systemVersion, machine ))
+    info += QString::fromLatin1("%1/%2").arg(systemName).arg(systemVersion);
+  info += QString::fromLatin1("KDE/%1.%2.%3").arg(KDE_VERSION_MAJOR)
+    .arg(KDE_VERSION_MINOR).arg(KDE_VERSION_RELEASE);
+  if (!machine.isEmpty())
+    info += machine;
+  info += extraInfo;
+  return QString::fromLatin1("%1/%2 
(%3)").arg(appName).arg(appVersion).arg(info.join("; "));
+}
+
+bool KProtocolManager::getSystemNameVersionAndMachine(
+  QString& systemName, QString& systemVersion, QString& machine )
+{
+  struct utsname unameBuf;
+  if ( 0 != uname( &unameBuf ) )
+    return false;
+#ifdef Q_WS_WIN
+  // we do not use unameBuf.sysname information constructed in kdewin32
+  // because we want to get separate name and version
+  systemName = QLatin1String( "Windows" );
+  OSVERSIONINFOEX versioninfo;
+  ZeroMemory(&versioninfo, sizeof(OSVERSIONINFOEX));
+  // try calling GetVersionEx using the OSVERSIONINFOEX, if that fails, try 
using the OSVERSIONINFO
+  versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+  bool ok = GetVersionEx( (OSVERSIONINFO *) &versioninfo );
+  if ( !ok ) {
+    versioninfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+    ok = GetVersionEx( (OSVERSIONINFO *) &versioninfo );
+  }
+  if ( ok )
+    systemVersion = QString::fromLatin1("%1.%2")
+      .arg(versioninfo.dwMajorVersion).arg(versioninfo.dwMinorVersion);
+#else
+  systemName = unameBuf.sysname;
+  systemVersion = unameBuf.release;
+#endif
+  machine = unameBuf.machine;
+  return true;
+}
+
 QString KProtocolManager::acceptLanguagesHeader()
 {
   static const QString &english = KGlobal::staticQString("en");
<Prev in Thread] Current Thread [Next in Thread>