summaryrefslogtreecommitdiffstats
path: root/src/network/socket
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2011-05-10 09:23:30 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2011-05-10 09:23:30 (GMT)
commite81ba9b802d6a5439b672c847aa9741cf3229227 (patch)
treeebb7f1e5dbd83279ee60e51be9884a4e57122138 /src/network/socket
parente75796dfa58652ec8998227d9f547eea990a0353 (diff)
parent19edac88af53eea7f733cabbaee77f9b725b7ea9 (diff)
downloadQt-e81ba9b802d6a5439b672c847aa9741cf3229227.zip
Qt-e81ba9b802d6a5439b672c847aa9741cf3229227.tar.gz
Qt-e81ba9b802d6a5439b672c847aa9741cf3229227.tar.bz2
Merge branch 'symbian-socket-engine' into staging-master
Diffstat (limited to 'src/network/socket')
-rw-r--r--src/network/socket/qabstractsocket.cpp20
-rw-r--r--src/network/socket/qhttpsocketengine.cpp8
-rw-r--r--src/network/socket/qsocks5socketengine.cpp7
-rw-r--r--src/network/socket/qsymbiansocketengine.cpp70
-rw-r--r--src/network/socket/qsymbiansocketengine_p.h2
-rw-r--r--src/network/socket/qtcpserver.cpp5
6 files changed, 87 insertions, 25 deletions
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index cfb1413..fc0bb85 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -547,15 +547,19 @@ bool QAbstractSocketPrivate::initSocketLayer(QAbstractSocket::NetworkLayerProtoc
resetSocketLayer();
socketEngine = QAbstractSocketEngine::createSocketEngine(q->socketType(), proxyInUse, q);
-#ifndef QT_NO_BEARERMANAGEMENT
- //copy network session down to the socket engine (if it has been set)
- socketEngine->setProperty("_q_networksession", q->property("_q_networksession"));
-#endif
if (!socketEngine) {
socketError = QAbstractSocket::UnsupportedSocketOperationError;
q->setErrorString(QAbstractSocket::tr("Operation on socket is not supported"));
return false;
}
+#ifndef QT_NO_BEARERMANAGEMENT
+ //copy network session down to the socket engine (if it has been set)
+ socketEngine->setProperty("_q_networksession", q->property("_q_networksession"));
+#endif
+#ifndef QT_NO_NETWORKPROXY
+ //copy user agent to socket engine (if it has been set)
+ socketEngine->setProperty("_q_user-agent", q->property("_q_user-agent"));
+#endif
if (!socketEngine->initialize(q->socketType(), protocol)) {
#if defined (QABSTRACTSOCKET_DEBUG)
qDebug("QAbstractSocketPrivate::initSocketLayer(%s, %s) failed (%s)",
@@ -1605,15 +1609,15 @@ bool QAbstractSocket::setSocketDescriptor(int socketDescriptor, SocketState sock
d->resetSocketLayer();
d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this);
-#ifndef QT_NO_BEARERMANAGEMENT
- //copy network session down to the socket engine (if it has been set)
- d->socketEngine->setProperty("_q_networksession", property("_q_networksession"));
-#endif
if (!d->socketEngine) {
d->socketError = UnsupportedSocketOperationError;
setErrorString(tr("Operation on socket is not supported"));
return false;
}
+#ifndef QT_NO_BEARERMANAGEMENT
+ //copy network session down to the socket engine (if it has been set)
+ d->socketEngine->setProperty("_q_networksession", property("_q_networksession"));
+#endif
bool result = d->socketEngine->initialize(socketDescriptor, socketState);
if (!result) {
d->socketError = d->socketEngine->error();
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index 7846056..a8a11a7 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -501,7 +501,13 @@ void QHttpSocketEngine::slotSocketConnected()
data += path;
data += " HTTP/1.1\r\n";
data += "Proxy-Connection: keep-alive\r\n"
- "User-Agent: Mozilla/5.0\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";
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator);
//qDebug() << "slotSocketConnected: priv=" << priv << (priv ? (int)priv->method : -1);
diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp
index c365635..88b5aca 100644
--- a/src/network/socket/qsocks5socketengine.cpp
+++ b/src/network/socket/qsocks5socketengine.cpp
@@ -1540,8 +1540,13 @@ qint64 QSocks5SocketEngine::write(const char *data, qint64 len)
// ### Handle this error.
}
- d->data->controlSocket->write(sealedBuf);
+ qint64 written = d->data->controlSocket->write(sealedBuf);
+ if (written <= 0) {
+ QSOCKS5_Q_DEBUG << "native write returned" << written;
+ return written;
+ }
d->data->controlSocket->waitForBytesWritten(0);
+ //NB: returning len rather than written for the OK case, because the "sealing" may increase the length
return len;
#ifndef QT_NO_UDPSOCKET
} else if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode) {
diff --git a/src/network/socket/qsymbiansocketengine.cpp b/src/network/socket/qsymbiansocketengine.cpp
index f1b2982..b6d12fe 100644
--- a/src/network/socket/qsymbiansocketengine.cpp
+++ b/src/network/socket/qsymbiansocketengine.cpp
@@ -251,7 +251,8 @@ QSymbianSocketEnginePrivate::QSymbianSocketEnginePrivate() :
readNotificationsEnabled(false),
writeNotificationsEnabled(false),
exceptNotificationsEnabled(false),
- asyncSelect(0)
+ asyncSelect(0),
+ hasReceivedBufferedDatagram(false)
{
}
@@ -781,21 +782,34 @@ qint64 QSymbianSocketEngine::pendingDatagramSize() const
Q_D(const QSymbianSocketEngine);
Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::pendingDatagramSize(), false);
Q_CHECK_TYPE(QSymbianSocketEngine::hasPendingDatagrams(), QAbstractSocket::UdpSocket, false);
- int nbytes;
+ //can only buffer one datagram at a time
+ if (d->hasReceivedBufferedDatagram)
+ return d->receivedDataBuffer.size();
+ int nbytes = 0;
TInt err = d->nativeSocket.GetOpt(KSOReadBytesPending,KSOLSocket, nbytes);
if (nbytes > 0) {
//nbytes includes IP header, which is of variable length (IPv4 with or without options, IPv6...)
- QByteArray next(nbytes,0);
- TPtr8 buffer((TUint8*)next.data(), next.size());
+ //therefore read the datagram into a buffer to find its true size
+ d->receivedDataBuffer.resize(nbytes);
+ TPtr8 buffer((TUint8*)d->receivedDataBuffer.data(), nbytes);
+ //nbytes = size including IP header, buffer is a pointer descriptor backed by the receivedDataBuffer
TInetAddr addr;
TRequestStatus status;
- //TODO: rather than peek, should we save this for next call to readDatagram?
- //what if calls don't match though?
- d->nativeSocket.RecvFrom(buffer, addr, KSockReadPeek, status);
+ //RecvFrom copies only the payload (we don't want the header so don't specify the option to retrieve it)
+ d->nativeSocket.RecvFrom(buffer, addr, 0, status);
User::WaitForRequest(status);
- if (status.Int())
+ if (status != KErrNone) {
+ d->receivedDataBuffer.clear();
return 0;
- return buffer.Length();
+ }
+ nbytes = buffer.Length();
+ //nbytes = size of payload, resize the receivedDataBuffer to the final size
+ d->receivedDataBuffer.resize(nbytes);
+ d->hasReceivedBufferedDatagram = true;
+ //now receivedDataBuffer contains one datagram, which has been removed from the socket's internal buffer
+#if defined (QNATIVESOCKETENGINE_DEBUG)
+ qDebug() << "QSymbianSocketEngine::pendingDatagramSize buffering" << nbytes << "bytes";
+#endif
}
return qint64(nbytes);
}
@@ -807,6 +821,19 @@ qint64 QSymbianSocketEngine::readDatagram(char *data, qint64 maxSize,
Q_D(QSymbianSocketEngine);
Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::readDatagram(), -1);
Q_CHECK_TYPE(QSymbianSocketEngine::readDatagram(), QAbstractSocket::UdpSocket, false);
+
+ // if a datagram was buffered in pendingDatagramSize(), return it now
+ if (d->hasReceivedBufferedDatagram) {
+ qint64 size = qMin(maxSize, (qint64)d->receivedDataBuffer.size());
+ memcpy(data, d->receivedDataBuffer.constData(), size);
+ d->receivedDataBuffer.clear();
+ d->hasReceivedBufferedDatagram = false;
+#if defined (QNATIVESOCKETENGINE_DEBUG)
+ qDebug() << "QSymbianSocketEngine::readDatagram returning" << size << "bytes from buffer";
+#endif
+ return size;
+ }
+
TPtr8 buffer((TUint8*)data, (int)maxSize);
TInetAddr addr;
TRequestStatus status;
@@ -985,6 +1012,9 @@ void QSymbianSocketEngine::close()
d->localAddress.clear();
d->peerPort = 0;
d->peerAddress.clear();
+
+ d->hasReceivedBufferedDatagram = false;
+ d->receivedDataBuffer.clear();
}
qint64 QSymbianSocketEngine::write(const char *data, qint64 len)
@@ -1036,6 +1066,18 @@ qint64 QSymbianSocketEngine::read(char *data, qint64 maxSize)
Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::read(), -1);
Q_CHECK_STATES(QSymbianSocketEngine::read(), QAbstractSocket::ConnectedState, QAbstractSocket::BoundState, -1);
+ // if a datagram was buffered in pendingDatagramSize(), return it now
+ if (d->hasReceivedBufferedDatagram) {
+ qint64 size = qMin(maxSize, (qint64)d->receivedDataBuffer.size());
+ memcpy(data, d->receivedDataBuffer.constData(), size);
+ d->receivedDataBuffer.clear();
+ d->hasReceivedBufferedDatagram = false;
+#if defined (QNATIVESOCKETENGINE_DEBUG)
+ qDebug() << "QSymbianSocketEngine::read returning" << size << "bytes from buffer";
+#endif
+ return size;
+ }
+
TPtr8 buffer((TUint8*)data, (int)maxSize);
TSockXfrLength received = 0;
TRequestStatus status;
@@ -1440,6 +1482,7 @@ void QSymbianSocketEngine::startNotifications()
qDebug() << "QSymbianSocketEngine::startNotifications" << d->readNotificationsEnabled << d->writeNotificationsEnabled << d->exceptNotificationsEnabled;
#endif
if (!d->asyncSelect && (d->readNotificationsEnabled || d->writeNotificationsEnabled || d->exceptNotificationsEnabled)) {
+ Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::startNotifications(), Q_VOID);
if (d->threadData->eventDispatcher) {
d->asyncSelect = q_check_ptr(new QAsyncSelect(
static_cast<QEventDispatcherSymbian*> (d->threadData->eventDispatcher), d->nativeSocket,
@@ -1456,14 +1499,12 @@ void QSymbianSocketEngine::startNotifications()
bool QSymbianSocketEngine::isReadNotificationEnabled() const
{
Q_D(const QSymbianSocketEngine);
- Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::isReadNotificationEnabled(), false);
return d->readNotificationsEnabled;
}
void QSymbianSocketEngine::setReadNotificationEnabled(bool enable)
{
Q_D(QSymbianSocketEngine);
- Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::setReadNotificationEnabled(), Q_VOID);
#ifdef QNATIVESOCKETENGINE_DEBUG
qDebug() << "QSymbianSocketEngine::setReadNotificationEnabled" << enable << "socket" << d->socketDescriptor;
#endif
@@ -1474,14 +1515,12 @@ void QSymbianSocketEngine::setReadNotificationEnabled(bool enable)
bool QSymbianSocketEngine::isWriteNotificationEnabled() const
{
Q_D(const QSymbianSocketEngine);
- Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::isWriteNotificationEnabled(), false);
return d->writeNotificationsEnabled;
}
void QSymbianSocketEngine::setWriteNotificationEnabled(bool enable)
{
Q_D(QSymbianSocketEngine);
- Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::setWriteNotificationEnabled(), Q_VOID);
#ifdef QNATIVESOCKETENGINE_DEBUG
qDebug() << "QSymbianSocketEngine::setWriteNotificationEnabled" << enable << "socket" << d->socketDescriptor;
#endif
@@ -1492,7 +1531,6 @@ void QSymbianSocketEngine::setWriteNotificationEnabled(bool enable)
bool QSymbianSocketEngine::isExceptionNotificationEnabled() const
{
Q_D(const QSymbianSocketEngine);
- Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::isExceptionNotificationEnabled(), false);
return d->exceptNotificationsEnabled;
return false;
}
@@ -1500,7 +1538,6 @@ bool QSymbianSocketEngine::isExceptionNotificationEnabled() const
void QSymbianSocketEngine::setExceptionNotificationEnabled(bool enable)
{
Q_D(QSymbianSocketEngine);
- Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::setExceptionNotificationEnabled(), Q_VOID);
#ifdef QNATIVESOCKETENGINE_DEBUG
qDebug() << "QSymbianSocketEngine::setExceptionNotificationEnabled" << enable << "socket" << d->socketDescriptor;
#endif
@@ -1660,6 +1697,9 @@ void QAsyncSelect::run()
//when event loop disabled socket events, defer until later
if (maybeDeferSocketEvent())
return;
+#if defined (QNATIVESOCKETENGINE_DEBUG)
+ qDebug() << "QAsyncSelect::run" << m_selectBuf() << m_selectFlags;
+#endif
m_inSocketEvent = true;
m_selectBuf() &= m_selectFlags; //the select ioctl reports everything, so mask to only what we requested
//KSockSelectReadContinuation is for reading datagrams in a mode that doesn't discard when the
diff --git a/src/network/socket/qsymbiansocketengine_p.h b/src/network/socket/qsymbiansocketengine_p.h
index 85ab54a..2e7c155 100644
--- a/src/network/socket/qsymbiansocketengine_p.h
+++ b/src/network/socket/qsymbiansocketengine_p.h
@@ -196,6 +196,8 @@ public:
bool exceptNotificationsEnabled;
QAsyncSelect* asyncSelect;
+ mutable QByteArray receivedDataBuffer;
+ mutable bool hasReceivedBufferedDatagram;
// FIXME this is duplicated from qnativesocketengine_p.h
enum ErrorString {
NonBlockingInitFailedErrorString,
diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp
index 5a60764..026ceb4 100644
--- a/src/network/socket/qtcpserver.cpp
+++ b/src/network/socket/qtcpserver.cpp
@@ -416,6 +416,11 @@ bool QTcpServer::setSocketDescriptor(int socketDescriptor)
if (d->socketEngine)
delete d->socketEngine;
d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this);
+ if (!d->socketEngine) {
+ d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError;
+ d->serverSocketErrorString = tr("Operation on socket is not supported");
+ return false;
+ }
#ifndef QT_NO_BEARERMANAGEMENT
//copy network session down to the socket engine (if it has been set)
d->socketEngine->setProperty("_q_networksession", property("_q_networksession"));