static SendCoinsRecipient handleRequest(PaymentServer* server, std::vector<unsigned char>& data) { RecipientCatcher sigCatcher; QObject::connect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), &sigCatcher, SLOT(getRecipient(SendCoinsRecipient))); // Write data to a temp file: QTemporaryFile f; f.open(); f.write((const char*)data.data(), data.size()); f.close(); // Create a QObject, install event filter from PaymentServer // and send a file open event to the object QObject object; object.installEventFilter(server); QFileOpenEvent event(f.fileName()); // If sending the event fails, this will cause sigCatcher to be empty, // which will lead to a test failure anyway. QCoreApplication::sendEvent(&object, &event); QObject::disconnect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), &sigCatcher, SLOT(getRecipient(SendCoinsRecipient))); // Return results from sigCatcher return sigCatcher.recipient; }
static SendCoinsRecipient handleRequest(PaymentServer* server, std::vector<unsigned char>& data) { RecipientCatcher sigCatcher; QObject::connect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), &sigCatcher, SLOT(getRecipient(SendCoinsRecipient))); // Write data to a temp file: QTemporaryFile f; f.open(); f.write((const char*)&data[0], data.size()); f.close(); // Create a FileOpenEvent and send it directly to the server's event filter: QFileOpenEvent event(f.fileName()); server->eventFilter(NULL, &event); QObject::disconnect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), &sigCatcher, SLOT(getRecipient(SendCoinsRecipient))); // Return results from sigCatcher return sigCatcher.recipient; }
void PaymentServer::netRequestFinished(QNetworkReply* reply) { reply->deleteLater(); // BIP70 DoS protection if (!verifySize(reply->size())) { Q_EMIT message(tr("Payment request rejected"), tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).") .arg(reply->request().url().toString()) .arg(reply->size()) .arg(BIP70_MAX_PAYMENTREQUEST_SIZE), CClientUIInterface::MSG_ERROR); return; } if (reply->error() != QNetworkReply::NoError) { QString msg = tr("Error communicating with %1: %2") .arg(reply->request().url().toString()) .arg(reply->errorString()); qWarning() << "PaymentServer::netRequestFinished: " << msg; Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); return; } QByteArray data = reply->readAll(); QString requestType = reply->request().attribute(QNetworkRequest::User).toString(); if (requestType == BIP70_MESSAGE_PAYMENTREQUEST) { PaymentRequestPlus request; SendCoinsRecipient recipient; if (!request.parse(data)) { qWarning() << "PaymentServer::netRequestFinished: Error parsing payment request"; Q_EMIT message(tr("Payment request error"), tr("Payment request cannot be parsed!"), CClientUIInterface::MSG_ERROR); } else if (processPaymentRequest(request, recipient)) Q_EMIT receivedPaymentRequest(recipient); return; } else if (requestType == BIP70_MESSAGE_PAYMENTACK) { payments::PaymentACK paymentACK; if (!paymentACK.ParseFromArray(data.data(), data.size())) { QString msg = tr("Bad response from server %1") .arg(reply->request().url().toString()); qWarning() << "PaymentServer::netRequestFinished: " << msg; Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); } else { Q_EMIT receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo())); } } }
void PaymentServer::handleURIOrFile(const QString& s) { if (saveURIs) { savedPaymentRequests.append(s); return; } if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI { #if QT_VERSION < 0x050000 QUrl uri(s); #else QUrlQuery uri((QUrl(s))); #endif if (uri.hasQueryItem("r")) // payment request URI { QByteArray temp; temp.append(uri.queryItemValue("r")); QString decoded = QUrl::fromPercentEncoding(temp); QUrl fetchUrl(decoded, QUrl::StrictMode); if (fetchUrl.isValid()) { qDebug() << "PaymentServer::handleURIOrFile: fetchRequest(" << fetchUrl << ")"; fetchRequest(fetchUrl); } else { qWarning() << "PaymentServer::handleURIOrFile: Invalid URL: " << fetchUrl; Q_EMIT message(tr("URI handling"), tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()), CClientUIInterface::ICON_WARNING); } return; } else // normal URI { SendCoinsRecipient recipient; if (GUIUtil::parseBitcoinURI(s, &recipient)) { if (!IsValidDestinationString(recipient.address.toStdString())) { Q_EMIT message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), CClientUIInterface::MSG_ERROR); } else Q_EMIT receivedPaymentRequest(recipient); } else Q_EMIT message(tr("URI handling"), tr("URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."), CClientUIInterface::ICON_WARNING); return; } } if (QFile::exists(s)) // payment request file { PaymentRequestPlus request; SendCoinsRecipient recipient; if (!readPaymentRequestFromFile(s, request)) { Q_EMIT message(tr("Payment request file handling"), tr("Payment request file cannot be read! This can be caused by an invalid payment request file."), CClientUIInterface::ICON_WARNING); } else if (processPaymentRequest(request, recipient)) Q_EMIT receivedPaymentRequest(recipient); return; } }