📄 qwebnetworkinterface.cpp
字号:
/* Copyright (C) 2006 Enrico Ros <enrico.ros@m31engineering.it> Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) Copyright (C) 2007 Staikos Computing Services Inc. <info@staikos.net> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/#include <qglobal.h>#if QT_VERSION < 0x040400#include "qwebframe.h"#include "qwebnetworkinterface.h"#include "qwebnetworkinterface_p.h"#include "qwebpage.h"#include "qcookiejar.h"#include <qdebug.h>#include <qfile.h>#include <qnetworkproxy.h>#include <qurl.h>#include <QAuthenticator>#include <QCoreApplication>#include <QSslError>#include "ResourceHandle.h"#include "ResourceHandleClient.h"#include "ResourceHandleInternal.h"#include "MIMETypeRegistry.h"#include "CookieJar.h"#if 0#define DEBUG qDebug#else#define DEBUG if (1) {} else qDebug#endifstatic QWebNetworkInterface *s_default_interface = 0;static QWebNetworkManager *s_manager = 0;using namespace WebCore;uint qHash(const HostInfo &info){ return qHash(info.host) + info.port;}static bool operator==(const HostInfo &i1, const HostInfo &i2){ return i1.port == i2.port && i1.host == i2.host;}enum ParserState { State_Begin, State_FirstChar, State_SecondChar};/* * Decode URLs without doing any charset conversion. * * Most simple approach to do it without any lookahead. */static QByteArray decodePercentEncoding(const QByteArray& input){ int actualLength = 0; QByteArray tmpVal; QByteArray output; ParserState state = State_Begin; output.resize(input.length()); tmpVal.resize(2); for (int i = 0; i < input.length(); ++i) if (state == State_Begin) { if (input.at(i) == '%') { state = State_FirstChar; } else { output[actualLength++] = input[i]; } } else if (state == State_FirstChar) { state = State_SecondChar; tmpVal[0] = input[i]; } else if (state == State_SecondChar) { state = State_Begin; tmpVal[1] = input[i]; output[actualLength++] = tmpVal.toShort(0, 16); } output.resize(actualLength); return output;}void QWebNetworkRequestPrivate::init(const WebCore::ResourceRequest &resourceRequest){ KURL url = resourceRequest.url(); QUrl qurl = QString(url.string()); init(resourceRequest.httpMethod(), qurl, &resourceRequest);}void QWebNetworkRequestPrivate::init(const QString &method, const QUrl &url, const WebCore::ResourceRequest *resourceRequest){ httpHeader = QHttpRequestHeader(method, url.toString(QUrl::RemoveScheme|QUrl::RemoveAuthority)); httpHeader.setValue(QLatin1String("Connection"), QLatin1String("Keep-Alive")); setURL(url); if (resourceRequest) { httpHeader.setValue(QLatin1String("User-Agent"), resourceRequest->httpUserAgent()); const QString scheme = url.scheme().toLower(); if (scheme == QLatin1String("http") || scheme == QLatin1String("https")) { QString cookies = QCookieJar::cookieJar()->cookies(resourceRequest->url()); if (!cookies.isEmpty()) httpHeader.setValue(QLatin1String("Cookie"), cookies); } const HTTPHeaderMap& loaderHeaders = resourceRequest->httpHeaderFields(); HTTPHeaderMap::const_iterator end = loaderHeaders.end(); for (HTTPHeaderMap::const_iterator it = loaderHeaders.begin(); it != end; ++it) httpHeader.setValue(it->first, it->second); // handle and perform a 'POST' request if (method == "POST") { Vector<char> data; resourceRequest->httpBody()->flatten(data); postData = QByteArray(data.data(), data.size()); httpHeader.setValue(QLatin1String("content-length"), QString::number(postData.size())); } }}void QWebNetworkRequestPrivate::setURL(const QUrl &u){ url = u; int port = url.port(); const QString scheme = u.scheme(); if (port > 0 && (port != 80 || scheme != "http") && (port != 443 || scheme != "https")) httpHeader.setValue(QLatin1String("Host"), url.host() + QLatin1Char(':') + QString::number(port)); else httpHeader.setValue(QLatin1String("Host"), url.host());}/*! \class QWebNetworkRequest The QWebNetworkRequest class represents a request for data from the network with all the necessary information needed for retrieval. This includes the url, extra HTTP header fields as well as data for a HTTP POST request.*/QWebNetworkRequest::QWebNetworkRequest() : d(new QWebNetworkRequestPrivate){}QWebNetworkRequest::QWebNetworkRequest(const QUrl &url, Method method, const QByteArray &postData) : d(new QWebNetworkRequestPrivate){ d->init(method == Get ? "GET" : "POST", url); d->postData = postData;}QWebNetworkRequest::QWebNetworkRequest(const QWebNetworkRequest &other) : d(new QWebNetworkRequestPrivate(*other.d)){}QWebNetworkRequest &QWebNetworkRequest::operator=(const QWebNetworkRequest &other){ *d = *other.d; return *this;}/*! \internal*/QWebNetworkRequest::QWebNetworkRequest(const QWebNetworkRequestPrivate &priv) : d(new QWebNetworkRequestPrivate(priv)){}/*! \internal*/QWebNetworkRequest::QWebNetworkRequest(const WebCore::ResourceRequest &request) : d(new QWebNetworkRequestPrivate){ d->init(request);}QWebNetworkRequest::~QWebNetworkRequest(){ delete d;}/*! The requested URL*/QUrl QWebNetworkRequest::url() const{ return d->url;}/*! Sets the URL to request. Note that setting the URL also sets the "Host" field in the HTTP header.*/void QWebNetworkRequest::setUrl(const QUrl &url){ d->setURL(url);}/*! The http request header information.*/QHttpRequestHeader QWebNetworkRequest::httpHeader() const{ return d->httpHeader;}void QWebNetworkRequest::setHttpHeader(const QHttpRequestHeader &header) const{ d->httpHeader = header;}QString QWebNetworkRequest::httpHeaderField(const QString &key) const{ return d->httpHeader.value(key);}void QWebNetworkRequest::setHttpHeaderField(const QString &key, const QString &value){ d->httpHeader.setValue(key, value);}/*! Post data sent with HTTP POST requests.*/QByteArray QWebNetworkRequest::postData() const{ return d->postData;}void QWebNetworkRequest::setPostData(const QByteArray &data){ d->postData = data;}/*! \class QWebNetworkJob The QWebNetworkJob class represents a network job, that needs to be processed by the QWebNetworkInterface. This class is only required when implementing a new network layer (or support for a special protocol) using QWebNetworkInterface. QWebNetworkJob objects are created and owned by the QtWebKit library. Most of it's properties are read-only. The job is reference counted. This can be used to ensure that the job doesn't get deleted while it's still stored in some data structure.*//*! \internal*/QWebNetworkJob::QWebNetworkJob() : d(new QWebNetworkJobPrivate){}/*! \internal*/QWebNetworkJob::~QWebNetworkJob(){ delete d; d = 0;}/*! The requested URL*/QUrl QWebNetworkJob::url() const{ return d->request.url;}/*! Post data associated with the job*/QByteArray QWebNetworkJob::postData() const{ return d->request.postData;}/*! The HTTP request header that should be used to download the job.*/QHttpRequestHeader QWebNetworkJob::httpHeader() const{ return d->request.httpHeader;}/*! The complete network request that should be used to download the job.*/QWebNetworkRequest QWebNetworkJob::request() const{ return QWebNetworkRequest(d->request);}/*! The HTTP response header received from the network.*/QHttpResponseHeader QWebNetworkJob::response() const{ return d->response;}/*! The last error of the Job.*/QString QWebNetworkJob::errorString() const{ return d->errorString;}/*! Sets the HTTP reponse header. The response header has to be called before emitting QWebNetworkInterface::started.*/void QWebNetworkJob::setResponse(const QHttpResponseHeader &response){ d->response = response;}void QWebNetworkJob::setErrorString(const QString& errorString){ d->errorString = errorString;}/*! returns true if the job has been cancelled by the WebKit framework*/bool QWebNetworkJob::cancelled() const{ return !d->resourceHandle;}/*! reference the job.*/void QWebNetworkJob::ref(){ ++d->ref;}/*! derefence the job. If the reference count drops to 0 this method also deletes the job. Returns false if the reference count has dropped to 0.*/bool QWebNetworkJob::deref(){ if (!--d->ref) { delete this; return false; } return true;}/*! Returns the network interface that is associated with this job.*/QWebNetworkInterface *QWebNetworkJob::networkInterface() const{ return d->interface;}/*! Returns the network interface that is associated with this job.*/QWebFrame *QWebNetworkJob::frame() const{ if (d->resourceHandle) { ResourceHandleInternal *rhi = d->resourceHandle->getInternal(); if (rhi) { return rhi->m_frame; } } return 0;}QWebNetworkJob::JobStatus QWebNetworkJob::status() const{ return d->jobStatus;}void QWebNetworkJob::setStatus(const JobStatus& status){ d->jobStatus = status;}/*! \class QWebNetworkManager \internal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -