From d98495c18a9c1884a865b1086ee2da50188c931c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 26 Mar 2017 23:27:51 +0200 Subject: [PATCH] WIP: new features for HTTP streams. --- src/tl/tlHttpStream.cc | 39 ++++++++++++++++++++++++++++++---- src/tl/tlHttpStream.h | 38 +++++++++++++++++++++++++++------ src/unit_tests/tlHttpStream.cc | 7 +++++- src/unit_tests/unit_tests.pro | 3 ++- 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/src/tl/tlHttpStream.cc b/src/tl/tlHttpStream.cc index a709586e8..216e31c76 100644 --- a/src/tl/tlHttpStream.cc +++ b/src/tl/tlHttpStream.cc @@ -78,7 +78,7 @@ public: static QNetworkAccessManager *s_network_manager (0); InputHttpStream::InputHttpStream (const std::string &url) - : m_url (url) + : m_url (url), m_request ("GET"), mp_buffer (0) { if (! s_network_manager) { s_network_manager = new QNetworkAccessManager(0); @@ -87,7 +87,7 @@ InputHttpStream::InputHttpStream (const std::string &url) connect (s_network_manager, SIGNAL (finished (QNetworkReply *)), this, SLOT (finished (QNetworkReply *))); connect (s_network_manager, SIGNAL (authenticationRequired (QNetworkReply *, QAuthenticator *)), this, SLOT (authenticationRequired (QNetworkReply *, QAuthenticator *))); connect (s_network_manager, SIGNAL (proxyAuthenticationRequired (const QNetworkProxy &, QAuthenticator *)), this, SLOT (proxyAuthenticationRequired (const QNetworkProxy &, QAuthenticator *))); - s_network_manager->get (QNetworkRequest (QUrl (tl::to_qstring (url)))); + issue_request (QUrl (tl::to_qstring (url))); mp_reply = 0; } @@ -97,6 +97,24 @@ InputHttpStream::~InputHttpStream () mp_reply = 0; } +void +InputHttpStream::set_request (const char *r) +{ + m_request = QByteArray (r); +} + +void +InputHttpStream::set_data (const char *data) +{ + m_data = QByteArray (data); +} + +void +InputHttpStream::set_data (const char *data, size_t n) +{ + m_data = QByteArray (data, int (n)); +} + void InputHttpStream::authenticationRequired (QNetworkReply *reply, QAuthenticator *auth) { @@ -117,13 +135,27 @@ InputHttpStream::finished (QNetworkReply *reply) QVariant redirect_target = reply->attribute (QNetworkRequest::RedirectionTargetAttribute); if (reply->error () == QNetworkReply::NoError && ! redirect_target.isNull ()) { m_url = tl::to_string (redirect_target.toString ()); - s_network_manager->get (QNetworkRequest (QUrl (redirect_target.toString ()))); + issue_request (QUrl (redirect_target.toString ())); delete reply; } else { mp_reply = reply; } } +void +InputHttpStream::issue_request (const QUrl &url) +{ + delete mp_buffer; + mp_buffer = 0; + + if (m_data.isEmpty ()) { + s_network_manager->sendCustomRequest (QNetworkRequest (url), m_request); + } else { + mp_buffer = new QBuffer (&m_data); + s_network_manager->sendCustomRequest (QNetworkRequest (url), m_request, mp_buffer); + } +} + size_t InputHttpStream::read (char *b, size_t n) { @@ -160,4 +192,3 @@ InputHttpStream::filename () const } } - diff --git a/src/tl/tlHttpStream.h b/src/tl/tlHttpStream.h index 5a2da4d8a..7f20c0aad 100644 --- a/src/tl/tlHttpStream.h +++ b/src/tl/tlHttpStream.h @@ -27,6 +27,8 @@ #include "tlStream.h" #include +#include +#include class QNetworkAccessManager; class QNetworkReply; @@ -68,14 +70,33 @@ public: */ virtual ~InputHttpStream (); + /** + * @brief Sets the request verb + * The default verb is "GET" + */ + void set_request (const char *r); + + /** + * @brief Sets data to be sent with the request + * If data is given, it is sent along with the request. + * This version takes a null-terminated string. + */ + void set_data (const char *data); + + /** + * @brief Sets data to be sent with the request + * If data is given, it is sent along with the request. + * This version takes a data plus length. + */ + void set_data (const char *data, size_t n); + /** * @brief Read from the stream - * * Implements the basic read method. */ virtual size_t read (char *b, size_t n); - virtual void reset (); + virtual void reset (); virtual std::string source () const { @@ -89,14 +110,19 @@ public: virtual std::string filename () const; -private: - std::string m_url; - QNetworkReply *mp_reply; - private slots: void finished (QNetworkReply *); void authenticationRequired (QNetworkReply *, QAuthenticator *); void proxyAuthenticationRequired (const QNetworkProxy &, QAuthenticator *); + +private: + std::string m_url; + QNetworkReply *mp_reply; + QByteArray m_request; + QByteArray m_data; + QBuffer *mp_buffer; + + void issue_request (const QUrl &url); }; } diff --git a/src/unit_tests/tlHttpStream.cc b/src/unit_tests/tlHttpStream.cc index 184416f1f..1783b2ccb 100644 --- a/src/unit_tests/tlHttpStream.cc +++ b/src/unit_tests/tlHttpStream.cc @@ -28,6 +28,11 @@ std::string test_url1 ("http://www.klayout.org/svn-public/klayout-resources/trun TEST(1) { - EXPECT_EQ (to_string (12.5), "12.5"); + tl::InputHttpStream stream (test_url1); + + char b[100]; + size_t n = stream.read (b, sizeof (b)); + std::string res (b, n); + EXPECT_EQ (res, "hello, world.\n"); } diff --git a/src/unit_tests/unit_tests.pro b/src/unit_tests/unit_tests.pro index 31dd201a4..608f86786 100644 --- a/src/unit_tests/unit_tests.pro +++ b/src/unit_tests/unit_tests.pro @@ -97,7 +97,8 @@ SOURCES = \ gsiTest.cc \ tlFileSystemWatcher.cc \ laySalt.cc \ - tlFileUtils.cc + tlFileUtils.cc \ + tlHttpStream.cc # main components: SOURCES += \