[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[vidalia-svn] r3862: Add a CrashReportUploader class for generating and POSTing a (vidalia/branches/breakpad/src/crashreporter)



Author: edmanm
Date: 2009-06-16 01:40:20 -0400 (Tue, 16 Jun 2009)
New Revision: 3862

Added:
   vidalia/branches/breakpad/src/crashreporter/CrashReportUploader.cpp
   vidalia/branches/breakpad/src/crashreporter/CrashReportUploader.h
Modified:
   vidalia/branches/breakpad/src/crashreporter/CMakeLists.txt
Log:

Add a CrashReportUploader class for generating and POSTing a
multipart/form-data request to the crash reporting server, including the
minidump, user comments and any extra fields parsed from the crash
annotations file.


Modified: vidalia/branches/breakpad/src/crashreporter/CMakeLists.txt
===================================================================
--- vidalia/branches/breakpad/src/crashreporter/CMakeLists.txt	2009-06-16 05:34:03 UTC (rev 3861)
+++ vidalia/branches/breakpad/src/crashreporter/CMakeLists.txt	2009-06-16 05:40:20 UTC (rev 3862)
@@ -19,10 +19,12 @@
 set(crashreporter_SRCS
   main.cpp
   CrashReportDialog.cpp
+  CrashReportUploader.cpp
   UploadProgressDialog.cpp
 )
 qt4_wrap_cpp(crashreporter_SRCS
   CrashReportDialog.h
+  CrashReportUploader.h
   UploadProgressDialog.h
 )
 qt4_wrap_ui(crashreporter_SRCS

Added: vidalia/branches/breakpad/src/crashreporter/CrashReportUploader.cpp
===================================================================
--- vidalia/branches/breakpad/src/crashreporter/CrashReportUploader.cpp	                        (rev 0)
+++ vidalia/branches/breakpad/src/crashreporter/CrashReportUploader.cpp	2009-06-16 05:40:20 UTC (rev 3862)
@@ -0,0 +1,142 @@
+/*
+**  This file is part of Vidalia, and is subject to the license terms in the
+**  LICENSE file, found in the top level directory of this distribution. If you
+**  did not receive the LICENSE file with this file, you may obtain it from the
+**  Vidalia source package distributed by the Vidalia Project at
+**  http://www.vidalia-project.net/. No part of Vidalia, including this file,
+**  may be copied, modified, propagated, or distributed except according to the
+**  terms described in the LICENSE file.
+*/
+
+/*
+** \file CrashReportUploader.cpp
+** \version $Id$
+** \brief Uploads a minidump file and any extra information to a crash
+** reporting server.
+*/
+
+#include "CrashReportUploader.h"
+
+#include <QtGlobal>
+#include <QDateTime>
+#include <QSslSocket>
+#include <QSslCertificate>
+#include <QHttpRequestHeader>
+#include <QHttpResponseHeader>
+#include <QMap>
+#include <QUrl>
+
+
+CrashReportUploader::CrashReportUploader(QObject *parent)
+  : QObject(parent)
+{
+  /* Clear the default CA certificate store and add the only one we want */
+  QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>());
+  QSslSocket::addDefaultCaCertificates(":/pki/gd-class2-root.crt");
+
+  /* Create the QHttp object used to talk to the crash reporting server */
+  _http = new QHttp(this);
+  connect(_http, SIGNAL(stateChanged(int)),
+          this, SLOT(httpStateChanged(int)));
+  connect(_http, SIGNAL(requestFinished(int, bool)),
+          this, SLOT(httpRequestFinished(int, bool)));
+  connect(_http, SIGNAL(dataSendProgress(int, int)),
+          this, SIGNAL(uploadProgress(int, int)));
+
+  /* Seed the lame PRNG we'll use to generate the multipart boundary marker */
+  qsrand(QDateTime::currentDateTime().toTime_t());
+}
+
+void
+CrashReportUploader::uploadMinidump(const QUrl &serverUrl,
+                                    const QString &minidumpId,
+                                    const QByteArray &minidump,
+                                    const QMap<QString,QString> &parameters)
+{
+  QByteArray body;
+
+  /* Set up the request header */
+  QHttpRequestHeader header("POST", serverUrl.path());
+  QString boundary = generateBoundaryMarker();
+  header.setValue("Host", serverUrl.host());
+  header.setContentType(QString("multipart/form-data; boundary=%1")
+                                                    .arg(boundary));
+
+  /* Add all the key=value parameters to the request body */
+  foreach (QString key, parameters.keys()) {
+    QString value = parameters.value(key);
+    if (! value.isEmpty()) {
+      body.append(QString("--%1\r\n").arg(boundary));
+      body.append(QString("Content-Disposition: form-data; name=\"%1\"").arg(key));
+      body.append("\r\n\r\n");
+      body.append(value.toUtf8());
+      body.append("\r\n");
+    }
+  }
+
+  /* Append the minidump contents */
+  body.append(QString("--%1\r\n").arg(boundary));
+  body.append("Content-Disposition: form-data; ");
+  body.append("name=\"upload_file_minidump\"; ");
+  body.append(QString("filename=\"%1\"").arg(minidumpId));
+  body.append("Content-Type: application/octet-stream\r\n\r\n");
+  body.append(minidump);
+  body.append(QString("\r\n--%1\r\n").arg(boundary));
+
+  /* Initiate the request and return the request ID */
+  _requestId = _http->request(header, body);
+}
+
+QString
+CrashReportUploader::generateBoundaryMarker() const
+{
+  return QString("%1%2").arg((quint32)qrand(), 8, 16, QChar('0'))
+                        .arg((quint32)qrand(), 8, 16, QChar('0'));  
+}
+
+void
+CrashReportUploader::cancel()
+{
+  _http->abort();
+}
+
+void
+CrashReportUploader::httpStateChanged(int state)
+{
+  switch (state) {
+    case QHttp::Connecting:
+      emit statusChanged(tr("Connecting..."));
+      break;
+
+    case QHttp::Sending:
+      emit statusChanged(tr("Sending crash report..."));
+      break;
+
+    case QHttp::Reading:
+      emit statusChanged(tr("Receiving response..."));
+      break;
+
+    default:
+      break;
+  }
+}
+
+void
+CrashReportUploader::httpRequestFinished(int id, bool error)
+{
+  if (id != _requestId)
+    return;
+
+  if (error) {
+    QString errorString = _http->errorString();
+    emit uploadFailed(errorString);
+  } else {
+    QHttpResponseHeader response = _http->lastResponse();
+    if (response.statusCode() == 200)
+      emit uploadFinished();
+    else
+      emit uploadFailed(response.reasonPhrase());
+  }
+  _http->close();
+}
+


Property changes on: vidalia/branches/breakpad/src/crashreporter/CrashReportUploader.cpp
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Added: vidalia/branches/breakpad/src/crashreporter/CrashReportUploader.h
===================================================================
--- vidalia/branches/breakpad/src/crashreporter/CrashReportUploader.h	                        (rev 0)
+++ vidalia/branches/breakpad/src/crashreporter/CrashReportUploader.h	2009-06-16 05:40:20 UTC (rev 3862)
@@ -0,0 +1,110 @@
+/*
+**  This file is part of Vidalia, and is subject to the license terms in the
+**  LICENSE file, found in the top level directory of this distribution. If you
+**  did not receive the LICENSE file with this file, you may obtain it from the
+**  Vidalia source package distributed by the Vidalia Project at
+**  http://www.vidalia-project.net/. No part of Vidalia, including this file,
+**  may be copied, modified, propagated, or distributed except according to the
+**  terms described in the LICENSE file.
+*/
+
+/*
+** \file CrashReportUploader.h
+** \version $Id$
+** \brief Uploads a minidump file and any extra information to a crash
+** reporting server.
+*/
+
+#ifndef _CRASHREPORTUPLOADER_H
+#define _CRASHREPORTUPLOADER_H
+
+#include <QObject>
+#include <QHttp>
+#include <QMap>
+
+class QUrl;
+class QString;
+class QByteArray;
+
+
+class CrashReportUploader : public QObject
+{
+  Q_OBJECT
+
+public:
+  /** Default constructor.
+   */
+  CrashReportUploader(QObject *parent = 0);
+
+  /** Starts uploading <b>minidump</b> to <b>serverUrl</b> and returns
+   * immediately. <b>minidumpId</b> is the minidump GUID generated by
+   * the exception handler and used for the minidump's filename. The
+   * optional <b>parameters</b> can be used to pass additional form fields
+   * to the crash reporting server.
+   */
+  void uploadMinidump(const QUrl &serverUrl,
+                      const QString &minidumpId,
+                      const QByteArray &minidump,
+                      const QMap<QString,QString> &parameters);
+
+public slots:
+  /** Cancels a pending minidump upload.
+   */
+  void cancel();
+
+signals:
+  /** Emitted when the underlying QHttp object posts data to the server.
+   * <b>done</b> indicates how many bytes out of <b>total</b>
+   * have been sent so far.
+   */
+  void uploadProgress(int done, int total);
+
+  /** Emitted when the status of the POST request changes. <b>status</b>
+   * describes the new current state of the request.
+   */
+  void statusChanged(const QString &status);
+
+  /** Emitted when the previous minidump upload completes successfully.
+   */
+  void uploadFinished();
+
+  /** Emitted when the previous crash report upload fails. The QString
+   * <b>error</b> is a human-readable string describing the error
+   * encountered.
+   */
+  void uploadFailed(const QString &error);
+
+private slots:
+  /** Called when the state of the underlying QHttp object changes. A
+   * statusChanged() signal is emitted with the appropriate text
+   * describing the new state of the POST request.
+   */
+  void httpStateChanged(int state); 
+
+  /** Called when the underlying QHttp object used to upload the minidump
+   * completes. <b>error</b> is set to false if the upload was
+   * successful, or true if the upload failed. If <b>id</b> does not
+   * match the request ID previously returned by QHttp::get(), then the
+   * signal is ignored since it is the result of a close() or abort()
+   * request.
+   */
+  void httpRequestFinished(int id, bool error);
+
+private:
+  /** Generates a "random" 8-byte multipart boundary marker encoded into
+   * 16 hex characters.
+   */
+  QString generateBoundaryMarker() const;
+
+  /** Unique numeric identifier of the current minidump upload POST request.
+   */
+  int _requestId;
+
+  /** Object used to POST a minidump to the crash server and read the
+   * response.
+   */
+  QHttp *_http;
+};
+
+#endif
+


Property changes on: vidalia/branches/breakpad/src/crashreporter/CrashReportUploader.h
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native