diff options
-rw-r--r-- | src/network/kernel/qnetworkproxy.cpp | 112 | ||||
-rw-r--r-- | src/network/kernel/qnetworkproxy.h | 11 | ||||
-rw-r--r-- | src/network/socket/qhttpsocketengine.cpp | 23 |
3 files changed, 137 insertions, 9 deletions
diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp index 9626a29997..19cf67feec 100644 --- a/src/network/kernel/qnetworkproxy.cpp +++ b/src/network/kernel/qnetworkproxy.cpp @@ -221,6 +221,7 @@ #ifndef QT_NO_NETWORKPROXY #include "private/qnetworkproxy_p.h" +#include "private/qnetworkrequest_p.h" #include "private/qsocks5socketengine_p.h" #include "private/qhttpsocketengine_p.h" #include "qauthenticator.h" @@ -385,6 +386,7 @@ public: quint16 port; QNetworkProxy::ProxyType type; bool capabilitiesSet; + QNetworkHeadersPrivate headers; inline QNetworkProxyPrivate(QNetworkProxy::ProxyType t = QNetworkProxy::DefaultProxy, const QString &h = QString(), quint16 p = 0, @@ -703,6 +705,116 @@ QNetworkProxy QNetworkProxy::applicationProxy() return QNetworkProxy(); } +/*! + Returns the value of the known network header \a header if it is + in use for this proxy. If it is not present, returns QVariant() + (i.e., an invalid variant). + + \sa QNetworkRequest::KnownHeaders, rawHeader(), setHeader() +*/ +QVariant QNetworkProxy::header(QNetworkRequest::KnownHeaders header) const +{ + if (d->type != HttpProxy && d->type != HttpCachingProxy) + return QVariant(); + return d->headers.cookedHeaders.value(header); +} + +/*! + Sets the value of the known header \a header to be \a value, + overriding any previously set headers. This operation also sets + the equivalent raw HTTP header. + + If the proxy is not of type HttpProxy or HttpCachingProxy this has no + effect. + + \sa QNetworkRequest::KnownHeaders, setRawHeader(), header() +*/ +void QNetworkProxy::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value) +{ + if (d->type == HttpProxy || d->type == HttpCachingProxy) + d->headers.setCookedHeader(header, value); +} + +/*! + Returns true if the raw header \a headerName is in use for this + proxy. Returns false if the proxy is not of type HttpProxy or + HttpCachingProxy. + + \sa rawHeader(), setRawHeader() +*/ +bool QNetworkProxy::hasRawHeader(const QByteArray &headerName) const +{ + if (d->type != HttpProxy && d->type != HttpCachingProxy) + return false; + return d->headers.findRawHeader(headerName) != d->headers.rawHeaders.constEnd(); +} + +/*! + Returns the raw form of header \a headerName. If no such header is + present or the proxy is not of type HttpProxy or HttpCachingProxy, + an empty QByteArray is returned, which may be indistinguishable + from a header that is present but has no content (use hasRawHeader() + to find out if the header exists or not). + + Raw headers can be set with setRawHeader() or with setHeader(). + + \sa header(), setRawHeader() +*/ +QByteArray QNetworkProxy::rawHeader(const QByteArray &headerName) const +{ + if (d->type != HttpProxy && d->type != HttpCachingProxy) + return QByteArray(); + QNetworkHeadersPrivate::RawHeadersList::ConstIterator it = + d->headers.findRawHeader(headerName); + if (it != d->headers.rawHeaders.constEnd()) + return it->second; + return QByteArray(); +} + +/*! + Returns a list of all raw headers that are set in this network + proxy. The list is in the order that the headers were set. + + If the proxy is not of type HttpProxy or HttpCachingProxy an empty + QList is returned. + + \sa hasRawHeader(), rawHeader() +*/ +QList<QByteArray> QNetworkProxy::rawHeaderList() const +{ + if (d->type != HttpProxy && d->type != HttpCachingProxy) + return QList<QByteArray>(); + return d->headers.rawHeadersKeys(); +} + +/*! + Sets the header \a headerName to be of value \a headerValue. If \a + headerName corresponds to a known header (see + QNetworkRequest::KnownHeaders), the raw format will be parsed and + the corresponding "cooked" header will be set as well. + + For example: + \snippet doc/src/snippets/code/src_network_access_qnetworkrequest.cpp 0 + + will also set the known header LastModifiedHeader to be the + QDateTime object of the parsed date. + + Note: setting the same header twice overrides the previous + setting. To accomplish the behaviour of multiple HTTP headers of + the same name, you should concatenate the two values, separating + them with a comma (",") and set one single raw header. + + If the proxy is not of type HttpProxy or HttpCachingProxy this has no + effect. + + \sa QNetworkRequest::KnownHeaders, setHeader(), hasRawHeader(), rawHeader() +*/ +void QNetworkProxy::setRawHeader(const QByteArray &headerName, const QByteArray &headerValue) +{ + if (d->type == HttpProxy || d->type == HttpCachingProxy) + d->headers.setRawHeader(headerName, headerValue); +} + class QNetworkProxyQueryPrivate: public QSharedData { public: diff --git a/src/network/kernel/qnetworkproxy.h b/src/network/kernel/qnetworkproxy.h index 3ad052244a..07da51e5ec 100644 --- a/src/network/kernel/qnetworkproxy.h +++ b/src/network/kernel/qnetworkproxy.h @@ -43,6 +43,7 @@ #define QNETWORKPROXY_H #include <QtNetwork/qhostaddress.h> +#include <QtNetwork/qnetworkrequest.h> #include <QtCore/qshareddata.h> #ifndef QT_NO_NETWORKPROXY @@ -174,6 +175,16 @@ public: static void setApplicationProxy(const QNetworkProxy &proxy); static QNetworkProxy applicationProxy(); + // "cooked" headers + QVariant header(QNetworkRequest::KnownHeaders header) const; + void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value); + + // raw headers: + bool hasRawHeader(const QByteArray &headerName) const; + QList<QByteArray> rawHeaderList() const; + QByteArray rawHeader(const QByteArray &headerName) const; + void setRawHeader(const QByteArray &headerName, const QByteArray &value); + private: QSharedDataPointer<QNetworkProxyPrivate> d; }; diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index b62bc05d22..428d21dc72 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -502,15 +502,20 @@ void QHttpSocketEngine::slotSocketConnected() QByteArray data = method; data += path; data += " HTTP/1.1\r\n"; - data += "Proxy-Connection: keep-alive\r\n" - "User-Agent: "; - QVariant v = property("_q_user-agent"); - if (v.isValid()) - data += v.toByteArray(); - else - data += "Mozilla/5.0"; - data += "\r\n" - "Host: " + peerAddress + "\r\n"; + data += "Proxy-Connection: keep-alive\r\n"; + data += "Host: " + peerAddress + "\r\n"; + if (!d->proxy.hasRawHeader("User-Agent")) { + data += "User-Agent: "; + QVariant v = property("_q_user-agent"); + if (v.isValid()) + data += v.toByteArray(); + else + data += "Mozilla/5.0"; + data += "\r\n"; + } + foreach (const QByteArray &header, d->proxy.rawHeaderList()) { + data += header + ": " + d->proxy.rawHeader(header) + "\r\n"; + } QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator); //qDebug() << "slotSocketConnected: priv=" << priv << (priv ? (int)priv->method : -1); if (priv && priv->method != QAuthenticatorPrivate::None) { |