Qt 4.8
Public Types | Public Functions | Public Variables | Protected Slots | Friends | List of all members
QHttpNetworkConnectionChannel Class Reference

#include <qhttpnetworkconnectionchannel_p.h>

Inheritance diagram for QHttpNetworkConnectionChannel:
QObject

Public Types

enum  ChannelState {
  IdleState = 0, ConnectingState = 1, WritingState = 2, WaitingState = 4,
  ReadingState = 8, ClosingState = 16, BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|ClosingState)
}
 
enum  PipeliningSupport { PipeliningSupportUnknown, PipeliningProbablySupported, PipeliningNotSupported }
 

Public Functions

void allDone ()
 
void close ()
 
void closeAndResendCurrentRequest ()
 
void detectPipeliningSupport ()
 
bool ensureConnection ()
 
bool expand (bool dataComplete)
 
void handleStatus ()
 
void handleUnexpectedEOF ()
 
void init ()
 
bool isSocketBusy () const
 
bool isSocketReading () const
 
bool isSocketWaiting () const
 
bool isSocketWriting () const
 
void pipelineFlush ()
 
void pipelineInto (HttpMessagePair &pair)
 
 QHttpNetworkConnectionChannel ()
 
void requeueCurrentlyPipelinedRequests ()
 
bool resetUploadData ()
 
bool sendRequest ()
 
void setConnection (QHttpNetworkConnection *c)
 
- Public Functions inherited from QObject
bool blockSignals (bool b)
 If block is true, signals emitted by this object are blocked (i.e., emitting a signal will not invoke anything connected to it). More...
 
const QObjectListchildren () const
 Returns a list of child objects. More...
 
bool connect (const QObject *sender, const char *signal, const char *member, Qt::ConnectionType type=Qt::AutoConnection) const
 
bool disconnect (const char *signal=0, const QObject *receiver=0, const char *member=0)
 
bool disconnect (const QObject *receiver, const char *member=0)
 
void dumpObjectInfo ()
 Dumps information about signal connections, etc. More...
 
void dumpObjectTree ()
 Dumps a tree of children to the debug output. More...
 
QList< QByteArraydynamicPropertyNames () const
 Returns the names of all properties that were dynamically added to the object using setProperty(). More...
 
virtual bool event (QEvent *)
 This virtual function receives events to an object and should return true if the event e was recognized and processed. More...
 
virtual bool eventFilter (QObject *, QEvent *)
 Filters events if this object has been installed as an event filter for the watched object. More...
 
template<typename T >
findChild (const QString &aName=QString()) const
 Returns the child of this object that can be cast into type T and that is called name, or 0 if there is no such object. More...
 
template<typename T >
QList< T > findChildren (const QString &aName=QString()) const
 Returns all children of this object with the given name that can be cast to type T, or an empty list if there are no such objects. More...
 
template<typename T >
QList< T > findChildren (const QRegExp &re) const
 
bool inherits (const char *classname) const
 Returns true if this object is an instance of a class that inherits className or a QObject subclass that inherits className; otherwise returns false. More...
 
void installEventFilter (QObject *)
 Installs an event filter filterObj on this object. More...
 
bool isWidgetType () const
 Returns true if the object is a widget; otherwise returns false. More...
 
void killTimer (int id)
 Kills the timer with timer identifier, id. More...
 
virtual const QMetaObjectmetaObject () const
 Returns a pointer to the meta-object of this object. More...
 
void moveToThread (QThread *thread)
 Changes the thread affinity for this object and its children. More...
 
QString objectName () const
 
QObjectparent () const
 Returns a pointer to the parent object. More...
 
QVariant property (const char *name) const
 Returns the value of the object's name property. More...
 
Q_INVOKABLE QObject (QObject *parent=0)
 Constructs an object with parent object parent. More...
 
void removeEventFilter (QObject *)
 Removes an event filter object obj from this object. More...
 
void setObjectName (const QString &name)
 
void setParent (QObject *)
 Makes the object a child of parent. More...
 
bool setProperty (const char *name, const QVariant &value)
 Sets the value of the object's name property to value. More...
 
void setUserData (uint id, QObjectUserData *data)
 
bool signalsBlocked () const
 Returns true if signals are blocked; otherwise returns false. More...
 
int startTimer (int interval)
 Starts a timer and returns a timer identifier, or returns zero if it could not start a timer. More...
 
QThreadthread () const
 Returns the thread in which the object lives. More...
 
QObjectUserDatauserData (uint id) const
 
virtual ~QObject ()
 Destroys the object, deleting all its child objects. More...
 

Public Variables

QList< HttpMessagePairalreadyPipelinedRequests
 
bool authenticationCredentialsSent
 
QAuthenticator authenticator
 
QAuthenticatorPrivate::Method authMethod
 
qint64 bytesTotal
 
QPointer< QHttpNetworkConnectionconnection
 
bool ignoreAllSslErrors
 
QList< QSslErrorignoreSslErrorsList
 
int lastStatus
 
QSharedPointer< QNetworkSessionnetworkSession
 
bool pendingEncrypt
 
QByteArray pipeline
 
PipeliningSupport pipeliningSupported
 
QAuthenticator proxyAuthenticator
 
QAuthenticatorPrivate::Method proxyAuthMethod
 
bool proxyCredentialsSent
 
int reconnectAttempts
 
QHttpNetworkReplyreply
 
QHttpNetworkRequest request
 
bool resendCurrent
 
QAbstractSocketsocket
 
bool ssl
 
ChannelState state
 
qint64 written
 

Protected Slots

void _q_bytesWritten (qint64 bytes)
 
void _q_connected ()
 
void _q_disconnected ()
 
void _q_encrypted ()
 
void _q_encryptedBytesWritten (qint64 bytes)
 
void _q_error (QAbstractSocket::SocketError)
 
void _q_proxyAuthenticationRequired (const QNetworkProxy &proxy, QAuthenticator *auth)
 
void _q_readyRead ()
 
void _q_receiveReply ()
 
void _q_sslErrors (const QList< QSslError > &errors)
 
void _q_uploadDataReadyRead ()
 

Friends

class QNetworkAccessHttpBackend
 

Additional Inherited Members

- Public Slots inherited from QObject
void deleteLater ()
 Schedules this object for deletion. More...
 
- Signals inherited from QObject
void destroyed (QObject *=0)
 This signal is emitted immediately before the object obj is destroyed, and can not be blocked. More...
 
- Static Public Functions inherited from QObject
static bool connect (const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
 Creates a connection of the given type from the signal in the sender object to the method in the receiver object. More...
 
static bool connect (const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type=Qt::AutoConnection)
 
static bool disconnect (const QObject *sender, const char *signal, const QObject *receiver, const char *member)
 Disconnects signal in object sender from method in object receiver. More...
 
static bool disconnect (const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &member)
 
static uint registerUserData ()
 
static QString tr (const char *sourceText, const char *comment=0, int n=-1)
 
static QString trUtf8 (const char *sourceText, const char *comment=0, int n=-1)
 
- Static Public Variables inherited from QObject
static const QMetaObject staticMetaObject
 This variable stores the meta-object for the class. More...
 
- Protected Functions inherited from QObject
virtual void childEvent (QChildEvent *)
 This event handler can be reimplemented in a subclass to receive child events. More...
 
virtual void connectNotify (const char *signal)
 This virtual function is called when something has been connected to signal in this object. More...
 
virtual void customEvent (QEvent *)
 This event handler can be reimplemented in a subclass to receive custom events. More...
 
virtual void disconnectNotify (const char *signal)
 This virtual function is called when something has been disconnected from signal in this object. More...
 
 QObject (QObjectPrivate &dd, QObject *parent=0)
 
int receivers (const char *signal) const
 Returns the number of receivers connected to the signal. More...
 
QObjectsender () const
 Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; otherwise it returns 0. More...
 
int senderSignalIndex () const
 
virtual void timerEvent (QTimerEvent *)
 This event handler can be reimplemented in a subclass to receive timer events for the object. More...
 
- Protected Variables inherited from QObject
QScopedPointer< QObjectDatad_ptr
 
- Static Protected Variables inherited from QObject
static const QMetaObject staticQtMetaObject
 

Detailed Description

Definition at line 89 of file qhttpnetworkconnectionchannel_p.h.

Enumerations

◆ ChannelState

◆ PipeliningSupport

Enumerator
PipeliningSupportUnknown 
PipeliningProbablySupported 
PipeliningNotSupported 

Definition at line 127 of file qhttpnetworkconnectionchannel_p.h.

Constructors and Destructors

◆ QHttpNetworkConnectionChannel()

QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel ( )

Definition at line 65 of file qhttpnetworkconnectionchannel.cpp.

66  : socket(0)
67  , ssl(false)
68  , state(IdleState)
69  , reply(0)
70  , written(0)
71  , bytesTotal(0)
72  , resendCurrent(false)
73  , lastStatus(0)
74  , pendingEncrypt(false)
79  , proxyCredentialsSent(false)
80 #ifndef QT_NO_OPENSSL
81  , ignoreAllSslErrors(false)
82 #endif
84  , connection(0)
85 {
86  // Inlining this function in the header leads to compiler error on
87  // release-armv5, on at least timebox 9.2 and 10.1.
88 }
QAuthenticatorPrivate::Method authMethod
QPointer< QHttpNetworkConnection > connection
QAuthenticatorPrivate::Method proxyAuthMethod

Functions

◆ _q_bytesWritten

void QHttpNetworkConnectionChannel::_q_bytesWritten ( qint64  bytes)
protectedslot

Definition at line 980 of file qhttpnetworkconnectionchannel.cpp.

Referenced by init().

981 {
982  Q_UNUSED(bytes);
983  // bytes have been written to the socket. write even more of them :)
984  if (isSocketWriting())
985  sendRequest();
986  // otherwise we do nothing
987 }
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729

◆ _q_connected

void QHttpNetworkConnectionChannel::_q_connected ( )
protectedslot

Definition at line 1014 of file qhttpnetworkconnectionchannel.cpp.

Referenced by init().

1015 {
1016  // improve performance since we get the request sent by the kernel ASAP
1017  //socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
1018  // We have this commented out now. It did not have the effect we wanted. If we want to
1019  // do this properly, Qt has to combine multiple HTTP requests into one buffer
1020  // and send this to the kernel in one syscall and then the kernel immediately sends
1021  // it as one TCP packet because of TCP_NODELAY.
1022  // However, this code is currently not in Qt, so we rely on the kernel combining
1023  // the requests into one TCP packet.
1024 
1025  // not sure yet if it helps, but it makes sense
1027 
1029 
1030  // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again!
1031  //channels[i].reconnectAttempts = 2;
1032  if (!pendingEncrypt) {
1034  if (!reply)
1035  connection->d_func()->dequeueRequest(socket);
1036  if (reply)
1037  sendRequest();
1038  }
1039 }
void setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value)
Sets the given option to the value described by value.
QPointer< QHttpNetworkConnection > connection

◆ _q_disconnected

void QHttpNetworkConnectionChannel::_q_disconnected ( )
protectedslot

Definition at line 989 of file qhttpnetworkconnectionchannel.cpp.

Referenced by init().

990 {
994  return;
995  }
996 
997  // read the available data before closing
998  if (isSocketWaiting() || isSocketReading()) {
999  if (reply) {
1001  _q_receiveReply();
1002  }
1004  // re-sending request because the socket was in ClosingState
1006  }
1008 
1010  close();
1011 }
QPointer< QHttpNetworkConnection > connection
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.

◆ _q_encrypted

void QHttpNetworkConnectionChannel::_q_encrypted ( )
protectedslot

◆ _q_encryptedBytesWritten

void QHttpNetworkConnectionChannel::_q_encryptedBytesWritten ( qint64  bytes)
protectedslot

Definition at line 1191 of file qhttpnetworkconnectionchannel.cpp.

Referenced by init().

1192 {
1193  Q_UNUSED(bytes);
1194  // bytes have been written to the socket. write even more of them :)
1195  if (isSocketWriting())
1196  sendRequest();
1197  // otherwise we do nothing
1198 }
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729

◆ _q_error

void QHttpNetworkConnectionChannel::_q_error ( QAbstractSocket::SocketError  socketError)
protectedslot

Definition at line 1042 of file qhttpnetworkconnectionchannel.cpp.

Referenced by _q_readyRead(), and init().

1043 {
1044  if (!socket)
1045  return;
1047 
1048  switch (socketError) {
1051  break;
1054  break;
1056  // try to reconnect/resend before sending an error.
1057  // while "Reading" the _q_disconnected() will handle this.
1059  if (reconnectAttempts-- > 0) {
1061  return;
1062  } else {
1064  }
1066  if (!reply)
1067  break;
1068 
1069  if (!reply->d_func()->expectContent()) {
1070  // No content expected, this is a valid way to have the connection closed by the server
1071  return;
1072  }
1073  if (reply->contentLength() == -1 && !reply->d_func()->isChunked()) {
1074  // There was no content-length header and it's not chunked encoding,
1075  // so this is a valid way to have the connection closed by the server
1076  return;
1077  }
1078  // ok, we got a disconnect even though we did not expect it
1079  // Try to read everything from the socket before we emit the error.
1080  if (socket->bytesAvailable()) {
1081  // Read everything from the socket into the reply buffer.
1082  // we can ignore the readbuffersize as the data is already
1083  // in memory and we will not recieve more data on the socket.
1085  _q_receiveReply();
1086 #ifndef QT_NO_OPENSSL
1087  if (ssl) {
1088  // QT_NO_OPENSSL. The QSslSocket can still have encrypted bytes in the plainsocket.
1089  // So we need to check this if the socket is a QSslSocket. When the socket is flushed
1090  // it will force a decrypt of the encrypted data in the plainsocket.
1091  QSslSocket *sslSocket = static_cast<QSslSocket*>(socket);
1092  qint64 beforeFlush = sslSocket->encryptedBytesAvailable();
1093  while (sslSocket->encryptedBytesAvailable()) {
1094  sslSocket->flush();
1095  _q_receiveReply();
1096  qint64 afterFlush = sslSocket->encryptedBytesAvailable();
1097  if (afterFlush == beforeFlush)
1098  break;
1099  beforeFlush = afterFlush;
1100  }
1101  }
1102 #endif
1103  }
1104 
1106  } else {
1108  }
1109  break;
1111  // try to reconnect/resend before sending an error.
1114  return;
1115  }
1116  errorCode = QNetworkReply::TimeoutError;
1117  break;
1120  break;
1123  break;
1124  default:
1125  // all other errors are treated as NetworkError
1127  break;
1128  }
1130  QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString());
1131 
1132  // Need to dequeu the request so that we can emit the error.
1133  if (!reply)
1134  connection->d_func()->dequeueRequest(socket);
1135  if (reply) {
1136  reply->d_func()->errorString = errorString;
1137  emit reply->finishedWithError(errorCode, errorString);
1138  reply = 0;
1139  }
1140  // send the next request
1141  QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection);
1142 
1143  if (that) //signal emission triggered event loop
1144  close();
1145 }
qint64 bytesAvailable() const
Returns the number of incoming bytes that are waiting to be read.
QString errorString() const
Returns a human-readable description of the last device error that occurred.
Definition: qiodevice.cpp:1671
The QSslSocket class provides an SSL encrypted socket for both clients and servers.
Definition: qsslsocket.h:67
NetworkError
Indicates all possible error conditions found during the processing of the request.
Definition: qnetworkreply.h:70
QString errorString() const
The QString class provides a Unicode character string.
Definition: qstring.h:83
qint64 encryptedBytesAvailable() const
Returns the number of encrypted bytes that are awaiting decryption.
Definition: qsslsocket.cpp:766
void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail=QString())
Q_GUI_EXPORT QString errorString(EGLint code=eglGetError())
Definition: qegl.cpp:743
QPointer< QHttpNetworkConnection > connection
#define emit
Definition: qobjectdefs.h:76
__int64 qint64
Definition: qglobal.h:942
void setReadBufferSize(qint64 size)
bool flush()
This function writes as much as possible from the internal write buffer to the underlying network soc...
Definition: qsslsocket.cpp:856
qint64 contentLength() const
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.

◆ _q_proxyAuthenticationRequired

void QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired ( const QNetworkProxy proxy,
QAuthenticator auth 
)
protectedslot

Definition at line 1148 of file qhttpnetworkconnectionchannel.cpp.

Referenced by init().

1149 {
1150  // Need to dequeue the request before we can emit the error.
1151  if (!reply)
1152  connection->d_func()->dequeueRequest(socket);
1153  if (reply)
1154  connection->d_func()->emitProxyAuthenticationRequired(this, proxy, auth);
1155 }
QPointer< QHttpNetworkConnection > connection

◆ _q_readyRead

void QHttpNetworkConnectionChannel::_q_readyRead ( )
protectedslot

Definition at line 955 of file qhttpnetworkconnectionchannel.cpp.

Referenced by init().

956 {
958  // We got a readyRead but no bytes are available..
959  // This happens for the Unbuffered QTcpSocket
960  // Also check if socket is in ConnectedState since
961  // this function may also be invoked via the event loop.
962  char c;
963  qint64 ret = socket->peek(&c, 1);
964  if (ret < 0) {
965  _q_error(socket->error());
966  // We still need to handle the reply so it emits its signals etc.
967  if (reply)
968  _q_receiveReply();
969  return;
970  }
971  }
972 
973  if (isSocketWaiting() || isSocketReading()) {
975  if (reply)
976  _q_receiveReply();
977  }
978 }
unsigned char c[8]
Definition: qnumeric_p.h:62
qint64 bytesAvailable() const
Returns the number of incoming bytes that are waiting to be read.
void _q_error(QAbstractSocket::SocketError)
qint64 peek(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, without side effects (i.
Definition: qiodevice.cpp:1563
__int64 qint64
Definition: qglobal.h:942
SocketError error() const
Returns the type of error that last occurred.
SocketState state() const
Returns the state of the socket.

◆ _q_receiveReply

void QHttpNetworkConnectionChannel::_q_receiveReply ( )
protectedslot

Definition at line 334 of file qhttpnetworkconnectionchannel.cpp.

Referenced by _q_disconnected(), _q_error(), and _q_readyRead().

335 {
336  Q_ASSERT(socket);
337 
338  if (!reply) {
339  if (socket->bytesAvailable() > 0)
340  qWarning() << "QHttpNetworkConnectionChannel::_q_receiveReply() called without QHttpNetworkReply,"
341  << socket->bytesAvailable() << "bytes on socket.";
342 
343  close();
344  return;
345  }
346 
347  // only run when the QHttpNetworkConnection is not currently being destructed, e.g.
348  // this function is called from _q_disconnected which is called because
349  // of ~QHttpNetworkConnectionPrivate
350  if (!qobject_cast<QHttpNetworkConnection*>(connection)) {
351  return;
352  }
353 
354  QAbstractSocket::SocketState socketState = socket->state();
355 
356  // connection might be closed to signal the end of data
357  if (socketState == QAbstractSocket::UnconnectedState) {
358  if (socket->bytesAvailable() <= 0) {
359  if (reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) {
360  // finish this reply. this case happens when the server did not send a content length
362  allDone();
363  return;
364  } else {
366  return;
367  }
368  } else {
369  // socket not connected but still bytes for reading.. just continue in this function
370  }
371  }
372 
373  // read loop for the response
374  qint64 bytes = 0;
375  qint64 lastBytes = bytes;
376  do {
377  lastBytes = bytes;
378 
380  switch (state) {
382  state = reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;
383  // fallthrough
384  }
386  qint64 statusBytes = reply->d_func()->readStatus(socket);
387  if (statusBytes == -1) {
388  // connection broke while reading status. also handled if later _q_disconnected is called
390  return;
391  }
392  bytes += statusBytes;
393  lastStatus = reply->d_func()->statusCode;
394  break;
395  }
397  QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
398  qint64 headerBytes = replyPrivate->readHeader(socket);
399  if (headerBytes == -1) {
400  // connection broke while reading headers. also handled if later _q_disconnected is called
402  return;
403  }
404  bytes += headerBytes;
405  // If headers were parsed successfully now it is the ReadingDataState
406  if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) {
407  if (replyPrivate->isGzipped() && replyPrivate->autoDecompress) {
408  // remove the Content-Length from header
409  replyPrivate->removeAutoDecompressHeader();
410  } else {
411  replyPrivate->autoDecompress = false;
412  }
413  if (replyPrivate->statusCode == 100) {
414  replyPrivate->clearHttpLayerInformation();
416  break; // ignore
417  }
418  if (replyPrivate->shouldEmitSignals())
420  // After headerChanged had been emitted
421  // we can suddenly have a replyPrivate->userProvidedDownloadBuffer
422  // this is handled in the ReadingDataState however
423 
424  if (!replyPrivate->expectContent()) {
426  allDone();
427  break;
428  }
429  }
430  break;
431  }
433  QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
435  replyPrivate->downstreamLimited && !replyPrivate->responseData.isEmpty() && replyPrivate->shouldEmitSignals()) {
436  // (only do the following when still connected, not when we have already been disconnected and there is still data)
437  // We already have some HTTP body data. We don't read more from the socket until
438  // this is fetched by QHttpNetworkAccessHttpBackend. If we would read more,
439  // we could not limit our read buffer usage.
440  // We only do this when shouldEmitSignals==true because our HTTP parsing
441  // always needs to parse the 401/407 replies. Therefore they don't really obey
442  // to the read buffer maximum size, but we don't care since they should be small.
443  return;
444  }
445 
446  if (replyPrivate->userProvidedDownloadBuffer) {
447  // the user provided a direct buffer where we should put all our data in.
448  // this only works when we can tell the user the content length and he/she can allocate
449  // the buffer in that size.
450  // note that this call will read only from the still buffered data
451  qint64 haveRead = replyPrivate->readBodyVeryFast(socket, replyPrivate->userProvidedDownloadBuffer + replyPrivate->totalProgress);
452  bytes += haveRead;
453  replyPrivate->totalProgress += haveRead;
454 
455  // the user will get notified of it via progress signal
456  if (haveRead > 0)
457  emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
458  } else if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress
459  && replyPrivate->bodyLength > 0) {
460  // bulk files like images should fulfill these properties and
461  // we can therefore save on memory copying
462  qint64 haveRead = replyPrivate->readBodyFast(socket, &replyPrivate->responseData);
463  bytes += haveRead;
464  replyPrivate->totalProgress += haveRead;
465  if (replyPrivate->shouldEmitSignals()) {
466  emit reply->readyRead();
467  emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
468  }
469  }
470  else
471  {
472  // use the traditional slower reading (for compressed encoding, chunked encoding,
473  // no content-length etc)
474  QByteDataBuffer byteDatas;
475  qint64 haveRead = replyPrivate->readBody(socket, &byteDatas);
476  if (haveRead) {
477  bytes += haveRead;
478  if (replyPrivate->autoDecompress)
479  replyPrivate->appendCompressedReplyData(byteDatas);
480  else
481  replyPrivate->appendUncompressedReplyData(byteDatas);
482 
483  if (!replyPrivate->autoDecompress) {
484  replyPrivate->totalProgress += bytes;
485  if (replyPrivate->shouldEmitSignals()) {
486  // important: At the point of this readyRead(), the byteDatas list must be empty,
487  // else implicit sharing will trigger memcpy when the user is reading data!
488  emit reply->readyRead();
489  emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
490  }
491  }
492 #ifndef QT_NO_COMPRESS
493  else if (!expand(false)) { // expand a chunk if possible
494  // If expand() failed we can just return, it had already called connection->emitReplyError()
495  return;
496  }
497 #endif
498  }
499  }
500  // still in ReadingDataState? This function will be called again by the socket's readyRead
502  break;
503 
504  // everything done, fall through
505  }
507  allDone();
508  break;
509  default:
510  break;
511  }
512  } while (bytes != lastBytes && reply);
513 }
qint64 bytesAvailable() const
Returns the number of incoming bytes that are waiting to be read.
qint64 readHeader(QAbstractSocket *socket)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
SocketState
This enum describes the different states in which a socket can be.
QPointer< QHttpNetworkConnection > connection
#define emit
Definition: qobjectdefs.h:76
Q_CORE_EXPORT void qWarning(const char *,...)
__int64 qint64
Definition: qglobal.h:942
bool isEmpty() const
Definition: qbytedata_p.h:192
void appendUncompressedReplyData(QByteArray &qba)
enum QHttpNetworkReplyPrivate::ReplyState state
qint64 readBody(QAbstractSocket *socket, QByteDataBuffer *out)
qint64 readBodyVeryFast(QAbstractSocket *socket, char *b)
void dataReadProgress(int done, int total)
qint64 readBodyFast(QAbstractSocket *socket, QByteDataBuffer *rb)
void appendCompressedReplyData(QByteDataBuffer &data)
SocketState state() const
Returns the state of the socket.

◆ _q_sslErrors

void QHttpNetworkConnectionChannel::_q_sslErrors ( const QList< QSslError > &  errors)
protectedslot

Definition at line 1176 of file qhttpnetworkconnectionchannel.cpp.

Referenced by init().

1177 {
1178  if (!socket)
1179  return;
1180  //QNetworkReply::NetworkError errorCode = QNetworkReply::ProtocolFailure;
1181  // Also pause the connection because socket notifiers may fire while an user
1182  // dialog is displaying
1183  connection->d_func()->pauseConnection();
1184  if (pendingEncrypt && !reply)
1185  connection->d_func()->dequeueRequest(socket);
1186  if (reply)
1187  emit reply->sslErrors(errors);
1188  connection->d_func()->resumeConnection();
1189 }
QPointer< QHttpNetworkConnection > connection
#define emit
Definition: qobjectdefs.h:76
void sslErrors(const QList< QSslError > &errors)

◆ _q_uploadDataReadyRead

void QHttpNetworkConnectionChannel::_q_uploadDataReadyRead ( )
protectedslot

Definition at line 1158 of file qhttpnetworkconnectionchannel.cpp.

Referenced by sendRequest().

◆ allDone()

void QHttpNetworkConnectionChannel::allDone ( )

Definition at line 687 of file qhttpnetworkconnectionchannel.cpp.

Referenced by _q_receiveReply().

688 {
689  Q_ASSERT(reply);
690 #ifndef QT_NO_COMPRESS
691  // expand the whole data.
692  if (reply->d_func()->expectContent() && reply->d_func()->autoDecompress && !reply->d_func()->streamEnd) {
693  bool expandResult = expand(true);
694  // If expand() failed we can just return, it had already called connection->emitReplyError()
695  if (!expandResult)
696  return;
697  }
698 #endif
699 
700  if (!reply) {
701  qWarning() << "QHttpNetworkConnectionChannel::allDone() called without reply. Please report at http://bugreports.qt-project.org/";
702  return;
703  }
704 
705  // while handling 401 & 407, we might reset the status code, so save this.
706  bool emitFinished = reply->d_func()->shouldEmitSignals();
707  bool connectionCloseEnabled = reply->d_func()->isConnectionCloseEnabled();
709 
710  handleStatus();
711  // handleStatus() might have removed the reply because it already called connection->emitReplyError()
712 
713  // queue the finished signal, this is required since we might send new requests from
714  // slot connected to it. The socket will not fire readyRead signal, if we are already
715  // in the slot connected to readyRead
716  if (reply && emitFinished)
718 
719 
720  // reset the reconnection attempts after we receive a complete reply.
721  // in case of failures, each channel will attempt two reconnects before emitting error.
722  reconnectAttempts = 2;
723 
724  // now the channel can be seen as free/idle again, all signal emissions for the reply have been done
727 
728  // if it does not need to be sent again we can set it to 0
729  // the previous code did not do that and we had problems with accidental re-sending of a
730  // finished request.
731  // Note that this may trigger a segfault at some other point. But then we can fix the underlying
732  // problem.
733  if (!resendCurrent) {
735  reply = 0;
736  }
737 
738  // move next from pipeline to current request
739  if (!alreadyPipelinedRequests.isEmpty()) {
740  if (resendCurrent || connectionCloseEnabled || socket->state() != QAbstractSocket::ConnectedState) {
741  // move the pipelined ones back to the main queue
743  close();
744  } else {
745  // there were requests pipelined in and we can continue
746  HttpMessagePair messagePair = alreadyPipelinedRequests.takeFirst();
747 
748  request = messagePair.first;
749  reply = messagePair.second;
751  resendCurrent = false;
752 
753  written = 0; // message body, excluding the header, irrelevant here
754  bytesTotal = 0; // message body total, excluding the header, irrelevant here
755 
756  // pipeline even more
757  connection->d_func()->fillPipeline(socket);
758 
759  // continue reading
760  //_q_receiveReply();
761  // this was wrong, allDone gets called from that function anyway.
762  }
763  } else if (alreadyPipelinedRequests.isEmpty() && socket->bytesAvailable() > 0) {
764  // this is weird. we had nothing pipelined but still bytes available. better close it.
765  close();
766 
768  } else if (alreadyPipelinedRequests.isEmpty()) {
769  if (connectionCloseEnabled)
771  close();
772  if (qobject_cast<QHttpNetworkConnection*>(connection))
774  }
775 }
qint64 bytesAvailable() const
Returns the number of incoming bytes that are waiting to be read.
T1 first
Definition: qpair.h:65
T2 second
Definition: qpair.h:66
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QPointer< QHttpNetworkConnection > connection
Q_CORE_EXPORT void qWarning(const char *,...)
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.
SocketState state() const
Returns the state of the socket.

◆ close()

void QHttpNetworkConnectionChannel::close ( )

◆ closeAndResendCurrentRequest()

void QHttpNetworkConnectionChannel::closeAndResendCurrentRequest ( )

Definition at line 924 of file qhttpnetworkconnectionchannel.cpp.

Referenced by _q_error(), handleStatus(), and handleUnexpectedEOF().

925 {
927  close();
928  if (reply)
929  resendCurrent = true;
930  if (qobject_cast<QHttpNetworkConnection*>(connection))
932 }
QPointer< QHttpNetworkConnection > connection
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.

◆ detectPipeliningSupport()

void QHttpNetworkConnectionChannel::detectPipeliningSupport ( )

Definition at line 777 of file qhttpnetworkconnectionchannel.cpp.

Referenced by allDone().

778 {
779  Q_ASSERT(reply);
780  // detect HTTP Pipelining support
781  QByteArray serverHeaderField;
782  if (
783  // check for HTTP/1.1
784  (reply->d_func()->majorVersion == 1 && reply->d_func()->minorVersion == 1)
785  // check for not having connection close
786  && (!reply->d_func()->isConnectionCloseEnabled())
787  // check if it is still connected
789  // check for broken servers in server reply header
790  // this is adapted from http://mxr.mozilla.org/firefox/ident?i=SupportsPipelining
791  && (serverHeaderField = reply->headerField("Server"), !serverHeaderField.contains("Microsoft-IIS/4."))
792  && (!serverHeaderField.contains("Microsoft-IIS/5."))
793  && (!serverHeaderField.contains("Netscape-Enterprise/3."))
794  // this is adpoted from the knowledge of the Nokia 7.x browser team (DEF143319)
795  && (!serverHeaderField.contains("WebLogic"))
796  && (!serverHeaderField.startsWith("Rocket")) // a Python Web Server, see Web2py.com
797  ) {
799  } else {
801  }
802 }
QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue=QByteArray()) const
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
bool startsWith(const QByteArray &a) const
Returns true if this byte array starts with byte array ba; otherwise returns false.
SocketState state() const
Returns the state of the socket.
QBool contains(char c) const
Returns true if the byte array contains the character ch; otherwise returns false.
Definition: qbytearray.h:525

◆ ensureConnection()

bool QHttpNetworkConnectionChannel::ensureConnection ( )

Definition at line 535 of file qhttpnetworkconnectionchannel.cpp.

Referenced by QHttpNetworkConnectionPrivate::_q_startNextRequest(), and sendRequest().

536 {
537  QAbstractSocket::SocketState socketState = socket->state();
538 
539  // resend this request after we receive the disconnected signal
540  if (socketState == QAbstractSocket::ClosingState) {
541  if (reply)
542  resendCurrent = true;
543  return false;
544  }
545 
546  // already trying to connect?
547  if (socketState == QAbstractSocket::HostLookupState ||
548  socketState == QAbstractSocket::ConnectingState) {
549  return false;
550  }
551 
552  // make sure that this socket is in a connected state, if not initiate
553  // connection to the host.
554  if (socketState != QAbstractSocket::ConnectedState) {
555  // connect to the host if not already connected.
558 
559  // reset state
562  proxyCredentialsSent = false;
565  priv->hasFailed = false;
568  priv->hasFailed = false;
569 
570  // This workaround is needed since we use QAuthenticator for NTLM authentication. The "phase == Done"
571  // is the usual criteria for emitting authentication signals. The "phase" is set to "Done" when the
572  // last header for Authorization is generated by the QAuthenticator. Basic & Digest logic does not
573  // check the "phase" for generating the Authorization header. NTLM authentication is a two stage
574  // process & needs the "phase". To make sure the QAuthenticator uses the current username/password
575  // the phase is reset to Start.
577  if (priv && priv->phase == QAuthenticatorPrivate::Done)
580  if (priv && priv->phase == QAuthenticatorPrivate::Done)
582 
583  QString connectHost = connection->d_func()->hostName;
584  qint16 connectPort = connection->d_func()->port;
585 
586 #ifndef QT_NO_NETWORKPROXY
587  // HTTPS always use transparent proxy.
588  if (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy && !ssl) {
589  connectHost = connection->d_func()->networkProxy.hostName();
590  connectPort = connection->d_func()->networkProxy.port();
591  }
593  // Make user-agent field available to HTTP proxy socket engine (QTBUG-17223)
594  QByteArray value;
595  // ensureConnection is called before any request has been assigned, but can also be called again if reconnecting
596  if (request.url().isEmpty())
597  value = connection->d_func()->predictNextRequest().headerField("user-agent");
598  else
599  value = request.headerField("user-agent");
600  if (!value.isEmpty())
601  socket->setProperty("_q_user-agent", value);
602  }
603 #endif
604  if (ssl) {
605 #ifndef QT_NO_OPENSSL
606  QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
607  sslSocket->connectToHostEncrypted(connectHost, connectPort);
608  if (ignoreAllSslErrors)
609  sslSocket->ignoreSslErrors();
611 
612  // limit the socket read buffer size. we will read everything into
613  // the QHttpNetworkReply anyway, so let's grow only that and not
614  // here and there.
615  socket->setReadBufferSize(64*1024);
616 #else
617  connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ProtocolUnknownError);
618 #endif
619  } else {
620  // In case of no proxy we can use the Unbuffered QTcpSocket
621 #ifndef QT_NO_NETWORKPROXY
622  if (connection->d_func()->networkProxy.type() == QNetworkProxy::NoProxy
625 #endif
626  socket->connectToHost(connectHost, connectPort, QIODevice::ReadWrite | QIODevice::Unbuffered);
627  // For an Unbuffered QTcpSocket, the read buffer size has a special meaning.
628  socket->setReadBufferSize(1*1024);
629 #ifndef QT_NO_NETWORKPROXY
630  } else {
631  socket->connectToHost(connectHost, connectPort);
632 
633  // limit the socket read buffer size. we will read everything into
634  // the QHttpNetworkReply anyway, so let's grow only that and not
635  // here and there.
636  socket->setReadBufferSize(64*1024);
637  }
638 #endif
639  }
640  return false;
641  }
642  return true;
643 }
QNetworkProxy::ProxyType type() const
Returns the proxy type for this instance.
QNetworkProxy transparentProxy() const
void connectToHost(const QString &hostName, quint16 port, OpenMode mode=ReadWrite)
Attempts to make a connection to hostName on the given port.
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QNetworkProxy proxy() const
Returns the network proxy for this socket.
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
Definition: qurl.cpp:4317
The QSslSocket class provides an SSL encrypted socket for both clients and servers.
Definition: qsslsocket.h:67
bool setProperty(const char *name, const QVariant &value)
Sets the value of the object&#39;s name property to value.
Definition: qobject.cpp:3755
QNetworkProxy cacheProxy() const
void ignoreSslErrors(const QList< QSslError > &errors)
This method tells QSslSocket to ignore only the errors given in errors.
The QString class provides a Unicode character string.
Definition: qstring.h:83
T * qobject_cast(QObject *object)
Definition: qobject.h:375
static QAuthenticatorPrivate * getPrivate(QAuthenticator &auth)
SocketState
This enum describes the different states in which a socket can be.
QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue=QByteArray()) const
QPointer< QHttpNetworkConnection > connection
void connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode mode=ReadWrite)
Starts an encrypted connection to the device hostName on port, using mode as the OpenMode ...
Definition: qsslsocket.cpp:414
short qint16
Definition: qglobal.h:935
void setReadBufferSize(qint64 size)
Sets the size of QAbstractSocket&#39;s internal read buffer to be size bytes.
static const QMetaObjectPrivate * priv(const uint *data)
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
SocketState state() const
Returns the state of the socket.

◆ expand()

bool QHttpNetworkConnectionChannel::expand ( bool  dataComplete)

Definition at line 647 of file qhttpnetworkconnectionchannel.cpp.

Referenced by _q_receiveReply(), and allDone().

648 {
649  Q_ASSERT(socket);
650  Q_ASSERT(reply);
651 
652  qint64 total = reply->d_func()->compressedData.size();
653  if (total >= CHUNK || dataComplete) {
654  // uncompress the data
655  QByteArray content, inflated;
656  content = reply->d_func()->compressedData;
657  reply->d_func()->compressedData.clear();
658 
659  int ret = Z_OK;
660  if (content.size())
661  ret = reply->d_func()->gunzipBodyPartially(content, inflated);
662  if (ret >= Z_OK) {
663  if (dataComplete && ret == Z_OK && !reply->d_func()->streamEnd) {
664  reply->d_func()->gunzipBodyPartiallyEnd();
665  reply->d_func()->streamEnd = true;
666  }
667  if (inflated.size()) {
668  reply->d_func()->totalProgress += inflated.size();
669  reply->d_func()->appendUncompressedReplyData(inflated);
670  if (reply->d_func()->shouldEmitSignals()) {
671  // important: At the point of this readyRead(), inflated must be cleared,
672  // else implicit sharing will trigger memcpy when the user is reading data!
673  emit reply->readyRead();
674  emit reply->dataReadProgress(reply->d_func()->totalProgress, 0);
675  }
676  }
677  } else {
678  connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ProtocolFailure);
679  return false;
680  }
681  }
682  return true;
683 }
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
#define CHUNK
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QPointer< QHttpNetworkConnection > connection
#define emit
Definition: qobjectdefs.h:76
__int64 qint64
Definition: qglobal.h:942
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
void dataReadProgress(int done, int total)

◆ handleStatus()

void QHttpNetworkConnectionChannel::handleStatus ( )

Definition at line 818 of file qhttpnetworkconnectionchannel.cpp.

Referenced by allDone().

819 {
820  Q_ASSERT(socket);
821  Q_ASSERT(reply);
822 
823  int statusCode = reply->statusCode();
824  bool resend = false;
825 
826  switch (statusCode) {
827  case 401: // auth required
828  case 407: // proxy auth required
829  if (connection->d_func()->handleAuthenticateChallenge(socket, reply, (statusCode == 407), resend)) {
830  if (resend) {
831  if (!resetUploadData())
832  break;
833 
834  reply->d_func()->eraseData();
835 
836  if (alreadyPipelinedRequests.isEmpty()) {
837  // this does a re-send without closing the connection
838  resendCurrent = true;
840  } else {
841  // we had requests pipelined.. better close the connection in closeAndResendCurrentRequest
844  }
845  } else {
846  //authentication cancelled, close the channel.
847  close();
848  }
849  } else {
851  emit reply->readyRead();
852  QNetworkReply::NetworkError errorCode = (statusCode == 407)
855  reply->d_func()->errorString = connection->d_func()->errorDetail(errorCode, socket);
856  emit reply->finishedWithError(errorCode, reply->d_func()->errorString);
857  }
858  break;
859  default:
860  if (qobject_cast<QHttpNetworkConnection*>(connection))
862  }
863 }
NetworkError
Indicates all possible error conditions found during the processing of the request.
Definition: qnetworkreply.h:70
QString errorString() const
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail=QString())
QPointer< QHttpNetworkConnection > connection
#define emit
Definition: qobjectdefs.h:76
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.

◆ handleUnexpectedEOF()

void QHttpNetworkConnectionChannel::handleUnexpectedEOF ( )

Definition at line 516 of file qhttpnetworkconnectionchannel.cpp.

Referenced by _q_receiveReply().

517 {
518  Q_ASSERT(reply);
519  if (reconnectAttempts <= 0) {
520  // too many errors reading/receiving/parsing the status, close the socket and emit error
522  close();
523  reply->d_func()->errorString = connection->d_func()->errorDetail(QNetworkReply::RemoteHostClosedError, socket);
526  } else {
528  reply->d_func()->clear();
529  reply->d_func()->connection = connection;
530  reply->d_func()->connectionChannel = this;
532  }
533 }
QString errorString() const
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail=QString())
QPointer< QHttpNetworkConnection > connection
#define emit
Definition: qobjectdefs.h:76
QHttpNetworkConnection * connection()
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.

◆ init()

void QHttpNetworkConnectionChannel::init ( )

Definition at line 90 of file qhttpnetworkconnectionchannel.cpp.

Referenced by QHttpNetworkConnectionPrivate::init().

91 {
92 #ifndef QT_NO_OPENSSL
93  if (connection->d_func()->encrypt)
94  socket = new QSslSocket;
95  else
96  socket = new QTcpSocket;
97 #else
98  socket = new QTcpSocket;
99 #endif
100 #ifndef QT_NO_BEARERMANAGEMENT
101  //push session down to socket
102  if (networkSession)
103  socket->setProperty("_q_networksession", QVariant::fromValue(networkSession));
104 #endif
105 #ifndef QT_NO_NETWORKPROXY
106  // Set by QNAM anyway, but let's be safe here
108 #endif
109 
110  QObject::connect(socket, SIGNAL(bytesWritten(qint64)),
111  this, SLOT(_q_bytesWritten(qint64)),
114  this, SLOT(_q_connected()),
116  QObject::connect(socket, SIGNAL(readyRead()),
117  this, SLOT(_q_readyRead()),
119 
120  // The disconnected() and error() signals may already come
121  // while calling connectToHost().
122  // In case of a cached hostname or an IP this
123  // will then emit a signal to the user of QNetworkReply
124  // but cannot be caught because the user did not have a chance yet
125  // to connect to QNetworkReply's signals.
126  qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
127  QObject::connect(socket, SIGNAL(disconnected()),
128  this, SLOT(_q_disconnected()),
133 
134 
135 #ifndef QT_NO_NETWORKPROXY
136  QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
139 #endif
140 
141 #ifndef QT_NO_OPENSSL
142  QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
143  if (sslSocket) {
144  // won't be a sslSocket if encrypt is false
145  QObject::connect(sslSocket, SIGNAL(encrypted()),
146  this, SLOT(_q_encrypted()),
148  QObject::connect(sslSocket, SIGNAL(sslErrors(QList<QSslError>)),
151  QObject::connect(sslSocket, SIGNAL(encryptedBytesWritten(qint64)),
154  }
155 #endif
156 }
#define error(msg)
void _q_sslErrors(const QList< QSslError > &errors)
#define SLOT(a)
Definition: qobjectdefs.h:226
The QSslSocket class provides an SSL encrypted socket for both clients and servers.
Definition: qsslsocket.h:67
bool setProperty(const char *name, const QVariant &value)
Sets the value of the object&#39;s name property to value.
Definition: qobject.cpp:3755
T * qobject_cast(QObject *object)
Definition: qobject.h:375
void _q_error(QAbstractSocket::SocketError)
#define SIGNAL(a)
Definition: qobjectdefs.h:227
The QNetworkProxy class provides a network layer proxy.
static QIntfbScreen * connected
QSharedPointer< QNetworkSession > networkSession
QPointer< QHttpNetworkConnection > connection
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
SocketError
This enum describes the socket errors that can occur.
The QTcpSocket class provides a TCP socket.
Definition: qtcpsocket.h:56
__int64 qint64
Definition: qglobal.h:942
static QVariant fromValue(const T &value)
Returns a QVariant containing a copy of value.
Definition: qvariant.h:336
The QAuthenticator class provides an authentication object.
void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth)
void setProxy(const QNetworkProxy &networkProxy)
Sets the explicit network proxy for this socket to networkProxy.

◆ isSocketBusy()

bool QHttpNetworkConnectionChannel::isSocketBusy ( ) const

◆ isSocketReading()

bool QHttpNetworkConnectionChannel::isSocketReading ( ) const

◆ isSocketWaiting()

bool QHttpNetworkConnectionChannel::isSocketWaiting ( ) const

◆ isSocketWriting()

bool QHttpNetworkConnectionChannel::isSocketWriting ( ) const

◆ pipelineFlush()

void QHttpNetworkConnectionChannel::pipelineFlush ( )

Definition at line 909 of file qhttpnetworkconnectionchannel.cpp.

Referenced by QHttpNetworkConnectionPrivate::fillPipeline().

910 {
911  if (pipeline.isEmpty())
912  return;
913 
914  // The goal of this is so that we have everything in one TCP packet.
915  // For the Unbuffered QTcpSocket this is manually needed, the buffered
916  // QTcpSocket does it automatically.
917  // Also, sometimes the OS does it for us (Nagle's algorithm) but that
918  // happens only sometimes.
920  pipeline.clear();
921 }
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
Definition: qiodevice.cpp:1342
void clear()
Clears the contents of the byte array and makes it empty.

◆ pipelineInto()

void QHttpNetworkConnectionChannel::pipelineInto ( HttpMessagePair pair)

Definition at line 885 of file qhttpnetworkconnectionchannel.cpp.

Referenced by QHttpNetworkConnectionPrivate::fillPipeline().

886 {
887  // this is only called for simple GET
888 
891  reply->d_func()->clear();
892  reply->d_func()->connection = connection;
893  reply->d_func()->connectionChannel = this;
894  reply->d_func()->autoDecompress = request.d->autoDecompress;
895  reply->d_func()->pipeliningUsed = true;
896 
897 #ifndef QT_NO_NETWORKPROXY
899  (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy)));
900 #else
902 #endif
903 
904  alreadyPipelinedRequests.append(pair);
905 
906  // pipelineFlush() needs to be called at some point afterwards
907 }
QSharedDataPointer< QHttpNetworkRequestPrivate > d
QByteArray & append(char c)
Appends the character ch to this byte array.
T1 first
Definition: qpair.h:65
T2 second
Definition: qpair.h:66
QPointer< QHttpNetworkConnection > connection
QHttpNetworkConnection * connection()
static QByteArray header(const QHttpNetworkRequest &request, bool throughProxy)

◆ requeueCurrentlyPipelinedRequests()

void QHttpNetworkConnectionChannel::requeueCurrentlyPipelinedRequests ( )

Definition at line 805 of file qhttpnetworkconnectionchannel.cpp.

Referenced by _q_disconnected(), allDone(), closeAndResendCurrentRequest(), QHttpNetworkConnectionPrivate::emitReplyError(), handleUnexpectedEOF(), and QHttpNetworkConnectionPrivate::removeReply().

806 {
807  for (int i = 0; i < alreadyPipelinedRequests.length(); i++)
808  connection->d_func()->requeueRequest(alreadyPipelinedRequests.at(i));
809  alreadyPipelinedRequests.clear();
810 
811  // only run when the QHttpNetworkConnection is not currently being destructed, e.g.
812  // this function is called from _q_disconnected which is called because
813  // of ~QHttpNetworkConnectionPrivate
814  if (qobject_cast<QHttpNetworkConnection*>(connection))
816 }
QPointer< QHttpNetworkConnection > connection
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.

◆ resetUploadData()

bool QHttpNetworkConnectionChannel::resetUploadData ( )

Definition at line 865 of file qhttpnetworkconnectionchannel.cpp.

Referenced by handleStatus().

866 {
867  if (!reply) {
868  //this happens if server closes connection while QHttpNetworkConnectionPrivate::_q_startNextRequest is pending
869  return false;
870  }
871  QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
872  if (!uploadByteDevice)
873  return true;
874 
875  if (uploadByteDevice->reset()) {
876  written = 0;
877  return true;
878  } else {
879  connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ContentReSendError);
880  return false;
881  }
882 }
virtual bool reset()=0
Moves the internal read pointer back to the beginning.
QNonContiguousByteDevice * uploadByteDevice() const
QPointer< QHttpNetworkConnection > connection
A QNonContiguousByteDevice is a representation of a file, array or buffer that allows access with a r...

◆ sendRequest()

bool QHttpNetworkConnectionChannel::sendRequest ( )

Definition at line 170 of file qhttpnetworkconnectionchannel.cpp.

Referenced by _q_bytesWritten(), _q_connected(), _q_encrypted(), _q_encryptedBytesWritten(), QHttpNetworkConnectionPrivate::_q_startNextRequest(), and _q_uploadDataReadyRead().

171 {
172  if (!reply) {
173  // heh, how should that happen!
174  qWarning() << "QHttpNetworkConnectionChannel::sendRequest() called without QHttpNetworkReply";
176  return false;
177  }
178 
179  switch (state) {
180  case QHttpNetworkConnectionChannel::IdleState: { // write the header
181  if (!ensureConnection()) {
182  // wait for the connection (and encryption) to be done
183  // sendRequest will be called again from either
184  // _q_connected or _q_encrypted
185  return false;
186  }
187  written = 0; // excluding the header
188  bytesTotal = 0;
189 
190  QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
191  replyPrivate->clear();
192  replyPrivate->connection = connection;
193  replyPrivate->connectionChannel = this;
194  replyPrivate->autoDecompress = request.d->autoDecompress;
195  replyPrivate->pipeliningUsed = false;
196 
197  // if the url contains authentication parameters, use the new ones
198  // both channels will use the new authentication parameters
200  QUrl url = request.url();
202  if (url.userName() != auth.user()
203  || (!url.password().isEmpty() && url.password() != auth.password())) {
204  auth.setUser(url.userName());
205  auth.setPassword(url.password());
206  connection->d_func()->copyCredentials(connection->d_func()->indexOf(socket), &auth, false);
207  }
208  // clear the userinfo, since we use the same request for resending
209  // userinfo in url can conflict with the one in the authenticator
210  url.setUserInfo(QString());
211  request.setUrl(url);
212  }
213  // Will only be false if QtWebKit is performing a cross-origin XMLHttpRequest
214  // and withCredentials has not been set to true.
215  if (request.withCredentials())
216  connection->d_func()->createAuthorization(socket, request);
217 #ifndef QT_NO_NETWORKPROXY
219  (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy));
220 #else
222 #endif
223  socket->write(header);
224  // flushing is dangerous (QSslSocket calls transmit which might read or error)
225 // socket->flush();
226  QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
227  if (uploadByteDevice) {
228  // connect the signals so this function gets called again
229  QObject::connect(uploadByteDevice, SIGNAL(readyRead()),this, SLOT(_q_uploadDataReadyRead()));
230 
232 
233  state = QHttpNetworkConnectionChannel::WritingState; // start writing data
234  sendRequest(); //recurse
235  } else {
236  state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
237  sendRequest(); //recurse
238  }
239 
240  break;
241  }
243  {
244  // write the data
245  QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
246  if (!uploadByteDevice || bytesTotal == written) {
247  if (uploadByteDevice)
249  state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
250  sendRequest(); // recurse
251  break;
252  }
253 
254  // only feed the QTcpSocket buffer when there is less than 32 kB in it
255  const qint64 socketBufferFill = 32*1024;
256  const qint64 socketWriteMaxSize = 16*1024;
257 
258 
259 #ifndef QT_NO_OPENSSL
260  QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
261  // if it is really an ssl socket, check more than just bytesToWrite()
262  while ((socket->bytesToWrite() + (sslSocket ? sslSocket->encryptedBytesToWrite() : 0))
263  <= socketBufferFill && bytesTotal != written)
264 #else
265  while (socket->bytesToWrite() <= socketBufferFill
266  && bytesTotal != written)
267 #endif
268  {
269  // get pointer to upload data
270  qint64 currentReadSize = 0;
271  qint64 desiredReadSize = qMin(socketWriteMaxSize, bytesTotal - written);
272  const char *readPointer = uploadByteDevice->readPointer(desiredReadSize, currentReadSize);
273 
274  if (currentReadSize == -1) {
275  // premature eof happened
276  connection->d_func()->emitReplyError(socket, reply, QNetworkReply::UnknownNetworkError);
277  return false;
278  break;
279  } else if (readPointer == 0 || currentReadSize == 0) {
280  // nothing to read currently, break the loop
281  break;
282  } else {
283  qint64 currentWriteSize = socket->write(readPointer, currentReadSize);
284  if (currentWriteSize == -1 || currentWriteSize != currentReadSize) {
285  // socket broke down
286  connection->d_func()->emitReplyError(socket, reply, QNetworkReply::UnknownNetworkError);
287  return false;
288  } else {
289  written += currentWriteSize;
290  uploadByteDevice->advanceReadPointer(currentWriteSize);
291 
293 
294  if (written == bytesTotal) {
295  // make sure this function is called once again
297  sendRequest();
298  break;
299  }
300  }
301  }
302  }
303  break;
304  }
305 
307  {
308  QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
309  if (uploadByteDevice) {
310  QObject::disconnect(uploadByteDevice, SIGNAL(readyRead()), this, SLOT(_q_uploadDataReadyRead()));
311  }
312 
313  // HTTP pipelining
314  //connection->d_func()->fillPipeline(socket);
315  //socket->flush();
316 
317  // ensure we try to receive a reply in all cases, even if _q_readyRead_ hat not been called
318  // this is needed if the sends an reply before we have finished sending the request. In that
319  // case receiveReply had been called before but ignored the server reply
320  if (socket->bytesAvailable())
321  QMetaObject::invokeMethod(this, "_q_receiveReply", Qt::QueuedConnection);
322  break;
323  }
325  // ignore _q_bytesWritten in these states
326  // fall through
327  default:
328  break;
329  }
330  return true;
331 }
QSharedDataPointer< QHttpNetworkRequestPrivate > d
void setUserInfo(const QString &userInfo)
Sets the user info of the URL to userInfo.
Definition: qurl.cpp:4615
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
qint64 bytesAvailable() const
Returns the number of incoming bytes that are waiting to be read.
qint64 encryptedBytesToWrite() const
Returns the number of encrypted bytes that are waiting to be written to the network.
Definition: qsslsocket.cpp:783
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
#define SLOT(a)
Definition: qobjectdefs.h:226
The QSslSocket class provides an SSL encrypted socket for both clients and servers.
Definition: qsslsocket.h:67
void dataSendProgress(qint64 done, qint64 total)
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
The QString class provides a Unicode character string.
Definition: qstring.h:83
T * qobject_cast(QObject *object)
Definition: qobject.h:375
void setUser(const QString &user)
Sets the user used for authentication.
virtual const char * readPointer(qint64 maximumLength, qint64 &len)=0
Return a byte pointer for at most maximumLength bytes of that device.
QNonContiguousByteDevice * uploadByteDevice() const
#define SIGNAL(a)
Definition: qobjectdefs.h:227
void setUrl(const QUrl &url)
QPointer< QHttpNetworkConnection > connection
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
#define emit
Definition: qobjectdefs.h:76
QString userInfo() const
Returns the user info of the URL, or an empty string if the user info is undefined.
Definition: qurl.cpp:4631
Q_CORE_EXPORT void qWarning(const char *,...)
__int64 qint64
Definition: qglobal.h:942
The QAuthenticator class provides an authentication object.
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Disconnects signal in object sender from method in object receiver.
Definition: qobject.cpp:2895
QString userName() const
Returns the user name of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4667
QPointer< QHttpNetworkConnectionChannel > connectionChannel
static QByteArray header(const QHttpNetworkRequest &request, bool throughProxy)
virtual bool advanceReadPointer(qint64 amount)=0
The old readPointer is invalid after this call.
QString user() const
returns the user used for authentication.
qint64 bytesToWrite() const
Returns the number of bytes that are waiting to be written.
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.
A QNonContiguousByteDevice is a representation of a file, array or buffer that allows access with a r...
QPointer< QHttpNetworkConnection > connection
void setPassword(const QString &password)
Sets the password used for authentication.
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
Definition: qiodevice.cpp:1342
QString password() const
returns the password used for authentication.
QString password() const
Returns the password of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4754

◆ setConnection()

void QHttpNetworkConnectionChannel::setConnection ( QHttpNetworkConnection c)

Definition at line 1202 of file qhttpnetworkconnectionchannel.cpp.

Referenced by QHttpNetworkConnectionPrivate::init().

1203 {
1204  // Inlining this function in the header leads to compiler error on
1205  // release-armv5, on at least timebox 9.2 and 10.1.
1206  connection = c;
1207 }
unsigned char c[8]
Definition: qnumeric_p.h:62
QPointer< QHttpNetworkConnection > connection

Friends and Related Functions

◆ QNetworkAccessHttpBackend

Definition at line 166 of file qhttpnetworkconnectionchannel_p.h.

Properties

◆ alreadyPipelinedRequests

QList<HttpMessagePair> QHttpNetworkConnectionChannel::alreadyPipelinedRequests

◆ authenticationCredentialsSent

bool QHttpNetworkConnectionChannel::authenticationCredentialsSent

◆ authenticator

QAuthenticator QHttpNetworkConnectionChannel::authenticator

◆ authMethod

QAuthenticatorPrivate::Method QHttpNetworkConnectionChannel::authMethod

◆ bytesTotal

qint64 QHttpNetworkConnectionChannel::bytesTotal

Definition at line 107 of file qhttpnetworkconnectionchannel_p.h.

Referenced by allDone(), and sendRequest().

◆ connection

QPointer<QHttpNetworkConnection> QHttpNetworkConnectionChannel::connection

◆ ignoreAllSslErrors

bool QHttpNetworkConnectionChannel::ignoreAllSslErrors

Definition at line 119 of file qhttpnetworkconnectionchannel_p.h.

Referenced by ensureConnection().

◆ ignoreSslErrorsList

QList<QSslError> QHttpNetworkConnectionChannel::ignoreSslErrorsList

Definition at line 120 of file qhttpnetworkconnectionchannel_p.h.

Referenced by ensureConnection().

◆ lastStatus

int QHttpNetworkConnectionChannel::lastStatus

Definition at line 109 of file qhttpnetworkconnectionchannel_p.h.

Referenced by _q_receiveReply().

◆ networkSession

QSharedPointer<QNetworkSession> QHttpNetworkConnectionChannel::networkSession

Definition at line 123 of file qhttpnetworkconnectionchannel_p.h.

Referenced by init(), and QHttpNetworkConnectionPrivate::init().

◆ pendingEncrypt

bool QHttpNetworkConnectionChannel::pendingEncrypt

◆ pipeline

QByteArray QHttpNetworkConnectionChannel::pipeline

Definition at line 134 of file qhttpnetworkconnectionchannel_p.h.

Referenced by pipelineFlush(), and pipelineInto().

◆ pipeliningSupported

PipeliningSupport QHttpNetworkConnectionChannel::pipeliningSupported

◆ proxyAuthenticator

QAuthenticator QHttpNetworkConnectionChannel::proxyAuthenticator

◆ proxyAuthMethod

QAuthenticatorPrivate::Method QHttpNetworkConnectionChannel::proxyAuthMethod

◆ proxyCredentialsSent

bool QHttpNetworkConnectionChannel::proxyCredentialsSent

◆ reconnectAttempts

int QHttpNetworkConnectionChannel::reconnectAttempts

Definition at line 111 of file qhttpnetworkconnectionchannel_p.h.

Referenced by _q_error(), allDone(), and handleUnexpectedEOF().

◆ reply

QHttpNetworkReply* QHttpNetworkConnectionChannel::reply

◆ request

QHttpNetworkRequest QHttpNetworkConnectionChannel::request

◆ resendCurrent

bool QHttpNetworkConnectionChannel::resendCurrent

◆ socket

QAbstractSocket* QHttpNetworkConnectionChannel::socket

◆ ssl

bool QHttpNetworkConnectionChannel::ssl

◆ state

ChannelState QHttpNetworkConnectionChannel::state

◆ written

qint64 QHttpNetworkConnectionChannel::written

Definition at line 106 of file qhttpnetworkconnectionchannel_p.h.

Referenced by allDone(), resetUploadData(), and sendRequest().


The documentation for this class was generated from the following files: