6 \brief InternalNetworkAccessManager non-inline non-template implementation */
8 #include "Publisher.hh"
9 //#include "Publisher.ih"
13 #include <QNetworkProxy>
15 #include "Publisher.hh"
16 #include <boost/python.hpp>
18 //#include "Publisher.mpp"
20 ///////////////////////////////cc.p////////////////////////////////////////
22 ///////////////////////////////////////////////////////////////////////////
23 // pykit::detail::InternalServerReply
28 class InternalServerReply
29 : public QNetworkReply
33 InternalServerReply(QNetworkAccessManager::Operation operation,
34 QNetworkRequest const & networkRequest,
35 QIODevice * postData, Publisher * publisher);
37 // Forwarded to buffer
38 virtual bool atEnd() const;
39 virtual qint64 bytesAvailable() const;
40 virtual qint64 bytesToWrite() const;
41 virtual bool canReadLine() const;
42 virtual bool isSequential() const;
43 virtual qint64 pos() const;
45 virtual bool seek(qint64 pos);
46 virtual qint64 size() const;
47 virtual bool waitForBytesWritten(int msecs);
48 virtual bool waitForReadyRead(int msecs);
52 using QNetworkReply::setHeader;
53 using QNetworkReply::setRawHeader;
54 using QNetworkReply::setAttribute;
57 QByteArray postData() const;
58 QString postContentType() const;
61 virtual qint64 readData(char * data, qint64 maxSize);
62 virtual qint64 writeData(char const * data, qint64 maxSize);
65 void bufferPostData();
66 void postDataReadable();
67 void postDataComplete();
68 void processRequest();
74 Publisher * publisher_;
75 QIODevice * postDevice_;
82 prefix_ pykit::detail::InternalServerReply::
83 InternalServerReply(QNetworkAccessManager::Operation operation,
84 QNetworkRequest const & networkRequest, QIODevice * postData,
85 Publisher * publisher)
86 : publisher_ (publisher), postDevice_ (postData)
88 setRequest(networkRequest);
89 setOperation(operation);
90 setUrl(networkRequest.url());
91 open(ReadWrite | Unbuffered);
92 buffer_.open(ReadWrite | Unbuffered);
95 QMetaObject::invokeMethod(this, "bufferPostData", Qt::QueuedConnection);
97 QMetaObject::invokeMethod(this, "processRequest", Qt::QueuedConnection);
100 prefix_ void pykit::detail::InternalServerReply::bufferPostData()
102 QVariant cl (request().header(QNetworkRequest::ContentLengthHeader));
103 connect(postDevice_, SIGNAL(readyRead()), this, SLOT(postDataReadable()));
104 connect(postDevice_, SIGNAL(readChannelFinished()), this, SLOT(postDataComplete()));
105 postData_.open(WriteOnly);
109 prefix_ bool pykit::detail::InternalServerReply::readPostData()
112 qint64 n (postDevice_->bytesAvailable());
117 n = postDevice_->read(data.data(), n);
122 postData_.write(data);
129 prefix_ void pykit::detail::InternalServerReply::postDataReadable()
131 if (readPostData()) {
132 disconnect(postDevice_, SIGNAL(readyRead()), this, SLOT(postDataReadable()));
133 disconnect(postDevice_, SIGNAL(readChannelFinished()), this, SLOT(postDataComplete()));
138 prefix_ void pykit::detail::InternalServerReply::postDataComplete()
141 disconnect(postDevice_, SIGNAL(readyRead()), this, SLOT(postDataReadable()));
142 disconnect(postDevice_, SIGNAL(readChannelFinished()), this, SLOT(postDataComplete()));
146 prefix_ void pykit::detail::InternalServerReply::processRequest()
148 Request request (*this);
149 publisher_->publish(request);
152 setHeader(QNetworkRequest::ContentLengthHeader, QVariant(size()));
154 QMetaObject::invokeMethod(this, "complete", Qt::QueuedConnection);
157 prefix_ void pykit::detail::InternalServerReply::complete()
163 prefix_ bool pykit::detail::InternalServerReply::atEnd()
165 { return buffer_.atEnd(); }
167 prefix_ qint64 pykit::detail::InternalServerReply::bytesAvailable()
169 { return buffer_.bytesAvailable(); }
171 prefix_ qint64 pykit::detail::InternalServerReply::bytesToWrite()
173 { return buffer_.bytesToWrite(); }
175 prefix_ bool pykit::detail::InternalServerReply::canReadLine()
177 { return buffer_.canReadLine(); }
179 prefix_ bool pykit::detail::InternalServerReply::isSequential()
181 { return buffer_.isSequential(); }
183 prefix_ qint64 pykit::detail::InternalServerReply::pos()
185 { return buffer_.pos(); }
187 prefix_ bool pykit::detail::InternalServerReply::reset()
188 { return buffer_.reset(); }
190 prefix_ bool pykit::detail::InternalServerReply::seek(qint64 pos)
191 { return buffer_.seek(pos); }
193 prefix_ qint64 pykit::detail::InternalServerReply::size()
195 { return buffer_.size(); }
197 prefix_ bool pykit::detail::InternalServerReply::waitForBytesWritten(int msecs)
198 { return buffer_.waitForBytesWritten(msecs); }
200 prefix_ bool pykit::detail::InternalServerReply::waitForReadyRead(int msecs)
201 { return buffer_.waitForReadyRead(msecs); }
203 prefix_ qint64 pykit::detail::InternalServerReply::readData(char * data, qint64 maxSize)
205 qint64 n (buffer_.read(data,maxSize));
207 emit readChannelFinished();
211 prefix_ qint64 pykit::detail::InternalServerReply::writeData(char const * data, qint64 maxSize)
212 { return buffer_.write(data,maxSize); }
214 prefix_ void pykit::detail::InternalServerReply::abort()
217 prefix_ void pykit::detail::InternalServerReply::clearResponse()
219 buffer_.buffer().clear();
222 prefix_ QByteArray pykit::detail::InternalServerReply::postData()
225 return postData_.buffer();
228 prefix_ QString pykit::detail::InternalServerReply::postContentType()
231 return request().header(QNetworkRequest::ContentTypeHeader).toString();
234 ///////////////////////////////////////////////////////////////////////////
237 prefix_ void pykit::Request::write(std::string const & data)
239 reply_.write(QByteArray(data.data(),data.size()));
242 prefix_ void pykit::Request::reset()
244 reply_.clearResponse();
247 prefix_ void pykit::Request::setContentType(std::string const & contentType)
249 reply_.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType.c_str()));
252 prefix_ void pykit::Request::setLocation(std::string const & location)
254 reply_.setHeader(QNetworkRequest::LocationHeader, QVariant(location.c_str()));
257 prefix_ void pykit::Request::setHeader(std::string const & header, std::string const & value)
259 reply_.setRawHeader(header.c_str(), value.c_str());
262 prefix_ void pykit::Request::setStatusCode(int code)
264 reply_.setAttribute(QNetworkRequest::HttpStatusCodeAttribute, code);
267 prefix_ QUrl pykit::Request::url()
273 prefix_ QByteArray pykit::Request::postData()
276 return reply_.postData();
279 prefix_ QByteArray pykit::Request::operation()
282 static char const * const operationNames[]
283 = { "", "HEAD", "GET", "PUT", "POST", "DELETE", "" };
284 return operationNames[reply_.operation()];
287 prefix_ QString pykit::Request::postContentType()
290 return reply_.postContentType();
293 prefix_ pykit::Request::Request(detail::InternalServerReply & reply)
297 ///////////////////////////////////////////////////////////////////////////
298 // pykit::InternalNetworkAccessManager
300 prefix_ pykit::InternalNetworkAccessManager::
301 InternalNetworkAccessManager(QNetworkAccessManager * manager, QObject * parent,
302 Publisher * publisher)
303 : QNetworkAccessManager(parent), publisher_ (publisher)
305 setCache(manager->cache());
306 setCookieJar(manager->cookieJar());
307 setProxy(manager->proxy());
308 setProxyFactory(manager->proxyFactory());
311 prefix_ QNetworkReply *
312 pykit::InternalNetworkAccessManager::createRequest(Operation operation,
313 QNetworkRequest const & request,
316 if (request.url().host() != "pykit")
317 return QNetworkAccessManager::createRequest(operation, request, device);
318 return new detail::InternalServerReply(operation, request, device, publisher_);
321 #include "Publisher.moc"
323 ///////////////////////////////cc.e////////////////////////////////////////
325 //#include "Publisher.mpp"
331 // comment-column: 40
332 // c-file-style: "j32"
333 // indent-tabs-mode: nil
334 // ispell-local-dictionary: "american"
335 // compile-command: "scons -U"