[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> ¶meters)
+{
+ 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> ¶meters);
+
+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