QBreakpadHttpUploader.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright (C) 2009 Aleksey Palazhchenko
  3. * Copyright (C) 2014 Sergey Shambir
  4. * Copyright (C) 2016 Alexander Makarov
  5. *
  6. * This file is a part of Breakpad-qt library.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. */
  19. #include <QCoreApplication>
  20. #include <QString>
  21. #include <QUrl>
  22. #include <QDir>
  23. #include <QFileInfo>
  24. #include <QMimeDatabase>
  25. #include <QHttpMultiPart>
  26. #include "QBreakpadHttpUploader.h"
  27. QBreakpadHttpUploader::QBreakpadHttpUploader(QObject *parent) :
  28. QObject(parent),
  29. m_file(0)
  30. {
  31. }
  32. QBreakpadHttpUploader::QBreakpadHttpUploader(const QUrl &url, QObject *parent) :
  33. QObject(parent),
  34. m_file(0)
  35. {
  36. m_request.setUrl(url);
  37. }
  38. QBreakpadHttpUploader::~QBreakpadHttpUploader()
  39. {
  40. if(m_reply) {
  41. qWarning("m_reply is not NULL");
  42. m_reply->deleteLater();
  43. }
  44. delete m_file;
  45. }
  46. QString QBreakpadHttpUploader::remoteUrl() const
  47. {
  48. return m_request.url().toString();
  49. }
  50. void QBreakpadHttpUploader::setUrl(const QUrl &url)
  51. {
  52. m_request.setUrl(url);
  53. }
  54. void QBreakpadHttpUploader::uploadDump(const QString& abs_file_path)
  55. {
  56. Q_ASSERT(!m_file);
  57. Q_ASSERT(!m_reply);
  58. Q_ASSERT(QDir().exists(abs_file_path));
  59. QFileInfo fileInfo(abs_file_path);
  60. QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
  61. //product name parameter
  62. QHttpPart prodPart;
  63. #if defined(SOCORRO)
  64. prodPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"ProductName\"")); // Socorro
  65. #elif defined(CALIPER)
  66. prodPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"prod\"")); // Caliper
  67. #endif
  68. prodPart.setBody(qApp->applicationName().toLatin1());
  69. //product version parameter
  70. QHttpPart verPart;
  71. #if defined(SOCORRO)
  72. verPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"Version\"")); // Socorro
  73. #elif defined(CALIPER)
  74. verPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"ver\"")); // Caliper
  75. #endif
  76. verPart.setBody(qApp->applicationVersion().toLatin1());
  77. // file_minidump name & file_binary in one part
  78. QHttpPart filePart;
  79. filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"upload_file_minidump\"; filename=\""+ fileInfo.fileName()+ "\""));
  80. filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
  81. m_file = new QFile(abs_file_path);
  82. if(!m_file->open(QIODevice::ReadOnly)) return;
  83. filePart.setBodyDevice(m_file);
  84. m_file->setParent(multiPart);
  85. multiPart->append(prodPart);
  86. multiPart->append(verPart);
  87. multiPart->append(filePart);
  88. m_request.setRawHeader("User-Agent", qApp->applicationName().toLatin1()+"/"+qApp->applicationVersion().toLatin1());
  89. #if defined(SOCORRO)
  90. m_request.setRawHeader("Host", qApp->applicationName().toLower().toLatin1()+"_reports");
  91. m_request.setRawHeader("Accept", "*/*");
  92. #endif
  93. m_reply = m_manager.post(m_request, multiPart);
  94. multiPart->setParent(m_reply);
  95. connect(m_reply, SIGNAL(uploadProgress(qint64, qint64)),
  96. this, SLOT(onUploadProgress(qint64,qint64)));
  97. connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
  98. this, SLOT(onError(QNetworkReply::NetworkError)));
  99. connect(m_reply, SIGNAL(finished()),
  100. this, SLOT(onUploadFinished()));
  101. }
  102. void QBreakpadHttpUploader::onUploadProgress(qint64 sent, qint64 total)
  103. {
  104. qDebug("upload progress: %lld/%lld", sent, total);
  105. }
  106. void QBreakpadHttpUploader::onError(QNetworkReply::NetworkError err)
  107. {
  108. qDebug() << err;
  109. }
  110. void QBreakpadHttpUploader::onUploadFinished()
  111. {
  112. QString data = (QString)m_reply->readAll();
  113. qDebug() << "Upload finished";
  114. qDebug() << "Answer: " << data;
  115. if(m_reply->error() != QNetworkReply::NoError) {
  116. qWarning("Upload error: %d - %s", m_reply->error(), qPrintable(m_reply->errorString()));
  117. } else {
  118. qDebug() << "Upload to " << remoteUrl() << " success!";
  119. m_file->remove();
  120. }
  121. emit finished(data);
  122. m_reply->close();
  123. m_reply->deleteLater();
  124. m_reply = 0;
  125. delete m_file;
  126. m_file = 0;
  127. }