📄 q3http.cpp
字号:
Q_ULONG Q3Http::bytesAvailable() const{#if defined(Q3HTTP_DEBUG) qDebug( "Q3Http::bytesAvailable(): %d bytes", (int)d->rba.size() );#endif return d->rba.size();}/*! Reads \a maxlen bytes from the response content into \a data and returns the number of bytes read. Returns -1 if an error occurred. \sa get() post() request() readyRead() bytesAvailable() readAll()*/Q_LONG Q3Http::readBlock( char *data, Q_ULONG maxlen ){ if ( data == 0 && maxlen != 0 ) {#if defined(QT_CHECK_NULL) qWarning( "Q3Http::readBlock: Null pointer error" );#endif return -1; } if ( maxlen >= (Q_ULONG)d->rba.size() ) maxlen = d->rba.size(); d->rba.consumeBytes( maxlen, data ); d->bytesDone += maxlen;#if defined(Q3HTTP_DEBUG) qDebug( "Q3Http::readBlock(): read %d bytes (%d bytes done)", (int)maxlen, d->bytesDone );#endif return maxlen;}/*! Reads all the bytes from the response content and returns them. \sa get() post() request() readyRead() bytesAvailable() readBlock()*/QByteArray Q3Http::readAll(){ Q_ULONG avail = bytesAvailable(); QByteArray tmp( avail ); Q_LONG read = readBlock( tmp.data(), avail ); tmp.resize( read ); return tmp;}/*! Returns the identifier of the HTTP request being executed or 0 if there is no request being executed (i.e. they've all finished). \sa currentRequest()*/int Q3Http::currentId() const{ Q3HttpRequest *r = d->pending.getFirst(); if ( r == 0 ) return 0; return r->id;}/*! Returns the request header of the HTTP request being executed. If the request is one issued by setHost() or closeConnection(), it returns an invalid request header, i.e. Q3HttpRequestHeader::isValid() returns false. \sa currentId()*/Q3HttpRequestHeader Q3Http::currentRequest() const{ Q3HttpRequest *r = d->pending.getFirst(); if ( r != 0 && r->hasRequestHeader() ) return r->requestHeader(); return Q3HttpRequestHeader();}/*! Returns the QIODevice pointer that is used as the data source of the HTTP request being executed. If there is no current request or if the request does not use an IO device as the data source, this function returns 0. This function can be used to delete the QIODevice in the slot connected to the requestFinished() signal. \sa currentDestinationDevice() post() request()*/QIODevice* Q3Http::currentSourceDevice() const{ Q3HttpRequest *r = d->pending.getFirst(); if ( !r ) return 0; return r->sourceDevice();}/*! Returns the QIODevice pointer that is used as to store the data of the HTTP request being executed. If there is no current request or if the request does not store the data to an IO device, this function returns 0. This function can be used to delete the QIODevice in the slot connected to the requestFinished() signal. \sa get() post() request()*/QIODevice* Q3Http::currentDestinationDevice() const{ Q3HttpRequest *r = d->pending.getFirst(); if ( !r ) return 0; return r->destinationDevice();}/*! Returns true if there are any requests scheduled that have not yet been executed; otherwise returns false. The request that is being executed is \e not considered as a scheduled request. \sa clearPendingRequests() currentId() currentRequest()*/bool Q3Http::hasPendingRequests() const{ return d->pending.count() > 1;}/*! Deletes all pending requests from the list of scheduled requests. This does not affect the request that is being executed. If you want to stop this this as well, use abort(). \sa hasPendingRequests() abort()*/void Q3Http::clearPendingRequests(){ Q3HttpRequest *r = 0; if ( d->pending.count() > 0 ) r = d->pending.take( 0 ); d->pending.clear(); if ( r ) d->pending.append( r );}/*! Sets the HTTP server that is used for requests to \a hostname on port \a port. The function does not block and returns immediately. The request is scheduled, and its execution is performed asynchronously. The function returns a unique identifier which is passed by requestStarted() and requestFinished(). When the request is started the requestStarted() signal is emitted. When it is finished the requestFinished() signal is emitted. \sa get() post() head() request() requestStarted() requestFinished() done()*/int Q3Http::setHost(const QString &hostname, Q_UINT16 port ){ return addRequest( new Q3HttpSetHostRequest( hostname, port ) );}/*! Sends a get request for \a path to the server set by setHost() or as specified in the constructor. \a path must be an absolute path like \c /index.html or an absolute URI like \c http://www.trolltech.com/index.html. If the IO device \a to is 0 the readyRead() signal is emitted every time new content data is available to read. If the IO device \a to is not 0, the content data of the response is written directly to the device. Make sure that the \a to pointer is valid for the duration of the operation (it is safe to delete it when the requestFinished() signal is emitted). The function does not block and returns immediately. The request is scheduled, and its execution is performed asynchronously. The function returns a unique identifier which is passed by requestStarted() and requestFinished(). When the request is started the requestStarted() signal is emitted. When it is finished the requestFinished() signal is emitted. \sa setHost() post() head() request() requestStarted() requestFinished() done()*/int Q3Http::get( const QString& path, QIODevice* to ){ Q3HttpRequestHeader header( QLatin1String("GET"), path ); header.setValue( QLatin1String("Connection"), QLatin1String("Keep-Alive") ); return addRequest( new Q3HttpPGHRequest( header, (QIODevice*)0, to ) );}/*! Sends a post request for \a path to the server set by setHost() or as specified in the constructor. \a path must be an absolute path like \c /index.html or an absolute URI like \c http://www.trolltech.com/index.html. The incoming data comes via the \a data IO device. If the IO device \a to is 0 the readyRead() signal is emitted every time new content data is available to read. If the IO device \a to is not 0, the content data of the response is written directly to the device. Make sure that the \a to pointer is valid for the duration of the operation (it is safe to delete it when the requestFinished() signal is emitted). The function does not block and returns immediately. The request is scheduled, and its execution is performed asynchronously. The function returns a unique identifier which is passed by requestStarted() and requestFinished(). When the request is started the requestStarted() signal is emitted. When it is finished the requestFinished() signal is emitted. \sa setHost() get() head() request() requestStarted() requestFinished() done()*/int Q3Http::post( const QString& path, QIODevice* data, QIODevice* to ){ Q3HttpRequestHeader header( QLatin1String("POST"), path ); header.setValue( QLatin1String("Connection"), QLatin1String("Keep-Alive") ); return addRequest( new Q3HttpPGHRequest( header, data, to ) );}/*! \overload \a data is used as the content data of the HTTP request.*/int Q3Http::post( const QString& path, const QByteArray& data, QIODevice* to ){ Q3HttpRequestHeader header( QLatin1String("POST"), path ); header.setValue( QLatin1String("Connection"), QLatin1String("Keep-Alive") ); return addRequest( new Q3HttpPGHRequest( header, new QByteArray(data), to ) );}/*! Sends a header request for \a path to the server set by setHost() or as specified in the constructor. \a path must be an absolute path like \c /index.html or an absolute URI like \c http://www.trolltech.com/index.html. The function does not block and returns immediately. The request is scheduled, and its execution is performed asynchronously. The function returns a unique identifier which is passed by requestStarted() and requestFinished(). When the request is started the requestStarted() signal is emitted. When it is finished the requestFinished() signal is emitted. \sa setHost() get() post() request() requestStarted() requestFinished() done()*/int Q3Http::head( const QString& path ){ Q3HttpRequestHeader header( QLatin1String("HEAD"), path ); header.setValue( QLatin1String("Connection"), QLatin1String("Keep-Alive") ); return addRequest( new Q3HttpPGHRequest( header, (QIODevice*)0, 0 ) );}/*! Sends a request to the server set by setHost() or as specified in the constructor. Uses the \a header as the HTTP request header. You are responsible for setting up a header that is appropriate for your request. The incoming data comes via the \a data IO device. If the IO device \a to is 0 the readyRead() signal is emitted every time new content data is available to read. If the IO device \a to is not 0, the content data of the response is written directly to the device. Make sure that the \a to pointer is valid for the duration of the operation (it is safe to delete it when the requestFinished() signal is emitted). The function does not block and returns immediately. The request is scheduled, and its execution is performed asynchronously. The function returns a unique identifier which is passed by requestStarted() and requestFinished(). When the request is started the requestStarted() signal is emitted. When it is finished the requestFinished() signal is emitted. \sa setHost() get() post() head() requestStarted() requestFinished() done()*/int Q3Http::request( const Q3HttpRequestHeader &header, QIODevice *data, QIODevice *to ){ return addRequest( new Q3HttpNormalRequest( header, data, to ) );}/*! \overload \a data is used as the content data of the HTTP request.*/int Q3Http::request( const Q3HttpRequestHeader &header, const QByteArray &data, QIODevice *to ){ return addRequest( new Q3HttpNormalRequest( header, new QByteArray(data), to ) );}/*! Closes the connection; this is useful if you have a keep-alive connection and want to close it. For the requests issued with get(), post() and head(), Q3Http sets the connection to be keep-alive. You can also do this using the header you pass to the request() function. Q3Http only closes the connection to the HTTP server if the response header requires it to do so. The function does not block and returns immediately. The request is scheduled, and its execution is performed asynchronously. The function returns a unique identifier which is passed by requestStarted() and requestFinished(). When the request is started the requestStarted() signal is emitted. When it is finished the requestFinished() signal is emitted. If you want to close the connection immediately, you have to use abort() instead. \sa stateChanged() abort() requestStarted() requestFinished() done()*/int Q3Http::closeConnection(){ return addRequest( new Q3HttpCloseRequest() );}int Q3Http::addRequest( Q3HttpRequest *req ){ d->pending.append( req ); if ( d->pending.count() == 1 ) // don't emit the requestStarted() signal before the id is returned QTimer::singleShot( 0, this, SLOT(startNextRequest()) ); return req->id;}void Q3Http::startNextRequest(){ Q3HttpRequest *r = d->pending.getFirst(); if ( r == 0 ) return; d->error = NoError; d->errorString = QHttp::tr( "Unknown error" ); if ( bytesAvailable() ) readAll(); // clear the data emit requestStarted( r->id ); r->start( this );}void Q3Http::sendRequest(){ if ( d->hostname.isNull() ) { finishedWithError( QHttp::tr("No server set to connect to"), UnknownError ); return; } killIdleTimer(); // Do we need to setup a new connection or can we reuse an // existing one ? if ( d->socket.peerName() != d->hostname || d->socket.peerPort() != d->port || d->socket.state() != Q3Socket::Connection ) { setState( Q3Http::Connecting ); d->socket.connectToHost( d->hostname, d->port ); } else { slotConnected(); }}void Q3Http::finishedWithSuccess(){ Q3HttpRequest *r = d->pending.getFirst(); if ( r == 0 ) return; emit requestFinished( r->id, false ); d->pending.removeFirst(); if ( d->pending.isEmpty() ) { emit done( false ); } else { startNextRequest(); }}void Q3Http::finishedWithError( const QString& detail, int errorCode ){ Q3HttpRequest *r = d->pending.getFirst(); if ( r == 0 ) return; d->error = (Error)errorCode; d->errorString = detail; emit requestFinished( r->id, true ); d->pending.clear(); emit done( true );}void Q3Http::slotClosed(){ if ( d->state == Closing ) return; if ( d->state == Reading ) { if ( d->response.hasKey( QLatin1String("content-length") ) ) { // We got Content-Length, so did we get all bytes? if ( d->bytesDone+bytesAvailable() != d->response.contentLength() ) { finishedWithError( QHttp::tr("Wrong content length"), WrongContentLength ); } } } else if ( d->state == Connecting || d->state == Sending ) { finishedWithError( QHttp::tr("Server closed connection unexpectedly"), UnexpectedClose ); } d->postDevice = 0; setState( Closing ); d->idleTimer = startTimer( 0 );}void Q3Http::slotConnected(){ if ( d->state != Sending ) { d->bytesDone = 0; setState( Sending ); } QString str = d->header.toString(); d->bytesTotal = str.length(); d->socket.writeBlock( str.latin1(), d->bytesTotal );#if defined(Q3HTTP_DEBUG) qDebug( "Q3Http: write request header:\n---{\n%s}---", str.latin1() );#endif if ( d->postDevice ) { d->bytesTotal += d->postDevice->size(); } else { d->bytesTotal += d->buffer.size(); d->socket.writeBlock( d->buffer.data(), d->buffer.size() ); d->buffer = QByteArray(); // save memory }}void Q3Http::slotError( int err ){ d->postDevice = 0; if ( d->state == Connecting || d->state == Reading || d->state == Sending ) { switch ( err ) { case Q3Socket::ErrConnectionRefused: finishedWithError( QHttp::tr("Connection refused"), ConnectionRefused ); break; case Q3Socket::ErrHostNotFound: finishedWithError( QHttp::tr("Host %1 not found").arg(d->socket.peerName()), HostNotFound );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -