imseng-capybara-webkit 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. data/.gitignore +21 -0
  2. data/.rspec +2 -0
  3. data/Appraisals +7 -0
  4. data/CONTRIBUTING.md +47 -0
  5. data/ChangeLog +70 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +19 -0
  8. data/NEWS.md +36 -0
  9. data/README.md +114 -0
  10. data/Rakefile +65 -0
  11. data/bin/Info.plist +22 -0
  12. data/capybara-webkit.gemspec +28 -0
  13. data/extconf.rb +2 -0
  14. data/gemfiles/1.0.gemfile +7 -0
  15. data/gemfiles/1.0.gemfile.lock +70 -0
  16. data/gemfiles/1.1.gemfile +7 -0
  17. data/gemfiles/1.1.gemfile.lock +70 -0
  18. data/lib/capybara/driver/webkit/browser.rb +164 -0
  19. data/lib/capybara/driver/webkit/connection.rb +120 -0
  20. data/lib/capybara/driver/webkit/cookie_jar.rb +55 -0
  21. data/lib/capybara/driver/webkit/node.rb +118 -0
  22. data/lib/capybara/driver/webkit/socket_debugger.rb +43 -0
  23. data/lib/capybara/driver/webkit/version.rb +7 -0
  24. data/lib/capybara/driver/webkit.rb +136 -0
  25. data/lib/capybara/webkit/matchers.rb +37 -0
  26. data/lib/capybara/webkit.rb +13 -0
  27. data/lib/capybara-webkit.rb +1 -0
  28. data/lib/capybara_webkit_builder.rb +68 -0
  29. data/spec/browser_spec.rb +173 -0
  30. data/spec/capybara_webkit_builder_spec.rb +37 -0
  31. data/spec/connection_spec.rb +54 -0
  32. data/spec/cookie_jar_spec.rb +48 -0
  33. data/spec/driver_rendering_spec.rb +80 -0
  34. data/spec/driver_resize_window_spec.rb +59 -0
  35. data/spec/driver_spec.rb +1552 -0
  36. data/spec/integration/driver_spec.rb +20 -0
  37. data/spec/integration/session_spec.rb +137 -0
  38. data/spec/self_signed_ssl_cert.rb +42 -0
  39. data/spec/spec_helper.rb +46 -0
  40. data/src/Body.h +12 -0
  41. data/src/ClearCookies.cpp +15 -0
  42. data/src/ClearCookies.h +11 -0
  43. data/src/Command.cpp +19 -0
  44. data/src/Command.h +31 -0
  45. data/src/CommandFactory.cpp +37 -0
  46. data/src/CommandFactory.h +16 -0
  47. data/src/CommandParser.cpp +76 -0
  48. data/src/CommandParser.h +33 -0
  49. data/src/Connection.cpp +71 -0
  50. data/src/Connection.h +37 -0
  51. data/src/ConsoleMessages.cpp +10 -0
  52. data/src/ConsoleMessages.h +12 -0
  53. data/src/CurrentUrl.cpp +68 -0
  54. data/src/CurrentUrl.h +16 -0
  55. data/src/Evaluate.cpp +84 -0
  56. data/src/Evaluate.h +22 -0
  57. data/src/Execute.cpp +16 -0
  58. data/src/Execute.h +12 -0
  59. data/src/Find.cpp +19 -0
  60. data/src/Find.h +13 -0
  61. data/src/FrameFocus.cpp +66 -0
  62. data/src/FrameFocus.h +28 -0
  63. data/src/GetCookies.cpp +20 -0
  64. data/src/GetCookies.h +14 -0
  65. data/src/Header.cpp +18 -0
  66. data/src/Header.h +11 -0
  67. data/src/Headers.cpp +10 -0
  68. data/src/Headers.h +12 -0
  69. data/src/IgnoreSslErrors.cpp +12 -0
  70. data/src/IgnoreSslErrors.h +12 -0
  71. data/src/JavascriptInvocation.cpp +14 -0
  72. data/src/JavascriptInvocation.h +19 -0
  73. data/src/NetworkAccessManager.cpp +29 -0
  74. data/src/NetworkAccessManager.h +19 -0
  75. data/src/NetworkCookieJar.cpp +101 -0
  76. data/src/NetworkCookieJar.h +15 -0
  77. data/src/Node.cpp +14 -0
  78. data/src/Node.h +13 -0
  79. data/src/NullCommand.cpp +10 -0
  80. data/src/NullCommand.h +11 -0
  81. data/src/PageLoadingCommand.cpp +46 -0
  82. data/src/PageLoadingCommand.h +40 -0
  83. data/src/Render.cpp +18 -0
  84. data/src/Render.h +12 -0
  85. data/src/RequestedUrl.cpp +12 -0
  86. data/src/RequestedUrl.h +12 -0
  87. data/src/Reset.cpp +29 -0
  88. data/src/Reset.h +15 -0
  89. data/src/ResizeWindow.cpp +16 -0
  90. data/src/ResizeWindow.h +12 -0
  91. data/src/Response.cpp +24 -0
  92. data/src/Response.h +15 -0
  93. data/src/Server.cpp +24 -0
  94. data/src/Server.h +21 -0
  95. data/src/SetCookie.cpp +16 -0
  96. data/src/SetCookie.h +11 -0
  97. data/src/SetProxy.cpp +22 -0
  98. data/src/SetProxy.h +11 -0
  99. data/src/Source.cpp +18 -0
  100. data/src/Source.h +19 -0
  101. data/src/Status.cpp +12 -0
  102. data/src/Status.h +12 -0
  103. data/src/UnsupportedContentHandler.cpp +32 -0
  104. data/src/UnsupportedContentHandler.h +18 -0
  105. data/src/Url.cpp +12 -0
  106. data/src/Url.h +12 -0
  107. data/src/Visit.cpp +12 -0
  108. data/src/Visit.h +12 -0
  109. data/src/WebPage.cpp +239 -0
  110. data/src/WebPage.h +58 -0
  111. data/src/body.cpp +10 -0
  112. data/src/capybara.js +315 -0
  113. data/src/find_command.h +29 -0
  114. data/src/main.cpp +33 -0
  115. data/src/webkit_server.pro +85 -0
  116. data/src/webkit_server.qrc +5 -0
  117. data/templates/Command.cpp +10 -0
  118. data/templates/Command.h +12 -0
  119. data/webkit_server.pro +4 -0
  120. metadata +298 -0
@@ -0,0 +1,68 @@
1
+ #include "CurrentUrl.h"
2
+ #include "WebPage.h"
3
+
4
+ CurrentUrl::CurrentUrl(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
5
+ }
6
+
7
+ /*
8
+ * This CurrentUrl command attempts to produce a current_url value consistent
9
+ * with that returned by the Selenium WebDriver Capybara driver.
10
+ *
11
+ * It does not currently return the correct value in the case of an iframe whose
12
+ * source URL results in a redirect because the loading of the iframe does not
13
+ * generate a history item. This is most likely a rare case and is consistent
14
+ * with the current behavior of the capybara-webkit driver.
15
+ *
16
+ * The following two values are *not* affected by Javascript pushState.
17
+ *
18
+ * QWebFrame->url()
19
+ * QWebHistoryItem.originalUrl()
20
+ *
21
+ * The following two values *are* affected by Javascript pushState.
22
+ *
23
+ * QWebFrame->requestedUrl()
24
+ * QWebHistoryItem.url()
25
+ *
26
+ * In the cases that we have access to both the QWebFrame values and the
27
+ * correct history item for that frame, we can compare the values and determine
28
+ * if a redirect occurred and if pushState was used. The table below describes
29
+ * the various combinations of URL values that are possible.
30
+ *
31
+ * O -> originally requested URL
32
+ * R -> URL after redirection
33
+ * P -> URL set by pushState
34
+ * * -> denotes the desired URL value from the frame
35
+ *
36
+ * frame history
37
+ * case url requestedUrl url originalUrl
38
+ * -----------------------------------------------------------------
39
+ * regular load O O* O O
40
+ *
41
+ * redirect w/o R* O R O
42
+ * pushState
43
+ *
44
+ * pushState O P* P O
45
+ * only
46
+ *
47
+ * redirect w/ R P* P O
48
+ * pushState
49
+ *
50
+ * Based on the above information, we only need to check for the case of a
51
+ * redirect w/o pushState, in which case QWebFrame->url() will have the correct
52
+ * current_url value. In all other cases QWebFrame->requestedUrl() is correct.
53
+ */
54
+ void CurrentUrl::start() {
55
+ QUrl humanUrl = wasRedirectedAndNotModifiedByJavascript() ?
56
+ page()->currentFrame()->url() : page()->currentFrame()->requestedUrl();
57
+ QByteArray encodedBytes = humanUrl.toEncoded();
58
+ emit finished(new Response(true, encodedBytes));
59
+ }
60
+
61
+ bool CurrentUrl::wasRegularLoad() {
62
+ return page()->currentFrame()->url() == page()->currentFrame()->requestedUrl();
63
+ }
64
+
65
+ bool CurrentUrl::wasRedirectedAndNotModifiedByJavascript() {
66
+ return !wasRegularLoad() && page()->currentFrame()->url() == page()->history()->currentItem().url();
67
+ }
68
+
data/src/CurrentUrl.h ADDED
@@ -0,0 +1,16 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class CurrentUrl : public Command {
6
+ Q_OBJECT
7
+
8
+ public:
9
+ CurrentUrl(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+
12
+ private:
13
+ bool wasRegularLoad();
14
+ bool wasRedirectedAndNotModifiedByJavascript();
15
+ };
16
+
data/src/Evaluate.cpp ADDED
@@ -0,0 +1,84 @@
1
+ #include "Evaluate.h"
2
+ #include "WebPage.h"
3
+ #include <iostream>
4
+
5
+ Evaluate::Evaluate(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
6
+ m_buffer = "";
7
+ }
8
+
9
+ void Evaluate::start() {
10
+ QVariant result = page()->currentFrame()->evaluateJavaScript(arguments()[0]);
11
+ addVariant(result);
12
+ emit finished(new Response(true, m_buffer));
13
+ }
14
+
15
+ void Evaluate::addVariant(QVariant &object) {
16
+ if (object.isValid()) {
17
+ switch(object.type()) {
18
+ case QMetaType::QString:
19
+ {
20
+ QString string = object.toString();
21
+ addString(string);
22
+ }
23
+ break;
24
+ case QMetaType::QVariantList:
25
+ {
26
+ QVariantList list = object.toList();
27
+ addArray(list);
28
+ }
29
+ break;
30
+ case QMetaType::Double:
31
+ m_buffer.append(object.toString());
32
+ break;
33
+ case QMetaType::QVariantMap:
34
+ {
35
+ QVariantMap map = object.toMap();
36
+ addMap(map);
37
+ break;
38
+ }
39
+ case QMetaType::Bool:
40
+ {
41
+ m_buffer.append(object.toString());
42
+ break;
43
+ }
44
+ default:
45
+ m_buffer.append("null");
46
+ }
47
+ } else {
48
+ m_buffer.append("null");
49
+ }
50
+ }
51
+
52
+ void Evaluate::addString(QString &string) {
53
+ QString escapedString(string);
54
+ escapedString.replace("\"", "\\\"");
55
+ m_buffer.append("\"");
56
+ m_buffer.append(escapedString);
57
+ m_buffer.append("\"");
58
+ }
59
+
60
+ void Evaluate::addArray(QVariantList &list) {
61
+ m_buffer.append("[");
62
+ for (int i = 0; i < list.length(); i++) {
63
+ if (i > 0)
64
+ m_buffer.append(",");
65
+ addVariant(list[i]);
66
+ }
67
+ m_buffer.append("]");
68
+ }
69
+
70
+ void Evaluate::addMap(QVariantMap &map) {
71
+ m_buffer.append("{");
72
+ QMapIterator<QString, QVariant> iterator(map);
73
+ while (iterator.hasNext()) {
74
+ iterator.next();
75
+ QString key = iterator.key();
76
+ QVariant value = iterator.value();
77
+ addString(key);
78
+ m_buffer.append(":");
79
+ addVariant(value);
80
+ if (iterator.hasNext())
81
+ m_buffer.append(",");
82
+ }
83
+ m_buffer.append("}");
84
+ }
data/src/Evaluate.h ADDED
@@ -0,0 +1,22 @@
1
+ #include "Command.h"
2
+
3
+ #include <QVariantList>
4
+
5
+ class WebPage;
6
+
7
+ class Evaluate : public Command {
8
+ Q_OBJECT
9
+
10
+ public:
11
+ Evaluate(WebPage *page, QStringList &arguments, QObject *parent = 0);
12
+ virtual void start();
13
+
14
+ private:
15
+ void addVariant(QVariant &object);
16
+ void addString(QString &string);
17
+ void addArray(QVariantList &list);
18
+ void addMap(QVariantMap &map);
19
+
20
+ QString m_buffer;
21
+ };
22
+
data/src/Execute.cpp ADDED
@@ -0,0 +1,16 @@
1
+ #include "Execute.h"
2
+ #include "WebPage.h"
3
+
4
+ Execute::Execute(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
5
+ }
6
+
7
+ void Execute::start() {
8
+ QString script = arguments()[0] + QString("; 'success'");
9
+ QVariant result = page()->currentFrame()->evaluateJavaScript(script);
10
+ if (result.isValid()) {
11
+ emit finished(new Response(true));
12
+ } else {
13
+ emit finished(new Response(false, QString("Javascript failed to execute")));
14
+ }
15
+ }
16
+
data/src/Execute.h ADDED
@@ -0,0 +1,12 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class Execute : public Command {
6
+ Q_OBJECT
7
+
8
+ public:
9
+ Execute(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+ };
12
+
data/src/Find.cpp ADDED
@@ -0,0 +1,19 @@
1
+ #include "Find.h"
2
+ #include "Command.h"
3
+ #include "WebPage.h"
4
+
5
+ Find::Find(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
6
+ }
7
+
8
+ void Find::start() {
9
+ QString message;
10
+ QVariant result = page()->invokeCapybaraFunction("find", arguments());
11
+
12
+ if (result.isValid()) {
13
+ message = result.toString();
14
+ emit finished(new Response(true, message));
15
+ } else {
16
+ emit finished(new Response(false, QString("Invalid XPath expression")));
17
+ }
18
+ }
19
+
data/src/Find.h ADDED
@@ -0,0 +1,13 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class Find : public Command {
6
+ Q_OBJECT
7
+
8
+ public:
9
+ Find(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+ };
12
+
13
+
@@ -0,0 +1,66 @@
1
+ #include "FrameFocus.h"
2
+ #include "Command.h"
3
+ #include "WebPage.h"
4
+
5
+ FrameFocus::FrameFocus(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
6
+ }
7
+
8
+ void FrameFocus::start() {
9
+ findFrames();
10
+ switch(arguments().length()) {
11
+ case 1:
12
+ focusId(arguments()[0]);
13
+ break;
14
+ case 2:
15
+ focusIndex(arguments()[1].toInt());
16
+ break;
17
+ default:
18
+ focusParent();
19
+ }
20
+ }
21
+
22
+ void FrameFocus::findFrames() {
23
+ frames = page()->currentFrame()->childFrames();
24
+ }
25
+
26
+ void FrameFocus::focusIndex(int index) {
27
+ if (isFrameAtIndex(index)) {
28
+ frames[index]->setFocus();
29
+ success();
30
+ } else {
31
+ frameNotFound();
32
+ }
33
+ }
34
+
35
+ bool FrameFocus::isFrameAtIndex(int index) {
36
+ return 0 <= index && index < frames.length();
37
+ }
38
+
39
+ void FrameFocus::focusId(QString name) {
40
+ for (int i = 0; i < frames.length(); i++) {
41
+ if (frames[i]->frameName().compare(name) == 0) {
42
+ frames[i]->setFocus();
43
+ success();
44
+ return;
45
+ }
46
+ }
47
+
48
+ frameNotFound();
49
+ }
50
+
51
+ void FrameFocus::focusParent() {
52
+ if (page()->currentFrame()->parentFrame() == 0) {
53
+ emit finished(new Response(false, QString("Already at parent frame.")));
54
+ } else {
55
+ page()->currentFrame()->parentFrame()->setFocus();
56
+ success();
57
+ }
58
+ }
59
+
60
+ void FrameFocus::frameNotFound() {
61
+ emit finished(new Response(false, QString("Unable to locate frame. ")));
62
+ }
63
+
64
+ void FrameFocus::success() {
65
+ emit finished(new Response(true));
66
+ }
data/src/FrameFocus.h ADDED
@@ -0,0 +1,28 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+ class QWebFrame;
5
+
6
+ class FrameFocus : public Command {
7
+ Q_OBJECT
8
+
9
+ public:
10
+ FrameFocus(WebPage *page, QStringList &arguments, QObject *parent = 0);
11
+ virtual void start();
12
+
13
+ private:
14
+ void findFrames();
15
+
16
+ void focusParent();
17
+
18
+ void focusIndex(int index);
19
+ bool isFrameAtIndex(int index);
20
+
21
+ void focusId(QString id);
22
+
23
+ void success();
24
+ void frameNotFound();
25
+
26
+ QList<QWebFrame *> frames;
27
+ };
28
+
@@ -0,0 +1,20 @@
1
+ #include "GetCookies.h"
2
+ #include "WebPage.h"
3
+ #include "NetworkCookieJar.h"
4
+
5
+ GetCookies::GetCookies(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent)
6
+ {
7
+ m_buffer = "";
8
+ }
9
+
10
+ void GetCookies::start()
11
+ {
12
+ NetworkCookieJar *jar = qobject_cast<NetworkCookieJar*>(page()
13
+ ->networkAccessManager()
14
+ ->cookieJar());
15
+ foreach (QNetworkCookie cookie, jar->getAllCookies()) {
16
+ m_buffer.append(cookie.toRawForm());
17
+ m_buffer.append("\n");
18
+ }
19
+ emit finished(new Response(true, m_buffer));
20
+ }
data/src/GetCookies.h ADDED
@@ -0,0 +1,14 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class GetCookies : public Command {
6
+ Q_OBJECT;
7
+
8
+ public:
9
+ GetCookies(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+
12
+ private:
13
+ QString m_buffer;
14
+ };
data/src/Header.cpp ADDED
@@ -0,0 +1,18 @@
1
+ #include "Header.h"
2
+ #include "WebPage.h"
3
+ #include "NetworkAccessManager.h"
4
+
5
+ Header::Header(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
6
+ }
7
+
8
+ void Header::start() {
9
+ QString key = arguments()[0];
10
+ QString value = arguments()[1];
11
+ NetworkAccessManager* networkAccessManager = qobject_cast<NetworkAccessManager*>(page()->networkAccessManager());
12
+ if (key.toLower().replace("-", "_") == "user_agent") {
13
+ page()->setUserAgent(value);
14
+ } else {
15
+ networkAccessManager->addHeader(key, value);
16
+ }
17
+ emit finished(new Response(true));
18
+ }
data/src/Header.h ADDED
@@ -0,0 +1,11 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class Header : public Command {
6
+ Q_OBJECT
7
+
8
+ public:
9
+ Header(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+ };
data/src/Headers.cpp ADDED
@@ -0,0 +1,10 @@
1
+ #include "Headers.h"
2
+ #include "WebPage.h"
3
+
4
+ Headers::Headers(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
5
+ }
6
+
7
+ void Headers::start() {
8
+ emit finished(new Response(true, page()->pageHeaders()));
9
+ }
10
+
data/src/Headers.h ADDED
@@ -0,0 +1,12 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class Headers : public Command {
6
+ Q_OBJECT
7
+
8
+ public:
9
+ Headers(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+ };
12
+
@@ -0,0 +1,12 @@
1
+ #include "IgnoreSslErrors.h"
2
+ #include "WebPage.h"
3
+
4
+ IgnoreSslErrors::IgnoreSslErrors(WebPage *page, QStringList &arguments, QObject *parent) :
5
+ Command(page, arguments, parent) {
6
+ }
7
+
8
+ void IgnoreSslErrors::start() {
9
+ page()->ignoreSslErrors();
10
+ emit finished(new Response(true));
11
+ }
12
+
@@ -0,0 +1,12 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class IgnoreSslErrors : public Command {
6
+ Q_OBJECT
7
+
8
+ public:
9
+ IgnoreSslErrors(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+ };
12
+
@@ -0,0 +1,14 @@
1
+ #include "JavascriptInvocation.h"
2
+
3
+ JavascriptInvocation::JavascriptInvocation(QString &functionName, QStringList &arguments, QObject *parent) : QObject(parent) {
4
+ m_functionName = functionName;
5
+ m_arguments = arguments;
6
+ }
7
+
8
+ QString &JavascriptInvocation::functionName() {
9
+ return m_functionName;
10
+ }
11
+
12
+ QStringList &JavascriptInvocation::arguments() {
13
+ return m_arguments;
14
+ }
@@ -0,0 +1,19 @@
1
+ #include <QObject>
2
+ #include <QString>
3
+ #include <QStringList>
4
+
5
+ class JavascriptInvocation : public QObject {
6
+ Q_OBJECT
7
+ Q_PROPERTY(QString functionName READ functionName)
8
+ Q_PROPERTY(QStringList arguments READ arguments)
9
+
10
+ public:
11
+ JavascriptInvocation(QString &functionName, QStringList &arguments, QObject *parent = 0);
12
+ QString &functionName();
13
+ QStringList &arguments();
14
+
15
+ private:
16
+ QString m_functionName;
17
+ QStringList m_arguments;
18
+ };
19
+
@@ -0,0 +1,29 @@
1
+ #include "NetworkAccessManager.h"
2
+ #include "WebPage.h"
3
+ #include <iostream>
4
+
5
+
6
+ NetworkAccessManager::NetworkAccessManager(QObject *parent):QNetworkAccessManager(parent) {
7
+ }
8
+
9
+ QNetworkReply* NetworkAccessManager::createRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice * outgoingData = 0) {
10
+ QNetworkRequest new_request(request);
11
+ if (operation != QNetworkAccessManager::PostOperation && operation != QNetworkAccessManager::PutOperation) {
12
+ new_request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant());
13
+ }
14
+ QHashIterator<QString, QString> item(m_headers);
15
+ while (item.hasNext()) {
16
+ item.next();
17
+ new_request.setRawHeader(item.key().toAscii(), item.value().toAscii());
18
+ }
19
+ return QNetworkAccessManager::createRequest(operation, new_request, outgoingData);
20
+ };
21
+
22
+ void NetworkAccessManager::addHeader(QString key, QString value) {
23
+ m_headers.insert(key, value);
24
+ };
25
+
26
+ void NetworkAccessManager::resetHeaders() {
27
+ m_headers.clear();
28
+ };
29
+
@@ -0,0 +1,19 @@
1
+ #include <QtNetwork/QNetworkAccessManager>
2
+ #include <QtNetwork/QNetworkRequest>
3
+ #include <QtNetwork/QNetworkReply>
4
+
5
+ class NetworkAccessManager : public QNetworkAccessManager {
6
+
7
+ Q_OBJECT
8
+
9
+ public:
10
+ NetworkAccessManager(QObject *parent = 0);
11
+ void addHeader(QString key, QString value);
12
+ void resetHeaders();
13
+
14
+ protected:
15
+ QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice * outgoingData);
16
+
17
+ private:
18
+ QHash<QString, QString> m_headers;
19
+ };
@@ -0,0 +1,101 @@
1
+ #include "NetworkCookieJar.h"
2
+ #include "QtCore/qdatetime.h"
3
+
4
+ NetworkCookieJar::NetworkCookieJar(QObject *parent)
5
+ : QNetworkCookieJar(parent)
6
+ { }
7
+
8
+ QList<QNetworkCookie> NetworkCookieJar::getAllCookies() const
9
+ {
10
+ return allCookies();
11
+ }
12
+
13
+ void NetworkCookieJar::clearCookies()
14
+ {
15
+ setAllCookies(QList<QNetworkCookie>());
16
+ }
17
+
18
+ static inline bool isParentDomain(QString domain, QString reference)
19
+ {
20
+ if (!reference.startsWith(QLatin1Char('.')))
21
+ return domain == reference;
22
+
23
+ return domain.endsWith(reference) || domain == reference.mid(1);
24
+ }
25
+
26
+ void NetworkCookieJar::overwriteCookies(const QList<QNetworkCookie>& cookieList)
27
+ {
28
+ /* this function is basically a copy-and-paste of the original
29
+ QNetworkCookieJar::setCookiesFromUrl with the domain and
30
+ path validations removed */
31
+
32
+ QString defaultPath(QLatin1Char('/'));
33
+ QDateTime now = QDateTime::currentDateTime();
34
+ QList<QNetworkCookie> newCookies = allCookies();
35
+
36
+ foreach (QNetworkCookie cookie, cookieList) {
37
+ bool isDeletion = (!cookie.isSessionCookie() &&
38
+ cookie.expirationDate() < now);
39
+
40
+ // validate the cookie & set the defaults if unset
41
+ if (cookie.path().isEmpty())
42
+ cookie.setPath(defaultPath);
43
+
44
+ // don't do path checking. See http://bugreports.qt.nokia.com/browse/QTBUG-5815
45
+ // else if (!isParentPath(pathAndFileName, cookie.path())) {
46
+ // continue; // not accepted
47
+ // }
48
+
49
+ if (cookie.domain().isEmpty()) {
50
+ continue;
51
+ } else {
52
+ // Ensure the domain starts with a dot if its field was not empty
53
+ // in the HTTP header. There are some servers that forget the
54
+ // leading dot and this is actually forbidden according to RFC 2109,
55
+ // but all browsers accept it anyway so we do that as well.
56
+ if (!cookie.domain().startsWith(QLatin1Char('.')))
57
+ cookie.setDomain(QLatin1Char('.') + cookie.domain());
58
+
59
+ QString domain = cookie.domain();
60
+
61
+ // the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2
62
+ // redundant; the "leading dot" rule has been relaxed anyway, see above
63
+ // we remove the leading dot for this check
64
+ /*
65
+ if (QNetworkCookieJarPrivate::isEffectiveTLD(domain.remove(0, 1)))
66
+ continue; // not accepted
67
+ */
68
+ }
69
+
70
+ for (int i = 0; i < newCookies.size(); ++i) {
71
+ // does this cookie already exist?
72
+ const QNetworkCookie &current = newCookies.at(i);
73
+ if (cookie.name() == current.name() &&
74
+ cookie.domain() == current.domain() &&
75
+ cookie.path() == current.path()) {
76
+ // found a match
77
+ newCookies.removeAt(i);
78
+ break;
79
+ }
80
+ }
81
+
82
+ // did not find a match
83
+ if (!isDeletion) {
84
+ int countForDomain = 0;
85
+ for (int i = newCookies.size() - 1; i >= 0; --i) {
86
+ // Start from the end and delete the oldest cookies to keep a maximum count of 50.
87
+ const QNetworkCookie &current = newCookies.at(i);
88
+ if (isParentDomain(cookie.domain(), current.domain())
89
+ || isParentDomain(current.domain(), cookie.domain())) {
90
+ if (countForDomain >= 49)
91
+ newCookies.removeAt(i);
92
+ else
93
+ ++countForDomain;
94
+ }
95
+ }
96
+
97
+ newCookies += cookie;
98
+ }
99
+ }
100
+ setAllCookies(newCookies);
101
+ }
@@ -0,0 +1,15 @@
1
+ #include <QtNetwork/QNetworkCookieJar>
2
+ #include <QtNetwork/QNetworkCookie>
3
+
4
+ class NetworkCookieJar : public QNetworkCookieJar {
5
+
6
+ Q_OBJECT;
7
+
8
+ public:
9
+
10
+ NetworkCookieJar(QObject *parent = 0);
11
+
12
+ QList<QNetworkCookie> getAllCookies() const;
13
+ void clearCookies();
14
+ void overwriteCookies(const QList<QNetworkCookie>& cookieList);
15
+ };