#include <q3http.h>
Inheritance diagram for Q3Http:


This class provides two different interfaces: one is the Q3NetworkProtocol interface that allows you to use HTTP through the QUrlOperator abstraction. The other is a direct interface to HTTP that allows you to have more control over the requests and that allows you to access the response header fields.
Don't mix the two interfaces, since the behavior is not well-defined.
If you want to use Q3Http with the Q3NetworkProtocol interface, you do not use it directly, but rather through a QUrlOperator, for example:
QUrlOperator op( "http://www.trolltech.com" ); op.get( "index.html" );
This code will only work if the Q3Http class is registered; to register the class, you must call q3InitNetworkProtocols() before using a QUrlOperator with HTTP.
The Q3NetworkProtocol interface for HTTP only supports the operations operationGet() and operationPut(), i.e. QUrlOperator::get() and QUrlOperator::put(), if you use it with a QUrlOperator.
The rest of this descrption describes the direct interface to HTTP.
The class works asynchronously, so there are no blocking functions. If an operation cannot be executed immediately, the function will still return straight away and the operation will be scheduled for later execution. The results of scheduled operations are reported via signals. This approach depends on the event loop being in operation.
The operations that can be scheduled (they are called "requests" in the rest of the documentation) are the following: setHost(), get(), post(), head() and request().
All of these requests return a unique identifier that allows you to keep track of the request that is currently executed. When the execution of a request starts, the requestStarted() signal with the identifier is emitted and when the request is finished, the requestFinished() signal is emitted with the identifier and a bool that indicates if the request finished with an error.
To make an HTTP request you must set up suitable HTTP headers. The following example demonstrates, how to request the main HTML page from the Trolltech home page (i.e. the URL http://www.trolltech.com/index.html):
Q3HttpRequestHeader header( "GET", "/index.html" ); header.setValue( "Host", "www.trolltech.com" ); http->setHost( "www.trolltech.com" ); http->request( header );
For the common HTTP requests GET, POST and HEAD, Q3Http provides the convenience functions get(), post() and head(). They already use a reasonable header and if you don't have to set special header fields, they are easier to use. The above example can also be written as:
http->setHost( "www.trolltech.com" ); // id == 1 http->get( "/index.html" ); // id == 2
For this example the following sequence of signals is emitted (with small variations, depending on network traffic, etc.):
requestStarted( 1 ) requestFinished( 1, false ) requestStarted( 2 ) stateChanged( Connecting ) stateChanged( Sending ) dataSendProgress( 77, 77 ) stateChanged( Reading ) responseHeaderReceived( responseheader ) dataReadProgress( 5388, 0 ) readyRead( responseheader ) dataReadProgress( 18300, 0 ) readyRead( responseheader ) stateChanged( Connected ) requestFinished( 2, false ) done( false ) stateChanged( Closing ) stateChanged( Unconnected )
The dataSendProgress() and dataReadProgress() signals in the above example are useful if you want to show a progressbar to inform the user about the progress of the download. The second argument is the total size of data. In certain cases it is not possible to know the total amount in advance, in which case the second argument is 0. (If you connect to a QProgressBar a total of 0 results in a busy indicator.)
When the response header is read, it is reported with the responseHeaderReceived() signal.
The readyRead() signal tells you that there is data ready to be read. The amount of data can then be queried with the bytesAvailable() function and it can be read with the readBlock() or readAll() functions.
If an error occurs during the execution of one of the commands in a sequence of commands, all the pending commands (i.e. scheduled, but not yet executed commands) are cleared and no signals are emitted for them.
For example, if you have the following sequence of reqeusts
http->setHost( "www.foo.bar" ); // id == 1 http->get( "/index.html" ); // id == 2 http->post( "register.html", data ); // id == 3
and the get() request fails because the host lookup fails, then the post() request is never executed and the signals would look like this:
requestStarted( 1 ) requestFinished( 1, false ) requestStarted( 2 ) stateChanged( HostLookup ) requestFinished( 2, true ) done( true ) stateChanged( Unconnected )
You can then get details about the error with the error() and errorString() functions. Note that only unexpected behaviour, like network failure is considered as an error. If the server response contains an error status, like a 404 response, this is reported as a normal response case. So you should always check the status code of the response header.
The functions currentId() and currentRequest() provide more information about the currently executing request.
The functions hasPendingRequests() and clearPendingRequests() allow you to query and clear the list of pending requests.
Definition at line 147 of file q3http.h.
Public Types | |
| enum | State |
| enum | Error |
Public Slots | |
| void | abort () |
Signals | |
| void | stateChanged (int) |
| void | responseHeaderReceived (const Q3HttpResponseHeader &resp) |
| void | readyRead (const Q3HttpResponseHeader &resp) |
| void | dataSendProgress (int, int) |
| void | dataReadProgress (int, int) |
| void | requestStarted (int) |
| void | requestFinished (int, bool) |
| void | done (bool) |
Public Member Functions | |
| Q3Http () | |
| Q3Http (QObject *parent, const char *name=0) | |
| Q3Http (const QString &hostname, Q_UINT16 port=80, QObject *parent=0, const char *name=0) | |
| virtual | ~Q3Http () |
| int | supportedOperations () const |
| int | setHost (const QString &hostname, Q_UINT16 port=80) |
| int | get (const QString &path, QIODevice *to=0) |
| int | post (const QString &path, QIODevice *data, QIODevice *to=0) |
| int | post (const QString &path, const QByteArray &data, QIODevice *to=0) |
| int | head (const QString &path) |
| int | request (const Q3HttpRequestHeader &header, QIODevice *device=0, QIODevice *to=0) |
| int | request (const Q3HttpRequestHeader &header, const QByteArray &data, QIODevice *to=0) |
| int | closeConnection () |
| Q_ULONG | bytesAvailable () const |
| Q_LONG | readBlock (char *data, Q_ULONG maxlen) |
| QByteArray | readAll () |
| int | currentId () const |
| QIODevice * | currentSourceDevice () const |
| QIODevice * | currentDestinationDevice () const |
| Q3HttpRequestHeader | currentRequest () const |
| bool | hasPendingRequests () const |
| void | clearPendingRequests () |
| State | state () const |
| Error | error () const |
| QString | errorString () const |
Protected Member Functions | |
| void | operationGet (Q3NetworkOperation *op) |
| void | operationPut (Q3NetworkOperation *op) |
| void | timerEvent (QTimerEvent *) |
Private Slots | |
| void | clientReply (const Q3HttpResponseHeader &rep) |
| void | clientDone (bool) |
| void | clientStateChanged (int) |
| void | startNextRequest () |
| void | slotReadyRead () |
| void | slotConnected () |
| void | slotError (int) |
| void | slotClosed () |
| void | slotBytesWritten (int) |
Private Member Functions | |
| int | addRequest (Q3HttpRequest *) |
| void | sendRequest () |
| void | finishedWithSuccess () |
| void | finishedWithError (const QString &detail, int errorCode) |
| void | killIdleTimer () |
| void | init () |
| void | setState (int) |
| void | close () |
Private Attributes | |
| Q3HttpPrivate * | d |
| void * | unused |
| int | bytesRead |
Friends | |
| class | Q3HttpNormalRequest |
| class | Q3HttpSetHostRequest |
| class | Q3HttpCloseRequest |
| class | Q3HttpPGHRequest |
| enum Q3Http::State |
This enum is used to specify the state the client is in:
Unconnected There is no connection to the host. HostLookup A host name lookup is in progress. Connecting An attempt to connect to the host is in progress. Sending The client is sending its request to the server. Reading The client's request has been sent and the client is reading the server's response. Connected The connection to the host is open, but the client is neither sending a request, nor waiting for a response. Closing The connection is closing down, but is not yet closed. (The state will be Unconnected when the connection is closed.)
Reimplemented from Q3NetworkProtocol.
Definition at line 159 of file q3http.h.
00159 { Unconnected, HostLookup, Connecting, Sending, Reading, Connected, Closing };
| enum Q3Http::Error |
This enum identifies the error that occurred.
NoError No error occurred. HostNotFound The host name lookup failed. ConnectionRefused The server refused the connection. UnexpectedClose The server closed the connection unexpectedly. InvalidResponseHeader The server sent an invalid response header. WrongContentLength The client could not read the content correctly because an error with respect to the content length occurred. Aborted The request was aborted with abort(). UnknownError An error other than those specified above occurred.
Reimplemented from Q3NetworkProtocol.
Definition at line 160 of file q3http.h.
00160 { 00161 NoError, 00162 UnknownError, 00163 HostNotFound, 00164 ConnectionRefused, 00165 UnexpectedClose, 00166 InvalidResponseHeader, 00167 WrongContentLength, 00168 Aborted 00169 };
| Q3Http::Q3Http | ( | ) |
Constructs a Q3Http object.
Definition at line 1152 of file q3http.cpp.
References init().
01153 { 01154 init(); 01155 }
Here is the call graph for this function:

| Q3Http::Q3Http | ( | QObject * | parent, | |
| const char * | name = 0 | |||
| ) |
Constructs a Q3Http object. The parameters parent and name are passed on to the QObject constructor.
Definition at line 1161 of file q3http.cpp.
References init(), and QObject::parent().
01162 { 01163 if ( parent ) 01164 parent->insertChild( this ); 01165 setName( name ); 01166 init(); 01167 }
Here is the call graph for this function:

| Q3Http::Q3Http | ( | const QString & | hostname, | |
| Q_UINT16 | port = 80, |
|||
| QObject * | parent = 0, |
|||
| const char * | name = 0 | |||
| ) |
Constructs a Q3Http object. Subsequent requests are done by connecting to the server hostname on port port. The parameters parent and name are passed on to the QObject constructor.
Definition at line 1177 of file q3http.cpp.
References d, Q3HttpPrivate::hostname, init(), QObject::parent(), and Q3HttpPrivate::port.
01178 { 01179 if ( parent ) 01180 parent->insertChild( this ); 01181 setName( name ); 01182 init(); 01183 01184 d->hostname = hostname; 01185 d->port = port; 01186 }
Here is the call graph for this function:

| Q3Http::~Q3Http | ( | ) | [virtual] |
| int Q3Http::supportedOperations | ( | ) | const [virtual] |
Reimplemented from Q3NetworkProtocol.
Definition at line 2193 of file q3http.cpp.
References Q3NetworkProtocol::OpGet, and Q3NetworkProtocol::OpPut.
| int Q3Http::setHost | ( | const QString & | hostname, | |
| Q_UINT16 | port = 80 | |||
| ) |
Sets the HTTP server that is used for requests to hostname on port 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.
Definition at line 1560 of file q3http.cpp.
References addRequest(), and Q3HttpSetHostRequest.
Referenced by operationGet(), and operationPut().
01561 { 01562 return addRequest( new Q3HttpSetHostRequest( hostname, port ) ); 01563 }
Here is the call graph for this function:

Sends a get request for path to the server set by setHost() or as specified in the constructor.
path must be an absolute path like /index.html or an absolute URI like http://www.trolltech.com/index.html.
If the IO device to is 0 the readyRead() signal is emitted every time new content data is available to read.
If the IO device to is not 0, the content data of the response is written directly to the device. Make sure that the 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.
Definition at line 1591 of file q3http.cpp.
References addRequest(), header(), path, and Q3HttpPGHRequest.
01592 { 01593 Q3HttpRequestHeader header( "GET", path ); 01594 header.setValue( "Connection", "Keep-Alive" ); 01595 return addRequest( new Q3HttpPGHRequest( header, (QIODevice*)0, to ) ); 01596 }
Here is the call graph for this function:

Sends a post request for path to the server set by setHost() or as specified in the constructor.
path must be an absolute path like /index.html or an absolute URI like http://www.trolltech.com/index.html.
The incoming data comes via the data IO device.
If the IO device to is 0 the readyRead() signal is emitted every time new content data is available to read.
If the IO device to is not 0, the content data of the response is written directly to the device. Make sure that the 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.
Definition at line 1626 of file q3http.cpp.
References addRequest(), Q3NetworkProtocol::data(), header(), path, and Q3HttpPGHRequest.
01627 { 01628 Q3HttpRequestHeader header( "POST", path ); 01629 header.setValue( "Connection", "Keep-Alive" ); 01630 return addRequest( new Q3HttpPGHRequest( header, data, to ) ); 01631 }
Here is the call graph for this function:

| int Q3Http::post | ( | const QString & | path, | |
| const QByteArray & | data, | |||
| QIODevice * | to = 0 | |||
| ) |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. data is used as the content data of the HTTP request.
Definition at line 1638 of file q3http.cpp.
References addRequest(), Q3NetworkProtocol::data(), header(), path, and Q3HttpPGHRequest.
01639 { 01640 Q3HttpRequestHeader header( "POST", path ); 01641 header.setValue( "Connection", "Keep-Alive" ); 01642 return addRequest( new Q3HttpPGHRequest( header, new QByteArray(data), to ) ); 01643 }
Here is the call graph for this function:

| int Q3Http::head | ( | const QString & | path | ) |
Sends a header request for path to the server set by setHost() or as specified in the constructor.
path must be an absolute path like /index.html or an absolute URI like 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.
Definition at line 1663 of file q3http.cpp.
References addRequest(), header(), path, and Q3HttpPGHRequest.
01664 { 01665 Q3HttpRequestHeader header( "HEAD", path ); 01666 header.setValue( "Connection", "Keep-Alive" ); 01667 return addRequest( new Q3HttpPGHRequest( header, (QIODevice*)0, 0 ) ); 01668 }
Here is the call graph for this function:

| int Q3Http::request | ( | const Q3HttpRequestHeader & | header, | |
| QIODevice * | data = 0, |
|||
| QIODevice * | to = 0 | |||
| ) |
Sends a request to the server set by setHost() or as specified in the constructor. Uses the 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 data IO device.
If the IO device to is 0 the readyRead() signal is emitted every time new content data is available to read.
If the IO device to is not 0, the content data of the response is written directly to the device. Make sure that the 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.
Definition at line 1697 of file q3http.cpp.
References addRequest(), Q3NetworkProtocol::data(), header(), and Q3HttpNormalRequest.
Referenced by operationGet(), and operationPut().
01698 { 01699 return addRequest( new Q3HttpNormalRequest( header, data, to ) ); 01700 }
Here is the call graph for this function:

| int Q3Http::request | ( | const Q3HttpRequestHeader & | header, | |
| const QByteArray & | data, | |||
| QIODevice * | to = 0 | |||
| ) |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. data is used as the content data of the HTTP request.
Definition at line 1707 of file q3http.cpp.
References addRequest(), Q3NetworkProtocol::data(), header(), and Q3HttpNormalRequest.
01708 { 01709 return addRequest( new Q3HttpNormalRequest( header, new QByteArray(data), to ) ); 01710 }
Here is the call graph for this function:

| int Q3Http::closeConnection | ( | ) |
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.
Definition at line 1736 of file q3http.cpp.
References addRequest(), and Q3HttpCloseRequest.
01737 { 01738 return addRequest( new Q3HttpCloseRequest() ); 01739 }
Here is the call graph for this function:

| Q_ULONG Q3Http::bytesAvailable | ( | ) | const |
Returns the number of bytes that can be read from the response content at the moment.
Definition at line 1401 of file q3http.cpp.
References d, qDebug(), Q3HttpPrivate::rba, and Q3Membuf::size().
Referenced by clientReply(), readAll(), slotClosed(), slotReadyRead(), and startNextRequest().
01402 { 01403 #if defined(Q3HTTP_DEBUG) 01404 qDebug( "Q3Http::bytesAvailable(): %d bytes", (int)d->rba.size() ); 01405 #endif 01406 return d->rba.size(); 01407 }
Here is the call graph for this function:

| Q_LONG Q3Http::readBlock | ( | char * | data, | |
| Q_ULONG | maxlen | |||
| ) |
Reads maxlen bytes from the response content into data and returns the number of bytes read. Returns -1 if an error occurred.
Definition at line 1415 of file q3http.cpp.
References Q3HttpPrivate::bytesDone, Q3Membuf::consumeBytes(), d, qDebug(), qWarning(), Q3HttpPrivate::rba, and Q3Membuf::size().
Referenced by readAll().
01416 { 01417 if ( data == 0 && maxlen != 0 ) { 01418 #if defined(QT_CHECK_NULL) 01419 qWarning( "Q3Http::readBlock: Null pointer error" ); 01420 #endif 01421 return -1; 01422 } 01423 if ( maxlen >= (Q_ULONG)d->rba.size() ) 01424 maxlen = d->rba.size(); 01425 d->rba.consumeBytes( maxlen, data ); 01426 01427 d->bytesDone += maxlen; 01428 #if defined(Q3HTTP_DEBUG) 01429 qDebug( "Q3Http::readBlock(): read %d bytes (%d bytes done)", (int)maxlen, d->bytesDone ); 01430 #endif 01431 return maxlen; 01432 }
Here is the call graph for this function:

| QByteArray Q3Http::readAll | ( | ) |
Reads all the bytes from the response content and returns them.
Definition at line 1439 of file q3http.cpp.
References bytesAvailable(), QByteArray::data(), readBlock(), and QByteArray::resize().
Referenced by clientReply(), and startNextRequest().
01440 { 01441 Q_ULONG avail = bytesAvailable(); 01442 QByteArray tmp( avail ); 01443 Q_LONG read = readBlock( tmp.data(), avail ); 01444 tmp.resize( read ); 01445 return tmp; 01446 }
Here is the call graph for this function:

| int Q3Http::currentId | ( | ) | const |
Returns the identifier of the HTTP request being executed or 0 if there is no request being executed (i.e. they've all finished).
Definition at line 1454 of file q3http.cpp.
References d, Q3PtrList< type >::getFirst(), Q3HttpRequest::id, and Q3HttpPrivate::pending.
01455 { 01456 Q3HttpRequest *r = d->pending.getFirst(); 01457 if ( r == 0 ) 01458 return 0; 01459 return r->id; 01460 }
Here is the call graph for this function:

| QIODevice * Q3Http::currentSourceDevice | ( | ) | const |
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.
Definition at line 1488 of file q3http.cpp.
References d, Q3PtrList< type >::getFirst(), Q3HttpPrivate::pending, and Q3HttpRequest::sourceDevice().
01489 { 01490 Q3HttpRequest *r = d->pending.getFirst(); 01491 if ( !r ) 01492 return 0; 01493 return r->sourceDevice(); 01494 }
Here is the call graph for this function:

| QIODevice * Q3Http::currentDestinationDevice | ( | ) | const |
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.
Definition at line 1506 of file q3http.cpp.
References d, Q3HttpRequest::destinationDevice(), Q3PtrList< type >::getFirst(), and Q3HttpPrivate::pending.
01507 { 01508 Q3HttpRequest *r = d->pending.getFirst(); 01509 if ( !r ) 01510 return 0; 01511 return r->destinationDevice(); 01512 }
Here is the call graph for this function:

| Q3HttpRequestHeader Q3Http::currentRequest | ( | ) | const |
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.
Definition at line 1470 of file q3http.cpp.
References d, Q3PtrList< type >::getFirst(), Q3HttpRequest::hasRequestHeader(), Q3HttpPrivate::pending, and Q3HttpRequest::requestHeader().
Referenced by slotReadyRead().
01471 { 01472 Q3HttpRequest *r = d->pending.getFirst(); 01473 if ( r != 0 && r->hasRequestHeader() ) 01474 return r->requestHeader(); 01475 return Q3HttpRequestHeader(); 01476 }
Here is the call graph for this function:

| bool Q3Http::hasPendingRequests | ( | ) | const |
Returns true if there are any requests scheduled that have not yet been executed; otherwise returns false.
The request that is being executed is not considered as a scheduled request.
Definition at line 1523 of file q3http.cpp.
References Q3PtrList< type >::count(), d, and Q3HttpPrivate::pending.
Here is the call graph for this function:

| void Q3Http::clearPendingRequests | ( | ) |
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().
Definition at line 1535 of file q3http.cpp.
References Q3PtrList< type >::append(), Q3PtrList< type >::clear(), Q3PtrList< type >::count(), d, Q3HttpPrivate::pending, and Q3PtrList< type >::take().
Referenced by abort().
01536 { 01537 Q3HttpRequest *r = 0; 01538 if ( d->pending.count() > 0 ) 01539 r = d->pending.take( 0 ); 01540 d->pending.clear(); 01541 if ( r ) 01542 d->pending.append( r ); 01543 }
Here is the call graph for this function:

| Q3Http::State Q3Http::state | ( | ) | const |
Returns the current state of the object. When the state changes, the stateChanged() signal is emitted.
Definition at line 2099 of file q3http.cpp.
References d, and Q3HttpPrivate::state.
| Q3Http::Error Q3Http::error | ( | ) | const |
Returns the last error that occurred. This is useful to find out what happened when receiving a requestFinished() or a done() signal with the error argument true.
If you start a new request, the error status is reset to NoError.
Definition at line 2111 of file q3http.cpp.
References d, and Q3HttpPrivate::error.
Referenced by clientDone(), and init().
| QString Q3Http::errorString | ( | ) | const |
Returns a human-readable description of the last error that occurred. This is useful to present a error message to the user when receiving a requestFinished() or a done() signal with the error argument true.
Definition at line 2122 of file q3http.cpp.
References d, and Q3HttpPrivate::errorString.
Referenced by clientDone().
02123 { 02124 return d->errorString; 02125 }
| void Q3Http::abort | ( | ) | [slot] |
Aborts the current request and deletes all scheduled requests.
For the current request, the requestFinished() signal with the error argument true is emitted. For all other requests that are affected by the abort(), no signals are emitted.
Since this slot also deletes the scheduled requests, there are no requests left and the done() signal is emitted (with the error argument true).
Definition at line 1383 of file q3http.cpp.
References Aborted, Q3Socket::clearPendingData(), clearPendingRequests(), close(), d, finishedWithError(), Q3PtrList< type >::getFirst(), Q3HttpPrivate::pending, and Q3HttpPrivate::socket.
Referenced by ~Q3Http().
01384 { 01385 Q3HttpRequest *r = d->pending.getFirst(); 01386 if ( r == 0 ) 01387 return; 01388 01389 finishedWithError( QHttp::tr("Request aborted"), Aborted ); 01390 clearPendingRequests(); 01391 d->socket.clearPendingData(); 01392 close(); 01393 }
| void Q3Http::stateChanged | ( | int | state | ) | [signal] |
This signal is emitted when the state of the Q3Http object changes. The argument state is the new state of the connection; it is one of the State values.
This usually happens when a request is started, but it can also happen when the server closes the connection or when a call to closeConnection() succeeded.
Referenced by clientDone(), operationGet(), operationPut(), and setState().
| void Q3Http::responseHeaderReceived | ( | const Q3HttpResponseHeader & | resp | ) | [signal] |
This signal is emitted when the HTTP header of a server response is available. The header is passed in resp.
Referenced by slotReadyRead().
| void Q3Http::readyRead | ( | const Q3HttpResponseHeader & | resp | ) | [signal] |
This signal is emitted when there is new response data to read.
If you specified a device in the request where the data should be written to, then this signal is not emitted; instead the data is written directly to the device.
The response header is passed in resp.
You can read the data with the readAll() or readBlock() functions
This signal is useful if you want to process the data in chunks as soon as it becomes available. If you are only interested in the complete data, just connect to the requestFinished() signal and read the data then instead.
Referenced by clientDone(), init(), operationGet(), operationPut(), and slotReadyRead().
| void Q3Http::dataSendProgress | ( | int | done, | |
| int | total | |||
| ) | [signal] |
This signal is emitted when this object sends data to a HTTP server to inform it about the progress of the upload.
done is the amount of data that has already arrived and total is the total amount of data. It is possible that the total amount of data that should be transferred cannot be determined, in which case total is 0.(If you connect to a QProgressBar, the progress bar shows a busy indicator if the total is 0).
Referenced by slotBytesWritten().
| void Q3Http::dataReadProgress | ( | int | done, | |
| int | total | |||
| ) | [signal] |
This signal is emitted when this object reads data from a HTTP server to indicate the current progress of the download.
done is the amount of data that has already arrived and total is the total amount of data. It is possible that the total amount of data that should be transferred cannot be determined, in which case total is 0.(If you connect to a QProgressBar, the progress bar shows a busy indicator if the total is 0).
Referenced by slotReadyRead().
| void Q3Http::requestStarted | ( | int | id | ) | [signal] |
This signal is emitted when processing the request identified by id starts.
Referenced by startNextRequest().
| void Q3Http::requestFinished | ( | int | id, | |
| bool | error | |||
| ) | [signal] |
This signal is emitted when processing the request identified by id has finished. error is true if an error occurred during the processing; otherwise error is false.
Referenced by finishedWithError(), and finishedWithSuccess().
| void Q3Http::done | ( | bool | error | ) | [signal] |
This signal is emitted when the last pending request has finished; (it is emitted after the last request's requestFinished() signal). error is true if an error occurred during the processing; otherwise error is false.
Referenced by clientDone(), finishedWithError(), finishedWithSuccess(), operationGet(), and operationPut().
| void Q3Http::operationGet | ( | Q3NetworkOperation * | op | ) | [protected, virtual] |
Reimplemented from Q3NetworkProtocol.
Definition at line 2200 of file q3http.cpp.
References bytesRead, clientDone(), clientReply(), clientStateChanged(), QObject::connect(), done(), header(), Q3NetworkProtocol::operationInProgress(), readyRead(), request(), setHost(), Q3NetworkOperation::setState(), SIGNAL, SLOT, stateChanged(), Q3NetworkProtocol::StInProgress, and u.
02201 { 02202 connect( this, SIGNAL(readyRead(Q3HttpResponseHeader)), 02203 this, SLOT(clientReply(Q3HttpResponseHeader)) ); 02204 connect( this, SIGNAL(done(bool)), 02205 this, SLOT(clientDone(bool)) ); 02206 connect( this, SIGNAL(stateChanged(int)), 02207 this, SLOT(clientStateChanged(int)) ); 02208 02209 bytesRead = 0; 02210 op->setState( StInProgress ); 02211 Q3Url u( operationInProgress()->arg( 0 ) ); 02212 Q3HttpRequestHeader header( "GET", u.encodedPathAndQuery(), 1, 0 ); 02213 header.setValue( "Host", u.host() ); 02214 setHost( u.host(), u.port() != -1 ? u.port() : 80 ); 02215 request( header ); 02216 }
Here is the call graph for this function:

| void Q3Http::operationPut | ( | Q3NetworkOperation * | op | ) | [protected, virtual] |
Reimplemented from Q3NetworkProtocol.
Definition at line 2220 of file q3http.cpp.
References bytesRead, clientDone(), clientReply(), clientStateChanged(), QObject::connect(), done(), header(), Q3NetworkProtocol::operationInProgress(), Q3NetworkOperation::rawArg(), readyRead(), request(), setHost(), Q3NetworkOperation::setState(), SIGNAL, SLOT, stateChanged(), Q3NetworkProtocol::StInProgress, and u.
02221 { 02222 connect( this, SIGNAL(readyRead(Q3HttpResponseHeader)), 02223 this, SLOT(clientReply(Q3HttpResponseHeader)) ); 02224 connect( this, SIGNAL(done(bool)), 02225 this, SLOT(clientDone(bool)) ); 02226 connect( this, SIGNAL(stateChanged(int)), 02227 this, SLOT(clientStateChanged(int)) ); 02228 02229 bytesRead = 0; 02230 op->setState( StInProgress ); 02231 Q3Url u( operationInProgress()->arg( 0 ) ); 02232 Q3HttpRequestHeader header( "POST", u.encodedPathAndQuery(), 1, 0 ); 02233 header.setValue( "Host", u.host() ); 02234 setHost( u.host(), u.port() != -1 ? u.port() : 80 ); 02235 request( header, op->rawArg(1) ); 02236 }
Here is the call graph for this function:

| void Q3Http::timerEvent | ( | QTimerEvent * | e | ) | [protected, virtual] |
Reimplemented from QObject.
Definition at line 2129 of file q3http.cpp.
References Connected, d, finishedWithSuccess(), Q3HttpPrivate::idleTimer, QObject::killTimer(), setState(), Q3HttpPrivate::state, QObject::timerEvent(), QTimerEvent::timerId(), and Unconnected.
02130 { 02131 if ( e->timerId() == d->idleTimer ) { 02132 killTimer( d->idleTimer ); 02133 d->idleTimer = 0; 02134 02135 if ( d->state == Connected ) { 02136 finishedWithSuccess(); 02137 } else if ( d->state != Unconnected ) { 02138 setState( Unconnected ); 02139 finishedWithSuccess(); 02140 } 02141 } else { 02142 QObject::timerEvent( e ); 02143 } 02144 }
Here is the call graph for this function:

| void Q3Http::clientReply | ( | const Q3HttpResponseHeader & | rep | ) | [private, slot] |
Definition at line 2238 of file q3http.cpp.
References bytesAvailable(), bytesRead, Q3HttpHeader::contentLength(), Q3NetworkProtocol::data(), Q3NetworkProtocol::dataTransferProgress(), emit, Q3NetworkProtocol::ErrFileNotExisting, Q3NetworkProtocol::ErrGet, Q3NetworkProtocol::ErrPermissionDenied, Q3NetworkProtocol::ErrPut, Q3HttpHeader::hasContentLength(), Q3NetworkOperation::operation(), Q3NetworkProtocol::operationInProgress(), Q3NetworkProtocol::OpGet, readAll(), Q3HttpResponseHeader::reasonPhrase(), Q3NetworkOperation::setErrorCode(), Q3NetworkOperation::setProtocolDetail(), Q3NetworkOperation::setState(), Q3HttpResponseHeader::statusCode(), and Q3NetworkProtocol::StFailed.
Referenced by clientDone(), operationGet(), and operationPut().
02239 { 02240 Q3NetworkOperation *op = operationInProgress(); 02241 if ( op ) { 02242 if ( rep.statusCode() >= 400 && rep.statusCode() < 600 ) { 02243 op->setState( StFailed ); 02244 op->setProtocolDetail( 02245 QString("%1 %2").arg(rep.statusCode()).arg(rep.reasonPhrase()) 02246 ); 02247 switch ( rep.statusCode() ) { 02248 case 401: 02249 case 403: 02250 case 405: 02251 op->setErrorCode( ErrPermissionDenied ); 02252 break; 02253 case 404: 02254 op->setErrorCode(ErrFileNotExisting ); 02255 break; 02256 default: 02257 if ( op->operation() == OpGet ) 02258 op->setErrorCode( ErrGet ); 02259 else 02260 op->setErrorCode( ErrPut ); 02261 break; 02262 } 02263 } 02264 // ### In cases of an error, should we still emit the data() signals? 02265 if ( op->operation() == OpGet && bytesAvailable() > 0 ) { 02266 QByteArray ba = readAll(); 02267 emit data( ba, op ); 02268 bytesRead += ba.size(); 02269 if ( rep.hasContentLength() ) { 02270 emit dataTransferProgress( bytesRead, rep.contentLength(), op ); 02271 } 02272 } 02273 } 02274 }
| void Q3Http::clientDone | ( | bool | ) | [private, slot] |
Definition at line 2276 of file q3http.cpp.
References clientReply(), clientStateChanged(), ConnectionRefused, QObject::disconnect(), done(), emit, Q3NetworkProtocol::ErrGet, Q3NetworkProtocol::ErrHostNotFound, error(), errorString(), Q3NetworkProtocol::ErrPut, Q3NetworkProtocol::finished(), HostNotFound, Q3NetworkProtocol::NoError, Q3NetworkOperation::operation(), Q3NetworkProtocol::operationInProgress(), Q3NetworkProtocol::OpGet, readyRead(), Q3NetworkOperation::setErrorCode(), Q3NetworkOperation::setProtocolDetail(), Q3NetworkOperation::setState(), SIGNAL, SLOT, Q3NetworkOperation::state(), stateChanged(), Q3NetworkProtocol::StDone, and Q3NetworkProtocol::StFailed.
Referenced by operationGet(), and operationPut().
02277 { 02278 disconnect( this, SIGNAL(readyRead(Q3HttpResponseHeader)), 02279 this, SLOT(clientReply(Q3HttpResponseHeader)) ); 02280 disconnect( this, SIGNAL(done(bool)), 02281 this, SLOT(clientDone(bool)) ); 02282 disconnect( this, SIGNAL(stateChanged(int)), 02283 this, SLOT(clientStateChanged(int)) ); 02284 02285 if ( err ) { 02286 Q3NetworkOperation *op = operationInProgress(); 02287 if ( op ) { 02288 op->setState( Q3NetworkProtocol::StFailed ); 02289 op->setProtocolDetail( errorString() ); 02290 switch ( error() ) { 02291 case ConnectionRefused: 02292 op->setErrorCode( ErrHostNotFound ); 02293 break; 02294 case HostNotFound: 02295 op->setErrorCode( ErrHostNotFound ); 02296 break; 02297 default: 02298 if ( op->operation() == OpGet ) 02299 op->setErrorCode( ErrGet ); 02300 else 02301 op->setErrorCode( ErrPut ); 02302 break; 02303 } 02304 emit finished( op ); 02305 } 02306 } else { 02307 Q3NetworkOperation *op = operationInProgress(); 02308 if ( op ) { 02309 if ( op->state() != StFailed ) { 02310 op->setState( Q3NetworkProtocol::StDone ); 02311 op->setErrorCode( Q3NetworkProtocol::NoError ); 02312 } 02313 emit finished( op ); 02314 } 02315 } 02316 02317 }
| void Q3Http::clientStateChanged | ( | int | ) | [private, slot] |
Definition at line 2319 of file q3http.cpp.
References Q3NetworkProtocol::ConClosed, Q3NetworkProtocol::ConConnected, Q3NetworkProtocol::ConHostFound, Connecting, Q3NetworkProtocol::connectionStateChanged(), emit, Sending, Unconnected, and Q3NetworkProtocol::url().
Referenced by clientDone(), operationGet(), and operationPut().
02320 { 02321 if ( url() ) { 02322 switch ( (State)state ) { 02323 case Connecting: 02324 emit connectionStateChanged( ConHostFound, QHttp::tr( "Host %1 found" ).arg( url()->host() ) ); 02325 break; 02326 case Sending: 02327 emit connectionStateChanged( ConConnected, QHttp::tr( "Connected to host %1" ).arg( url()->host() ) ); 02328 break; 02329 case Unconnected: 02330 emit connectionStateChanged( ConClosed, QHttp::tr( "Connection to %1 closed" ).arg( url()->host() ) ); 02331 break; 02332 default: 02333 break; 02334 } 02335 } else { 02336 switch ( (State)state ) { 02337 case Connecting: 02338 emit connectionStateChanged( ConHostFound, QHttp::tr( "Host found" ) ); 02339 break; 02340 case Sending: 02341 emit connectionStateChanged( ConConnected, QHttp::tr( "Connected to host" ) ); 02342 break; 02343 case Unconnected: 02344 emit connectionStateChanged( ConClosed, QHttp::tr( "Connection closed" ) ); 02345 break; 02346 default: 02347 break; 02348 } 02349 } 02350 }
| void Q3Http::startNextRequest | ( | ) | [private, slot] |
Definition at line 1752 of file q3http.cpp.
References bytesAvailable(), d, emit, Q3HttpPrivate::error, Q3HttpPrivate::errorString, Q3PtrList< type >::getFirst(), Q3HttpRequest::id, NoError, Q3HttpPrivate::pending, readAll(), requestStarted(), and Q3HttpRequest::start().
Referenced by addRequest(), and finishedWithSuccess().
01753 { 01754 Q3HttpRequest *r = d->pending.getFirst(); 01755 if ( r == 0 ) 01756 return; 01757 01758 d->error = NoError; 01759 d->errorString = QHttp::tr( "Unknown error" ); 01760 01761 if ( bytesAvailable() ) 01762 readAll(); // clear the data 01763 emit requestStarted( r->id ); 01764 r->start( this ); 01765 }
| void Q3Http::slotReadyRead | ( | ) | [private, slot] |
Definition at line 1908 of file q3http.cpp.
References Q3Membuf::append(), Q3HttpPrivate::buffer, bytesAvailable(), Q3Socket::bytesAvailable(), Q3HttpPrivate::bytesDone, Q3Socket::canReadLine(), Q3HttpPrivate::chunkedSize, close(), Connected, QString::contains(), Q3HttpHeader::contentLength(), currentRequest(), d, QByteArray::data(), dataReadProgress(), emit, finishedWithError(), Q3HttpHeader::hasContentLength(), Q3HttpHeader::hasKey(), Q3HttpPrivate::headerStr, Q3HttpPrivate::idleTimer, InvalidResponseHeader, Q3HttpHeader::isValid(), method, n, qDebug(), Q3HttpPrivate::rba, QIODevice::readAll(), Q3HttpPrivate::readHeader, Reading, QIODevice::readLine(), readyRead(), QByteArray::resize(), Q3HttpPrivate::response, responseHeaderReceived(), setState(), QByteArray::size(), Q3HttpPrivate::socket, QObject::startTimer(), Q3HttpPrivate::state, Q3HttpResponseHeader::statusCode(), Q3HttpPrivate::toDevice, QString::toInt(), Q3HttpResponseHeader::toString(), QString::truncate(), Q3HttpHeader::value(), and WrongContentLength.
Referenced by init().
01909 { 01910 if ( d->state != Reading ) { 01911 setState( Reading ); 01912 d->buffer = QByteArray(); 01913 d->readHeader = true; 01914 d->headerStr = ""; 01915 d->bytesDone = 0; 01916 d->chunkedSize = -1; 01917 } 01918 01919 while ( d->readHeader ) { 01920 bool end = false; 01921 QString tmp; 01922 while ( !end && d->socket.canReadLine() ) { 01923 tmp = d->socket.readLine(); 01924 if ( tmp == "\r\n" || tmp == "\n" ) 01925 end = true; 01926 else 01927 d->headerStr += tmp; 01928 } 01929 01930 if ( !end ) 01931 return; 01932 01933 #if defined(Q3HTTP_DEBUG) 01934 qDebug( "Q3Http: read response header:\n---{\n%s}---", d->headerStr.latin1() ); 01935 #endif 01936 d->response = Q3HttpResponseHeader( d->headerStr ); 01937 d->headerStr = ""; 01938 #if defined(Q3HTTP_DEBUG) 01939 qDebug( "Q3Http: read response header:\n---{\n%s}---", d->response.toString().latin1() ); 01940 #endif 01941 // Check header 01942 if ( !d->response.isValid() ) { 01943 finishedWithError( QHttp::tr("Invalid HTTP response header"), InvalidResponseHeader ); 01944 close(); 01945 return; 01946 } 01947 01948 // The 100-continue header is ignored, because when using the 01949 // POST method, we send both the request header and data in 01950 // one chunk. 01951 if (d->response.statusCode() != 100) { 01952 d->readHeader = false; 01953 if ( d->response.hasKey( "transfer-encoding" ) && 01954 d->response.value( "transfer-encoding" ).lower().contains( "chunked" ) ) 01955 d->chunkedSize = 0; 01956 01957 emit responseHeaderReceived( d->response ); 01958 } 01959 } 01960 01961 if ( !d->readHeader ) { 01962 bool everythingRead = false; 01963 01964 if ( currentRequest().method() == "HEAD" ) { 01965 everythingRead = true; 01966 } else { 01967 Q_ULONG n = d->socket.bytesAvailable(); 01968 QByteArray *arr = 0; 01969 if ( d->chunkedSize != -1 ) { 01970 // transfer-encoding is chunked 01971 for ( ;; ) { 01972 // get chunk size 01973 if ( d->chunkedSize == 0 ) { 01974 if ( !d->socket.canReadLine() ) 01975 break; 01976 QString sizeString = d->socket.readLine(); 01977 int tPos = sizeString.find( ';' ); 01978 if ( tPos != -1 ) 01979 sizeString.truncate( tPos ); 01980 bool ok; 01981 d->chunkedSize = sizeString.toInt( &ok, 16 ); 01982 if ( !ok ) { 01983 finishedWithError( QHttp::tr("Invalid HTTP chunked body"), WrongContentLength ); 01984 close(); 01985 delete arr; 01986 return; 01987 } 01988 if ( d->chunkedSize == 0 ) // last-chunk 01989 d->chunkedSize = -2; 01990 } 01991 01992 // read trailer 01993 while ( d->chunkedSize == -2 && d->socket.canReadLine() ) { 01994 QString read = d->socket.readLine(); 01995 if ( read == "\r\n" || read == "\n" ) 01996 d->chunkedSize = -1; 01997 } 01998 if ( d->chunkedSize == -1 ) { 01999 everythingRead = true; 02000 break; 02001 } 02002 02003 // make sure that you can read the terminating CRLF, 02004 // otherwise wait until next time... 02005 n = d->socket.bytesAvailable(); 02006 if ( n == 0 ) 02007 break; 02008 if ( (Q_LONG)n == d->chunkedSize || (Q_LONG)n == d->chunkedSize+1 ) { 02009 n = d->chunkedSize - 1; 02010 if ( n == 0 ) 02011 break; 02012 } 02013 02014 // read data 02015 uint toRead = QMIN( (Q_LONG)n, (d->chunkedSize < 0 ? (Q_LONG)n : d->chunkedSize) ); 02016 if ( !arr ) 02017 arr = new QByteArray( 0 ); 02018 uint oldArrSize = arr->size(); 02019 arr->resize( oldArrSize + toRead ); 02020 Q_LONG read = d->socket.readBlock( arr->data()+oldArrSize, toRead ); 02021 arr->resize( oldArrSize + read ); 02022 02023 d->chunkedSize -= read; 02024 02025 if ( d->chunkedSize == 0 && n - read >= 2 ) { 02026 // read terminating CRLF 02027 char tmp[2]; 02028 d->socket.readBlock( tmp, 2 ); 02029 if ( tmp[0] != '\r' || tmp[1] != '\n' ) { 02030 finishedWithError( QHttp::tr("Invalid HTTP chunked body"), WrongContentLength ); 02031 close(); 02032 delete arr; 02033 return; 02034 } 02035 } 02036 } 02037 } else if ( d->response.hasContentLength() ) { 02038 n = qMin<ulong>( d->response.contentLength() - d->bytesDone, n ); 02039 if ( n > 0 ) { 02040 arr = new QByteArray( n ); 02041 Q_LONG read = d->socket.readBlock( arr->data(), n ); 02042 arr->resize( read ); 02043 } 02044 if ( d->bytesDone + bytesAvailable() + n == d->response.contentLength() ) 02045 everythingRead = true; 02046 } else if ( n > 0 ) { 02047 // workaround for VC++ bug 02048 QByteArray temp = d->socket.readAll(); 02049 arr = new QByteArray( temp ); 02050 } 02051 02052 if ( arr ) { 02053 n = arr->size(); 02054 if ( d->toDevice ) { 02055 d->toDevice->writeBlock( arr->data(), n ); 02056 delete arr; 02057 d->bytesDone += n; 02058 #if defined(Q3HTTP_DEBUG) 02059 qDebug( "Q3Http::slotReadyRead(): read %ld bytes (%d bytes done)", n, d->bytesDone ); 02060 #endif 02061 if ( d->response.hasContentLength() ) 02062 emit dataReadProgress( d->bytesDone, d->response.contentLength() ); 02063 else 02064 emit dataReadProgress( d->bytesDone, 0 ); 02065 } else { 02066 d->rba.append( arr ); 02067 #if defined(Q3HTTP_DEBUG) 02068 qDebug( "Q3Http::slotReadyRead(): read %ld bytes (%ld bytes done)", n, d->bytesDone + bytesAvailable() ); 02069 #endif 02070 if ( d->response.hasContentLength() ) 02071 emit dataReadProgress( d->bytesDone + bytesAvailable(), d->response.contentLength() ); 02072 else 02073 emit dataReadProgress( d->bytesDone + bytesAvailable(), 0 ); 02074 emit readyRead( d->response ); 02075 } 02076 } 02077 } 02078 02079 if ( everythingRead ) { 02080 // Handle "Connection: close" 02081 if ( d->response.value("connection").lower() == "close" ) { 02082 close(); 02083 } else { 02084 setState( Connected ); 02085 // Start a timer, so that we emit the keep alive signal 02086 // "after" this method returned. 02087 d->idleTimer = startTimer( 0 ); 02088 } 02089 } 02090 } 02091 }
| void Q3Http::slotConnected | ( | ) | [private, slot] |
Definition at line 1838 of file q3http.cpp.
References Q3HttpPrivate::buffer, Q3HttpPrivate::bytesDone, Q3HttpPrivate::bytesTotal, d, QByteArray::data(), Q3HttpPrivate::header, QString::length(), Q3HttpPrivate::postDevice, qDebug(), Sending, setState(), QByteArray::size(), QIODevice::size(), Q3HttpPrivate::socket, Q3HttpPrivate::state, and Q3HttpRequestHeader::toString().
Referenced by init(), and sendRequest().
01839 { 01840 if ( d->state != Sending ) { 01841 d->bytesDone = 0; 01842 setState( Sending ); 01843 } 01844 01845 QString str = d->header.toString(); 01846 d->bytesTotal = str.length(); 01847 d->socket.writeBlock( str.latin1(), d->bytesTotal ); 01848 #if defined(Q3HTTP_DEBUG) 01849 qDebug( "Q3Http: write request header:\n---{\n%s}---", str.latin1() ); 01850 #endif 01851 01852 if ( d->postDevice ) { 01853 d->bytesTotal += d->postDevice->size(); 01854 } else { 01855 d->bytesTotal += d->buffer.size(); 01856 d->socket.writeBlock( d->buffer.data(), d->buffer.size() ); 01857 d->buffer = QByteArray(); // save memory 01858 } 01859 }
| void Q3Http::slotError | ( | int | ) | [private, slot] |
Definition at line 1861 of file q3http.cpp.
References close(), Connecting, ConnectionRefused, d, Q3Socket::ErrConnectionRefused, Q3Socket::ErrHostNotFound, finishedWithError(), HostNotFound, Q3Socket::peerName(), Q3HttpPrivate::postDevice, Reading, Sending, Q3HttpPrivate::socket, Q3HttpPrivate::state, and UnknownError.
Referenced by init().
01862 { 01863 d->postDevice = 0; 01864 01865 if ( d->state == Connecting || d->state == Reading || d->state == Sending ) { 01866 switch ( err ) { 01867 case Q3Socket::ErrConnectionRefused: 01868 finishedWithError( QHttp::tr("Connection refused"), ConnectionRefused ); 01869 break; 01870 case Q3Socket::ErrHostNotFound: 01871 finishedWithError( QHttp::tr("Host %1 not found").arg(d->socket.peerName()), HostNotFound ); 01872 break; 01873 default: 01874 finishedWithError( QHttp::tr("HTTP request failed"), UnknownError ); 01875 break; 01876 } 01877 } 01878 01879 close(); 01880 }
| void Q3Http::slotClosed | ( | ) | [private, slot] |
Definition at line 1817 of file q3http.cpp.
References bytesAvailable(), Q3HttpPrivate::bytesDone, Closing, Connecting, Q3HttpHeader::contentLength(), d, finishedWithError(), Q3HttpHeader::hasKey(), Q3HttpPrivate::idleTimer, Q3HttpPrivate::postDevice, Reading, Q3HttpPrivate::response, Sending, setState(), QObject::startTimer(), Q3HttpPrivate::state, UnexpectedClose, and WrongContentLength.
Referenced by init().
01818 { 01819 if ( d->state == Closing ) 01820 return; 01821 01822 if ( d->state == Reading ) { 01823 if ( d->response.hasKey( "content-length" ) ) { 01824 // We got Content-Length, so did we get all bytes? 01825 if ( d->bytesDone+bytesAvailable() != d->response.contentLength() ) { 01826 finishedWithError( QHttp::tr("Wrong content length"), WrongContentLength ); 01827 } 01828 } 01829 } else if ( d->state == Connecting || d->state == Sending ) { 01830 finishedWithError( QHttp::tr("Server closed connection unexpectedly"), UnexpectedClose ); 01831 } 01832 01833 d->postDevice = 0; 01834 setState( Closing ); 01835 d->idleTimer = startTimer( 0 ); 01836 }
| void Q3Http::slotBytesWritten | ( | int | ) | [private, slot] |
Definition at line 1882 of file q3http.cpp.
References QIODevice::atEnd(), Q3HttpPrivate::bytesDone, Q3HttpPrivate::bytesTotal, Q3Socket::bytesToWrite(), close(), d, QByteArray::data(), dataSendProgress(), emit, n, Q3HttpPrivate::postDevice, qWarning(), QIODevice::size(), and Q3HttpPrivate::socket.
Referenced by init().
01883 { 01884 d->bytesDone += written; 01885 emit dataSendProgress( d->bytesDone, d->bytesTotal ); 01886 01887 if ( !d->postDevice ) 01888 return; 01889 01890 if ( d->socket.bytesToWrite() == 0 ) { 01891 int max = qMin<int>( 4096, d->postDevice->size() - d->postDevice->at() ); 01892 QByteArray arr( max ); 01893 01894 int n = d->postDevice->readBlock( arr.data(), max ); 01895 if ( n != max ) { 01896 qWarning("Could not read enough bytes from the device"); 01897 close(); 01898 return; 01899 } 01900 if ( d->postDevice->atEnd() ) { 01901 d->postDevice = 0; 01902 } 01903 01904 d->socket.writeBlock( arr.data(), max ); 01905 } 01906 }
| int Q3Http::addRequest | ( | Q3HttpRequest * | ) | [private] |
Definition at line 1741 of file q3http.cpp.
References Q3PtrList< type >::append(), Q3PtrList< type >::count(), d, Q3HttpRequest::id, Q3HttpPrivate::pending, QTimer::singleShot(), SLOT, and startNextRequest().
Referenced by closeConnection(), get(), head(), post(), request(), and setHost().
01742 { 01743 d->pending.append( req ); 01744 01745 if ( d->pending.count() == 1 ) 01746 // don't emit the requestStarted() signal before the id is returned 01747 QTimer::singleShot( 0, this, SLOT(startNextRequest()) ); 01748 01749 return req->id; 01750 }
Here is the call graph for this function:

| void Q3Http::sendRequest | ( | ) | [private] |
Definition at line 1767 of file q3http.cpp.
References Connecting, Q3Socket::Connection, Q3Socket::connectToHost(), d, finishedWithError(), Q3HttpPrivate::hostname, QString::isNull(), killIdleTimer(), Q3Socket::peerName(), Q3Socket::peerPort(), Q3HttpPrivate::port, setState(), slotConnected(), Q3HttpPrivate::socket, Q3Socket::state(), and UnknownError.
Referenced by Q3HttpNormalRequest::start().
01768 { 01769 if ( d->hostname.isNull() ) { 01770 finishedWithError( QHttp::tr("No server set to connect to"), UnknownError ); 01771 return; 01772 } 01773 01774 killIdleTimer(); 01775 01776 // Do we need to setup a new connection or can we reuse an 01777 // existing one ? 01778 if ( d->socket.peerName() != d->hostname || d->socket.peerPort() != d->port 01779 || d->socket.state() != Q3Socket::Connection ) { 01780 setState( Q3Http::Connecting ); 01781 d->socket.connectToHost( d->hostname, d->port ); 01782 } else { 01783 slotConnected(); 01784 } 01785 01786 }
Here is the call graph for this function:

| void Q3Http::finishedWithSuccess | ( | ) | [private] |
Definition at line 1788 of file q3http.cpp.
References d, done(), emit, Q3PtrList< type >::getFirst(), Q3HttpRequest::id, Q3PtrList< type >::isEmpty(), Q3HttpPrivate::pending, Q3PtrList< type >::removeFirst(), requestFinished(), and startNextRequest().
Referenced by Q3HttpSetHostRequest::start(), and timerEvent().
01789 { 01790 Q3HttpRequest *r = d->pending.getFirst(); 01791 if ( r == 0 ) 01792 return; 01793 01794 emit requestFinished( r->id, false ); 01795 d->pending.removeFirst(); 01796 if ( d->pending.isEmpty() ) { 01797 emit done( false ); 01798 } else { 01799 startNextRequest(); 01800 } 01801 }
Here is the call graph for this function:

| void Q3Http::finishedWithError | ( | const QString & | detail, | |
| int | errorCode | |||
| ) | [private] |
Definition at line 1803 of file q3http.cpp.
References Q3PtrList< type >::clear(), d, done(), emit, Q3HttpPrivate::error, Q3HttpPrivate::errorString, Q3PtrList< type >::getFirst(), Q3HttpRequest::id, Q3HttpPrivate::pending, and requestFinished().
Referenced by abort(), sendRequest(), slotClosed(), slotError(), and slotReadyRead().
01804 { 01805 Q3HttpRequest *r = d->pending.getFirst(); 01806 if ( r == 0 ) 01807 return; 01808 01809 d->error = (Error)errorCode; 01810 d->errorString = detail; 01811 emit requestFinished( r->id, true ); 01812 01813 d->pending.clear(); 01814 emit done( true ); 01815 }
Here is the call graph for this function:

| void Q3Http::killIdleTimer | ( | ) | [private] |
Definition at line 2146 of file q3http.cpp.
References d, Q3HttpPrivate::idleTimer, and QObject::killTimer().
Referenced by sendRequest().
Here is the call graph for this function:

| void Q3Http::init | ( | ) | [private] |
Definition at line 1188 of file q3http.cpp.
References bytesRead, QObject::connect(), d, error(), Q3HttpPrivate::errorString, Q3HttpPrivate::idleTimer, readyRead(), SIGNAL, SLOT, slotBytesWritten(), slotClosed(), slotConnected(), slotError(), slotReadyRead(), Q3HttpPrivate::socket, and QObject::startTimer().
Referenced by Q3Http().
01189 { 01190 bytesRead = 0; 01191 d = new Q3HttpPrivate; 01192 d->errorString = QHttp::tr( "Unknown error" ); 01193 01194 connect( &d->socket, SIGNAL(connected()), 01195 this, SLOT(slotConnected()) ); 01196 connect( &d->socket, SIGNAL(connectionClosed()), 01197 this, SLOT(slotClosed()) ); 01198 connect( &d->socket, SIGNAL(delayedCloseFinished()), 01199 this, SLOT(slotClosed()) ); 01200 connect( &d->socket, SIGNAL(readyRead()), 01201 this, SLOT(slotReadyRead()) ); 01202 connect( &d->socket, SIGNAL(error(int)), 01203 this, SLOT(slotError(int)) ); 01204 connect( &d->socket, SIGNAL(bytesWritten(int)), 01205 this, SLOT(slotBytesWritten(int)) ); 01206 01207 d->idleTimer = startTimer( 0 ); 01208 }
Here is the call graph for this function:

| void Q3Http::setState | ( | int | ) | [private] |
Definition at line 2153 of file q3http.cpp.
References d, emit, qDebug(), Q3HttpPrivate::state, and stateChanged().
Referenced by close(), sendRequest(), slotClosed(), slotConnected(), slotReadyRead(), and timerEvent().
02154 { 02155 #if defined(Q3HTTP_DEBUG) 02156 qDebug( "Q3Http state changed %d -> %d", d->state, s ); 02157 #endif 02158 d->state = (State)s; 02159 emit stateChanged( s ); 02160 }
Here is the call graph for this function:

| void Q3Http::close | ( | ) | [private] |
Definition at line 2162 of file q3http.cpp.
References Q3Socket::close(), Closing, d, Q3Socket::Idle, Q3HttpPrivate::idleTimer, QIODevice::isOpen(), Q3HttpPrivate::postDevice, setState(), Q3HttpPrivate::socket, QObject::startTimer(), Q3Socket::state(), Q3HttpPrivate::state, and Unconnected.
Referenced by abort(), slotBytesWritten(), slotError(), slotReadyRead(), and Q3HttpCloseRequest::start().
02163 { 02164 // If no connection is open -> ignore 02165 if ( d->state == Closing || d->state == Unconnected ) 02166 return; 02167 02168 d->postDevice = 0; 02169 setState( Closing ); 02170 02171 // Already closed ? 02172 if ( !d->socket.isOpen() ) { 02173 d->idleTimer = startTimer( 0 ); 02174 } else { 02175 // Close now. 02176 d->socket.close(); 02177 02178 // Did close succeed immediately ? 02179 if ( d->socket.state() == Q3Socket::Idle ) { 02180 // Prepare to emit the requestFinished() signal. 02181 d->idleTimer = startTimer( 0 ); 02182 } 02183 } 02184 }
Here is the call graph for this function:

friend class Q3HttpNormalRequest [friend] |
friend class Q3HttpSetHostRequest [friend] |
friend class Q3HttpCloseRequest [friend] |
friend class Q3HttpPGHRequest [friend] |
Q3HttpPrivate* Q3Http::d [private] |
Reimplemented from Q3NetworkProtocol.
Definition at line 231 of file q3http.h.
Referenced by abort(), addRequest(), bytesAvailable(), clearPendingRequests(), close(), currentDestinationDevice(), currentId(), currentRequest(), currentSourceDevice(), error(), errorString(), finishedWithError(), finishedWithSuccess(), hasPendingRequests(), init(), killIdleTimer(), Q3Http(), readBlock(), sendRequest(), setState(), slotBytesWritten(), slotClosed(), slotConnected(), slotError(), slotReadyRead(), Q3HttpNormalRequest::start(), Q3HttpSetHostRequest::start(), Q3HttpPGHRequest::start(), startNextRequest(), state(), timerEvent(), and ~Q3Http().
void* Q3Http::unused [private] |
int Q3Http::bytesRead [private] |
Definition at line 233 of file q3http.h.
Referenced by clientReply(), init(), operationGet(), and operationPut().
1.5.1