bool UPNPSubscription::SendUnsubscribeRequest(const QString &usn, const QUrl &url, const QString &path, const QString &uuid) { bool success = false; QString host = url.host(); int port = url.port(); QByteArray sub; QTextStream data(&sub); data.setCodec(QTextCodec::codecForName("UTF-8")); // N.B. Play On needs an extra space between UNSUBSCRIBE and path... data << QString("UNSUBSCRIBE %1 HTTP/1.1\r\n").arg(path); data << QString("HOST: %1:%2\r\n").arg(host).arg(QString::number(port)); data << QString("SID: uuid:%1\r\n").arg(uuid); data << "\r\n"; data.flush(); LOG(VB_UPNP, LOG_DEBUG, LOC + "\n\n" + sub); MSocketDevice *sockdev = new MSocketDevice(MSocketDevice::Stream); BufferedSocketDevice *sock = new BufferedSocketDevice(sockdev); sockdev->setBlocking(true); if (sock->Connect(QHostAddress(host), port)) { if (sock->WriteBlockDirect(sub.constData(), sub.size()) != -1) { QString line = sock->ReadLine(MAX_WAIT); success = !line.isEmpty(); } else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Socket write error for %1:%2") .arg(host).arg(port)); } sock->Close(); } else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open socket for %1:%2") .arg(host).arg(port)); } delete sock; delete sockdev; if (success) LOG(VB_GENERAL, LOG_INFO, LOC + QString("Unsubscribed to %1").arg(usn)); else LOG(VB_UPNP, LOG_WARNING, LOC + QString("Failed to unsubscribe to %1") .arg(usn)); return success; }
void UPnpEventTask::Execute( TaskQueue * /*pQueue*/ ) { if (m_pPayload == NULL) return; MSocketDevice *pSockDev = new MSocketDevice( MSocketDevice::Stream ); BufferedSocketDevice *pSock = new BufferedSocketDevice( pSockDev ); pSockDev->setBlocking( true ); if (pSock->Connect( m_PeerAddress, m_nPeerPort )) { // ------------------------------------------------------------------ // Send NOTIFY message // ------------------------------------------------------------------ if (pSock->WriteBlockDirect( m_pPayload->data(), m_pPayload->size() ) != -1) { // -------------------------------------------------------------- // Read first line to determine success/Fail // -------------------------------------------------------------- QString sResponseLine = pSock->ReadLine( 3000 ); if ( sResponseLine.length() > 0) { //if (sResponseLine.contains("200 OK")) //{ VERBOSE( VB_UPNP, QString( "UPnpEventTask::Execute - NOTIFY to %1:%2 returned %3." ) .arg( m_PeerAddress.toString() ) .arg( m_nPeerPort ) .arg( sResponseLine )); //} } else { VERBOSE( VB_UPNP, QString( "UPnpEventTask::Execute - Timeout reading first line of reply from %1:%2." ) .arg( m_PeerAddress.toString() ) .arg( m_nPeerPort ) ); } } else VERBOSE( VB_UPNP, QString( "UPnpEventTask::Execute - Error sending to %1:%2." ) .arg( m_PeerAddress.toString() ) .arg( m_nPeerPort ) ); pSock->Close(); } else { VERBOSE( VB_UPNP, QString( "UPnpEventTask::Execute - Error sending to %1:%2." ) .arg( m_PeerAddress.toString() ) .arg( m_nPeerPort ) ); } if ( pSock != NULL ) delete pSock; if ( pSockDev != NULL ) delete pSockDev; }
void UPnpEventTask::Execute( TaskQueue * /*pQueue*/ ) { if (m_pPayload == NULL) return; MSocketDevice sockDev( MSocketDevice::Stream ); BufferedSocketDevice sock ( &sockDev ); sockDev.setBlocking( true ); if (sock.Connect( m_PeerAddress, m_nPeerPort )) { // ------------------------------------------------------------------ // Send NOTIFY message // ------------------------------------------------------------------ if (sock.WriteBlockDirect( m_pPayload->data(), m_pPayload->size() ) != -1) { // -------------------------------------------------------------- // Read first line to determine success/Fail // -------------------------------------------------------------- QString sResponseLine = sock.ReadLine( 3000 ); if ( sResponseLine.length() > 0) { #if 0 if (sResponseLine.contains("200 OK")) { #endif LOG(VB_UPNP, LOG_INFO, QString("UPnpEventTask::Execute - NOTIFY to " "%1:%2 returned %3.") .arg(m_PeerAddress.toString()) .arg(m_nPeerPort) .arg(sResponseLine)); #if 0 } #endif } else { LOG(VB_UPNP, LOG_ERR, QString("UPnpEventTask::Execute - Timeout reading first " "line of reply from %1:%2.") .arg(m_PeerAddress.toString()) .arg(m_nPeerPort)); } } else LOG(VB_UPNP, LOG_ERR, QString("UPnpEventTask::Execute - Error sending to %1:%2.") .arg(m_PeerAddress.toString()) .arg(m_nPeerPort)); sock.Close(); } else { LOG(VB_UPNP, LOG_ERR, QString("UPnpEventTask::Execute - Error sending to %1:%2.") .arg(m_PeerAddress.toString()) .arg(m_nPeerPort)); } }
void HttpWorkerThread::ProcessWork() { // VERBOSE( VB_UPNP, QString( "HttpWorkerThread::ProcessWork:Begin( %1 ) socket=%2" ) // .arg( (long)QThread::currentThread() ) // .arg( m_nSocket )); bool bTimeout = false; bool bKeepAlive = true; BufferedSocketDevice *pSocket = NULL; HTTPRequest *pRequest = NULL; try { if ((pSocket = new BufferedSocketDevice( m_nSocket )) == NULL) { VERBOSE( VB_IMPORTANT, QString( "HttpWorkerThread::ProcessWork - Error Creating BufferedSocketDevice" )); return; } pSocket->SocketDevice()->setBlocking( true ); while( !m_bTermRequested && bKeepAlive && pSocket->IsValid()) { bTimeout = 0; int64_t nBytes = pSocket->WaitForMore(m_nSocketTimeout, &bTimeout); if ( nBytes > 0) { // ---------------------------------------------------------- // See if this is a valid request // ---------------------------------------------------------- if ((pRequest = new BufferedSocketDeviceRequest( pSocket )) != NULL) { if ( pRequest->ParseRequest() ) { bKeepAlive = pRequest->GetKeepAlive(); // ------------------------------------------------------ // Request Parsed... Pass on to Main HttpServer class to // delegate processing to HttpServerExtensions. // ------------------------------------------------------ m_pHttpServer->DelegateRequest( this, pRequest ); } else { VERBOSE( VB_UPNP, QString( "HttpWorkerThread::ProcessWork - ParseRequest Failed." )); pRequest->m_nResponseStatus = 501; bKeepAlive = false; } /* // Dump Request Header if (!bKeepAlive ) { for ( QStringMap::iterator it = pRequest->m_mapHeaders.begin(); it != pRequest->m_mapHeaders.end(); ++it ) { cout << it.key() << ": " << it.data() << endl; } } */ // ---------------------------------------------------------- // Always MUST send a response. // ---------------------------------------------------------- if (pRequest->SendResponse() < 0) { bKeepAlive = false; VERBOSE( VB_UPNP, QString( "HttpWorkerThread::ProcessWork socket(%1) - Error returned from SendResponse... Closing connection" ) .arg( m_nSocket )); } // ---------------------------------------------------------- // Check to see if a PostProcess was registered // ---------------------------------------------------------- if ( pRequest->m_pPostProcess != NULL ) pRequest->m_pPostProcess->ExecutePostProcess(); delete pRequest; pRequest = NULL; } else { VERBOSE( VB_IMPORTANT, QString( "HttpWorkerThread::ProcessWork - Error Creating BufferedSocketDeviceRequest" )); bKeepAlive = false; } } else { bKeepAlive = false; } } } catch( ... ) { VERBOSE( VB_IMPORTANT, QString( "HttpWorkerThread::ProcessWork - Unexpected Exception." )); } if (pRequest != NULL) delete pRequest; pSocket->Close(); delete pSocket; m_nSocket = 0; // VERBOSE( VB_UPNP, QString( "HttpWorkerThread::ProcessWork:End( %1 )") // .arg( (long)QThread::currentThread() )); }
int UPNPSubscription::SendSubscribeRequest(const QString &callback, const QString &usn, const QUrl &url, const QString &path, const QString &uuidin, QString &uuidout) { QString host = url.host(); int port = url.port(); QByteArray sub; QTextStream data(&sub); data.setCodec(QTextCodec::codecForName("UTF-8")); // N.B. Play On needs an extra space between SUBSCRIBE and path... data << QString("SUBSCRIBE %1 HTTP/1.1\r\n").arg(path); data << QString("HOST: %1:%2\r\n").arg(host).arg(QString::number(port)); if (uuidin.isEmpty()) // new subscription { data << QString("CALLBACK: <%1%2>\r\n") .arg(callback).arg(usn); data << "NT: upnp:event\r\n"; } else // renewal data << QString("SID: uuid:%1\r\n").arg(uuidin); data << QString("TIMEOUT: Second-%1\r\n").arg(SUBSCRIPTION_TIME); data << "\r\n"; data.flush(); LOG(VB_UPNP, LOG_DEBUG, LOC + "\n\n" + sub); MSocketDevice *sockdev = new MSocketDevice(MSocketDevice::Stream); BufferedSocketDevice *sock = new BufferedSocketDevice(sockdev); sockdev->setBlocking(true); QString uuid; QString timeout; uint result = 0; if (sock->Connect(QHostAddress(host), port)) { if (sock->WriteBlockDirect(sub.constData(), sub.size()) != -1) { bool ok = false; QString line = sock->ReadLine(MAX_WAIT); while (!line.isEmpty()) { LOG(VB_UPNP, LOG_DEBUG, LOC + line); if (line.contains("HTTP/1.1 200 OK", Qt::CaseInsensitive)) ok = true; if (line.startsWith("SID:", Qt::CaseInsensitive)) uuid = line.mid(4).trimmed().mid(5).trimmed(); if (line.startsWith("TIMEOUT:", Qt::CaseInsensitive)) timeout = line.mid(8).trimmed().mid(7).trimmed(); if (ok && !uuid.isEmpty() && !timeout.isEmpty()) break; line = sock->ReadLine(MAX_WAIT); } if (ok && !uuid.isEmpty() && !timeout.isEmpty()) { uuidout = uuid; result = timeout.toUInt(); } else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to subscribe to %1").arg(usn)); } } else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Socket write error for %1:%2") .arg(host).arg(port)); } sock->Close(); } else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open socket for %1:%2") .arg(host).arg(port)); } delete sock; delete sockdev; return result; }
void HttpWorker::run(void) { #if 0 LOG(VB_UPNP, LOG_DEBUG, QString("HttpWorker::run() socket=%1 -- begin").arg(m_socket)); #endif bool bTimeout = false; bool bKeepAlive = true; BufferedSocketDevice *pSocket = NULL; HTTPRequest *pRequest = NULL; try { if ((pSocket = new BufferedSocketDevice( m_socket )) == NULL) { LOG(VB_GENERAL, LOG_ERR, "Error Creating BufferedSocketDevice"); return; } pSocket->SocketDevice()->setBlocking( true ); while (m_httpServer.IsRunning() && bKeepAlive && pSocket->IsValid()) { bTimeout = false; int64_t nBytes = pSocket->WaitForMore(m_socketTimeout, &bTimeout); if (!m_httpServer.IsRunning()) break; if ( nBytes > 0) { // ---------------------------------------------------------- // See if this is a valid request // ---------------------------------------------------------- pRequest = new BufferedSocketDeviceRequest( pSocket ); if (pRequest != NULL) { if ( pRequest->ParseRequest() ) { bKeepAlive = pRequest->GetKeepAlive(); // ------------------------------------------------------ // Request Parsed... Pass on to Main HttpServer class to // delegate processing to HttpServerExtensions. // ------------------------------------------------------ if (pRequest->m_nResponseStatus != 401) m_httpServer.DelegateRequest(pRequest); } else { LOG(VB_UPNP, LOG_ERR, "ParseRequest Failed."); pRequest->m_nResponseStatus = 501; bKeepAlive = false; } #if 0 // Dump Request Header if (!bKeepAlive ) { for ( QStringMap::iterator it = pRequest->m_mapHeaders.begin(); it != pRequest->m_mapHeaders.end(); ++it ) { LOG(VB_GENERAL, LOG_DEBUG, QString("%1: %2") .arg(it.key()) .arg(it.data())); } } #endif // ------------------------------------------------------- // Always MUST send a response. // ------------------------------------------------------- if (pRequest->SendResponse() < 0) { bKeepAlive = false; LOG(VB_UPNP, LOG_ERR, QString("socket(%1) - Error returned from " "SendResponse... Closing connection") .arg(m_socket)); } // ------------------------------------------------------- // Check to see if a PostProcess was registered // ------------------------------------------------------- if ( pRequest->m_pPostProcess != NULL ) pRequest->m_pPostProcess->ExecutePostProcess(); delete pRequest; pRequest = NULL; } else { LOG(VB_GENERAL, LOG_ERR, "Error Creating BufferedSocketDeviceRequest"); bKeepAlive = false; } } else { bKeepAlive = false; } } } catch(...) { LOG(VB_GENERAL, LOG_ERR, "HttpWorkerThread::ProcessWork - Unexpected Exception."); } if (pRequest != NULL) delete pRequest; pSocket->Close(); delete pSocket; m_socket = 0; #if 0 LOG(VB_UPNP, LOG_DEBUG, "HttpWorkerThread::run() -- end"); #endif }