X-Git-Url: http://git.webkit.org/?p=WebKit-https.git;a=blobdiff_plain;f=WebCore%2Fplatform%2Fnetwork%2Fqt%2FQNetworkReplyHandler.cpp;h=5e3d9432f418837b7bc276738dd05e436bcb148f;hp=ab240f588b7234a76fc830c544f180939d96226b;hb=5f56e9db61cb9d14724cabe0d34f7d70c8c5eb50;hpb=e90518741eeff66eaa9f68ade83b31d22aa031a0;ds=inline diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index ab240f5..5e3d943 100644 --- a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Trolltech ASA + Copyright (C) 2007-2008 Trolltech ASA Copyright (C) 2007 Staikos Computing Services Inc. This library is free software; you can redistribute it and/or @@ -29,19 +29,111 @@ #include "ResourceHandleInternal.h" #include "ResourceResponse.h" #include "ResourceRequest.h" +#include +#include #include #include #include #include +#include + namespace WebCore { +// Take a deep copy of the FormDataElement +FormDataIODevice::FormDataIODevice(FormData* data) + : m_formElements(data ? data->elements() : Vector()) + , m_currentFile(0) + , m_currentDelta(0) +{ + setOpenMode(FormDataIODevice::ReadOnly); +} + +FormDataIODevice::~FormDataIODevice() +{ + delete m_currentFile; +} + +void FormDataIODevice::moveToNextElement() +{ + if (m_currentFile) + m_currentFile->close(); + m_currentDelta = 0; + + m_formElements.remove(0); + + if (m_formElements.isEmpty() || m_formElements[0].m_type == FormDataElement::data) + return; + + if (!m_currentFile) + m_currentFile = new QFile; + + m_currentFile->setFileName(m_formElements[0].m_filename); + m_currentFile->open(QFile::ReadOnly); +} + +// m_formElements[0] is the current item. If the destination buffer is +// big enough we are going to read from more than one FormDataElement +qint64 FormDataIODevice::readData(char* destination, qint64 size) +{ + if (m_formElements.isEmpty()) + return -1; + + qint64 copied = 0; + while (copied < size && !m_formElements.isEmpty()) { + const FormDataElement& element = m_formElements[0]; + const qint64 available = size-copied; + + if (element.m_type == FormDataElement::data) { + const qint64 toCopy = qMin(available, element.m_data.size() - m_currentDelta); + memcpy(destination+copied, element.m_data.data()+m_currentDelta, toCopy); + m_currentDelta += toCopy; + copied += toCopy; + + if (m_currentDelta == element.m_data.size()) + moveToNextElement(); + } else { + const QByteArray data = m_currentFile->read(available); + memcpy(destination+copied, data.constData(), data.size()); + copied += data.size(); + + if (m_currentFile->atEnd() || !m_currentFile->isOpen()) + moveToNextElement(); + } + } + + return copied; +} + +qint64 FormDataIODevice::writeData(const char*, qint64) +{ + return -1; +} + +void FormDataIODevice::setParent(QNetworkReply* reply) +{ + QIODevice::setParent(reply); + + connect(reply, SIGNAL(finished()), SLOT(slotFinished())); +} + +bool FormDataIODevice::isSequential() const +{ + return true; +} + +void FormDataIODevice::slotFinished() +{ + deleteLater(); +} + QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle *handle) : QObject(0) - , m_resourceHandle(handle) - , m_reply(0) - , m_redirected(false) - , m_responseSent(false) + , m_resourceHandle(handle) + , m_reply(0) + , m_redirected(false) + , m_responseSent(false) + , m_startTime(0) { const ResourceRequest &r = m_resourceHandle->request(); @@ -72,6 +164,16 @@ void QNetworkReplyHandler::abort() } } +QNetworkReply *QNetworkReplyHandler::release() +{ + QNetworkReply *reply = m_reply; + if (m_reply) { + disconnect(m_reply, 0, this, 0); + m_reply = 0; + } + return reply; +} + void QNetworkReplyHandler::finish() { sendResponseIfNeeded(); @@ -121,12 +223,15 @@ void QNetworkReplyHandler::sendResponseIfNeeded() } KURL url(m_reply->url()); - String contentDisposition = QString::fromAscii(m_reply->rawHeader("Content-Disposition")); + String suggestedFilename = filenameFromHTTPContentDisposition(QString::fromAscii(m_reply->rawHeader("Content-Disposition"))); + + if (suggestedFilename.isEmpty()) + suggestedFilename = url.lastPathComponent(); ResourceResponse response(url, mimeType, m_reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), encoding, - filenameFromHTTPContentDisposition(contentDisposition)); + suggestedFilename); const bool isLocalFileReply = (m_reply->url().scheme() == QLatin1String("file")); int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); @@ -149,6 +254,9 @@ void QNetworkReplyHandler::sendResponseIfNeeded() response.setHTTPHeaderField(QString::fromAscii(headerName), QString::fromAscii(m_reply->rawHeader(headerName))); } + if (isLocalFileReply) + response.setExpirationDate(m_startTime); + QUrl redirection = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); if (redirection.isValid()) { QUrl newUrl = m_reply->url().resolved(redirection); @@ -204,26 +312,25 @@ void QNetworkReplyHandler::start() && (!url.toLocalFile().isEmpty() || url.scheme() == QLatin1String("data"))) m_method = QNetworkAccessManager::GetOperation; + m_startTime = QDateTime::currentDateTime().toTime_t(); + switch (m_method) { case QNetworkAccessManager::GetOperation: m_reply = manager->get(m_request); break; case QNetworkAccessManager::PostOperation: { - Vector bytes; - if (d->m_request.httpBody()) - d->m_request.httpBody()->flatten(bytes); - m_reply = manager->post(m_request, QByteArray(bytes.data(), bytes.size())); + FormDataIODevice* postDevice = new FormDataIODevice(d->m_request.httpBody()); + m_reply = manager->post(m_request, postDevice); + postDevice->setParent(m_reply); break; } case QNetworkAccessManager::HeadOperation: m_reply = manager->head(m_request); break; case QNetworkAccessManager::PutOperation: { - // ### data? - Vector bytes; - if (d->m_request.httpBody()) - d->m_request.httpBody()->flatten(bytes); - m_reply = manager->put(m_request, QByteArray(bytes.data(), bytes.size())); + FormDataIODevice* putDevice = new FormDataIODevice(d->m_request.httpBody()); + m_reply = manager->put(m_request, putDevice); + putDevice->setParent(m_reply); break; } case QNetworkAccessManager::UnknownOperation: