ClientSession.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Qt.h"
00024 #include "BodyReader.h"
00025 #include "BodyWriter.h"
00026 #include "ClientSession.h"
00027 #include "HeaderReader.h"
00028 #include "HeaderWriter.h"
00029 #include "RequestHeader.h"
00030 #include "ResponseHeader.h"
00031 #include "Imports.cpp"
00032
00033 using namespace Http;
00034
00035 namespace Http {
00036
00037 enum Constants
00038 {
00039 MajorVersion = 1,
00040 MinorVersion = 1
00041 };
00042
00043 class ClientSessionPrivate
00044 {
00045 public:
00046 Connection *connection;
00047 HeaderReader *headerReader;
00048 HeaderWriter *headerWriter;
00049 BodyReader *bodyReader;
00050 BodyWriter *bodyWriter;
00051
00052 QByteArray requestBody;
00053 QBuffer postBuffer;
00054
00055 ClientSessionPrivate() : connection (0), headerReader (0),
00056 headerWriter (0), bodyReader (0),
00057 bodyWriter (0), requestBody(), postBuffer()
00058 {}
00059
00060 private:
00061 REFERENCE_OBJECT (ClientSessionPrivate)
00062 };
00063
00064 }
00065
00066 ClientSession::ClientSession (Connection *connection)
00067 : p (new ClientSessionPrivate)
00068 {
00069 p->connection = connection;
00070 p->headerReader = new HeaderReader (connection);
00071 p->headerWriter = new HeaderWriter (connection);
00072 p->bodyReader = new BodyReader (connection);
00073 p->bodyWriter = new BodyWriter (connection);
00074
00075 connect (p->headerWriter, SIGNAL (headerWritten()),
00076 this, SLOT (writeRequestBody()));
00077 connect (p->bodyWriter, SIGNAL (bodyWritten()),
00078 this, SLOT (startReadingResponse()));
00079 connect (p->headerReader, SIGNAL (headerRead()),
00080 this, SIGNAL (responseHeaderRead()));
00081 connect (p->bodyReader, SIGNAL (bodyRead()),
00082 this, SIGNAL (responseBodyRead()));
00083
00084 }
00085
00086 ClientSession::~ClientSession()
00087 {
00088 p->headerReader->disconnect (this);
00089 p->headerWriter->disconnect (this);
00090 p->bodyReader->disconnect (this);
00091 p->bodyWriter->disconnect (this);
00092
00093 delete p->headerReader;
00094 delete p->headerWriter;
00095 delete p->bodyReader;
00096 delete p->bodyWriter;
00097 delete p;
00098 }
00099
00100 void ClientSession::get (const QUrl &url, const Header &header)
00101 {
00102 sendRequest ("GET", url ,header, QByteArray());
00103 }
00104
00105 void ClientSession::head (const QUrl &url, const Header &header)
00106 {
00107 sendRequest ("HEAD", url ,header, QByteArray());
00108 }
00109
00110 void ClientSession::post (const QUrl &url, const Header &header,
00111 const QByteArray &requestBody)
00112 {
00113 sendRequest ("POST", url, header, requestBody);
00114 }
00115
00116 inline void ClientSession::sendRequest (const QString &method,
00117 const QUrl &url,
00118 const Header &header,
00119 const QByteArray &requestBody)
00120 {
00121 Q_ASSERT (p->headerWriter->canWrite());
00122
00123 QString path = url.toEncoded (QUrl::RemoveScheme | QUrl::RemoveAuthority |
00124 QUrl::RemoveFragment);
00125 RequestHeader request (method, path, MajorVersion, MinorVersion);
00126 request.Header::operator= (header);
00127 request.setFieldValue ("Host", url.host());
00128
00129 qDebug() << request.toString();
00130 p->requestBody = requestBody;
00131 p->headerWriter->write (request);
00132 }
00133
00134 void ClientSession::writeRequestBody()
00135 {
00136 qDebug() << "starting writing request body...";
00137 if (p->requestBody.length() > 0) {
00138 p->postBuffer.setBuffer (&p->requestBody);
00139 p->bodyWriter->write (&p->postBuffer, p->requestBody.length());
00140 } else {
00141 startReadingResponse();
00142 }
00143 }
00144
00145 void ClientSession::startReadingResponse()
00146 {
00147 qDebug() << "starting reading response header...";
00148 p->headerReader->startReading (new ResponseHeader);
00149 }
00150
00151 const ResponseHeader * ClientSession::responseHeader() const
00152 {
00153 return dynamic_cast <const ResponseHeader *> (p->headerReader->header());
00154 }
00155
00156 void ClientSession::readResponseBody (QIODevice *file)
00157 {
00158 qint64 length = 0;
00159
00160
00161 length = responseHeader()->fieldValue ("Content-Length").toLongLong();
00162 qDebug() << "starting reading response body of size" << length;
00163 p->bodyReader->startReading (file, length);
00164 }