2644680e173e1f3d75fdd963eb3dd8ae5bf18e0d
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WebKitGLib / TestSSL.cpp
1 /*
2  * Copyright (C) 2012 Igalia S.L.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21
22 #include "LoadTrackingTest.h"
23 #include "WebKitTestServer.h"
24
25 static WebKitTestServer* kHttpsServer;
26 static WebKitTestServer* kHttpServer;
27
28 static const char* indexHTML = "<html><body>Testing WebKit2GTK+ SSL</body></htmll>";
29 static const char* insecureContentHTML = "<html><script src=\"%s\"></script><body><p>Text + image <img src=\"%s\" align=\"right\"/></p></body></html>";
30 static const char TLSExpectedSuccessTitle[] = "WebKit2Gtk+ TLS permission test";
31 static const char TLSSuccessHTMLString[] = "<html><head><title>WebKit2Gtk+ TLS permission test</title></head><body></body></html>";
32
33 class SSLTest: public LoadTrackingTest {
34 public:
35     MAKE_GLIB_TEST_FIXTURE(SSLTest);
36
37     SSLTest()
38         : m_tlsErrors(static_cast<GTlsCertificateFlags>(0))
39     {
40     }
41
42     virtual void provisionalLoadFailed(const gchar* failingURI, GError* error)
43     {
44         g_assert_error(error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED);
45         LoadTrackingTest::provisionalLoadFailed(failingURI, error);
46     }
47
48     virtual void loadCommitted()
49     {
50         GTlsCertificate* certificate = 0;
51         webkit_web_view_get_tls_info(m_webView, &certificate, &m_tlsErrors);
52         m_certificate = certificate;
53         LoadTrackingTest::loadCommitted();
54     }
55
56     void waitUntilLoadFinished()
57     {
58         m_certificate = 0;
59         m_tlsErrors = static_cast<GTlsCertificateFlags>(0);
60         LoadTrackingTest::waitUntilLoadFinished();
61     }
62
63     GRefPtr<GTlsCertificate> m_certificate;
64     GTlsCertificateFlags m_tlsErrors;
65 };
66
67 static void testSSL(SSLTest* test, gconstpointer)
68 {
69     WebKitWebContext* context = webkit_web_view_get_context(test->m_webView);
70     WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context);
71     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
72
73     test->loadURI(kHttpsServer->getURIForPath("/").data());
74     test->waitUntilLoadFinished();
75     g_assert_nonnull(test->m_certificate);
76     // Self-signed certificate has a nullptr issuer.
77     g_assert_null(g_tls_certificate_get_issuer(test->m_certificate.get()));
78     // We always expect errors because we are using a self-signed certificate,
79     // but only G_TLS_CERTIFICATE_UNKNOWN_CA flags should be present.
80     g_assert_cmpuint(test->m_tlsErrors, ==, G_TLS_CERTIFICATE_UNKNOWN_CA);
81
82     // Non HTTPS loads shouldn't have a certificate nor errors.
83     test->loadHtml(indexHTML, 0);
84     test->waitUntilLoadFinished();
85     g_assert_null(test->m_certificate);
86     g_assert_cmpuint(test->m_tlsErrors, ==, 0);
87
88     webkit_web_context_set_tls_errors_policy(context, originalPolicy);
89 }
90
91 class InsecureContentTest: public WebViewTest {
92 public:
93     MAKE_GLIB_TEST_FIXTURE(InsecureContentTest);
94
95     InsecureContentTest()
96         : m_insecureContentRun(false)
97         , m_insecureContentDisplayed(false)
98     {
99         g_signal_connect(m_webView, "insecure-content-detected", G_CALLBACK(insecureContentDetectedCallback), this);
100     }
101
102     static void insecureContentDetectedCallback(WebKitWebView* webView, WebKitInsecureContentEvent event, InsecureContentTest* test)
103     {
104         g_assert_true(webView == test->m_webView);
105
106         if (event == WEBKIT_INSECURE_CONTENT_RUN)
107             test->m_insecureContentRun = true;
108
109         if (event == WEBKIT_INSECURE_CONTENT_DISPLAYED)
110             test->m_insecureContentDisplayed = true;
111     }
112
113     bool m_insecureContentRun;
114     bool m_insecureContentDisplayed;
115 };
116
117 static void testInsecureContent(InsecureContentTest* test, gconstpointer)
118 {
119     WebKitWebContext* context = webkit_web_view_get_context(test->m_webView);
120     WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context);
121     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
122
123     test->loadURI(kHttpsServer->getURIForPath("/insecure-content/").data());
124     test->waitUntilLoadFinished();
125
126     g_assert_false(test->m_insecureContentRun);
127     // Images are currently always displayed, even bypassing mixed content settings. Check
128     // https://bugs.webkit.org/show_bug.cgi?id=142469
129     g_assert_true(test->m_insecureContentDisplayed);
130
131     webkit_web_context_set_tls_errors_policy(context, originalPolicy);
132 }
133
134 static bool assertIfSSLRequestProcessed = false;
135
136 static void testTLSErrorsPolicy(SSLTest* test, gconstpointer)
137 {
138     WebKitWebContext* context = webkit_web_view_get_context(test->m_webView);
139     // TLS errors are treated as transport failures by default.
140     g_assert_cmpint(webkit_web_context_get_tls_errors_policy(context), ==, WEBKIT_TLS_ERRORS_POLICY_FAIL);
141
142     assertIfSSLRequestProcessed = true;
143     test->loadURI(kHttpsServer->getURIForPath("/").data());
144     test->waitUntilLoadFinished();
145     g_assert_true(test->m_loadFailed);
146     g_assert_true(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed));
147     g_assert_false(test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted));
148     assertIfSSLRequestProcessed = false;
149
150     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
151     g_assert_cmpint(webkit_web_context_get_tls_errors_policy(context), ==, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
152
153     test->m_loadFailed = false;
154     test->loadURI(kHttpsServer->getURIForPath("/").data());
155     test->waitUntilLoadFinished();
156     g_assert_false(test->m_loadFailed);
157
158     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL);
159     g_assert_cmpint(webkit_web_context_get_tls_errors_policy(context), ==, WEBKIT_TLS_ERRORS_POLICY_FAIL);
160 }
161
162 static void testTLSErrorsRedirect(SSLTest* test, gconstpointer)
163 {
164     WebKitWebContext* context = webkit_web_view_get_context(test->m_webView);
165     WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context);
166     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL);
167
168     assertIfSSLRequestProcessed = true;
169     test->loadURI(kHttpsServer->getURIForPath("/redirect").data());
170     test->waitUntilLoadFinished();
171     g_assert_true(test->m_loadFailed);
172     g_assert_true(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed));
173     g_assert_false(test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted));
174     assertIfSSLRequestProcessed = false;
175
176     webkit_web_context_set_tls_errors_policy(context, originalPolicy);
177 }
178
179 static gboolean webViewAuthenticationCallback(WebKitWebView*, WebKitAuthenticationRequest* request)
180 {
181     g_assert_not_reached();
182     return TRUE;
183 }
184
185
186 static void testTLSErrorsHTTPAuth(SSLTest* test, gconstpointer)
187 {
188     WebKitWebContext* context = webkit_web_view_get_context(test->m_webView);
189     WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context);
190     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL);
191
192     assertIfSSLRequestProcessed = true;
193     g_signal_connect(test->m_webView, "authenticate", G_CALLBACK(webViewAuthenticationCallback), NULL);
194     test->loadURI(kHttpsServer->getURIForPath("/auth").data());
195     test->waitUntilLoadFinished();
196     g_assert_true(test->m_loadFailed);
197     g_assert_true(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed));
198     g_assert_false(test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted));
199     assertIfSSLRequestProcessed = false;
200
201     webkit_web_context_set_tls_errors_policy(context, originalPolicy);
202 }
203
204 class TLSErrorsTest: public SSLTest {
205 public:
206     MAKE_GLIB_TEST_FIXTURE(TLSErrorsTest);
207
208     TLSErrorsTest()
209         : m_tlsErrors(static_cast<GTlsCertificateFlags>(0))
210         , m_failingURI(nullptr)
211     {
212     }
213
214     ~TLSErrorsTest()
215     {
216         if (m_failingURI)
217             soup_uri_free(m_failingURI);
218     }
219
220     bool loadFailedWithTLSErrors(const char* failingURI, GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors) override
221     {
222         LoadTrackingTest::loadFailedWithTLSErrors(failingURI, certificate, tlsErrors);
223
224         assertObjectIsDeletedWhenTestFinishes(G_OBJECT(certificate));
225         m_certificate = certificate;
226         m_tlsErrors = tlsErrors;
227         if (m_failingURI)
228             soup_uri_free(m_failingURI);
229         m_failingURI = soup_uri_new(failingURI);
230         return true;
231     }
232
233     GTlsCertificate* certificate() const { return m_certificate.get(); }
234     GTlsCertificateFlags tlsErrors() const { return m_tlsErrors; }
235     const char* host() const { return m_failingURI->host; }
236
237 private:
238     GRefPtr<GTlsCertificate> m_certificate;
239     GTlsCertificateFlags m_tlsErrors;
240     SoupURI* m_failingURI;
241 };
242
243 static void testLoadFailedWithTLSErrors(TLSErrorsTest* test, gconstpointer)
244 {
245     WebKitWebContext* context = webkit_web_view_get_context(test->m_webView);
246     WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context);
247     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL);
248
249     assertIfSSLRequestProcessed = true;
250     // The load-failed-with-tls-errors signal should be emitted when there is a TLS failure.
251     test->loadURI(kHttpsServer->getURIForPath("/test-tls/").data());
252     test->waitUntilLoadFinished();
253     g_assert_true(G_IS_TLS_CERTIFICATE(test->certificate()));
254     g_assert_cmpuint(test->tlsErrors(), ==, G_TLS_CERTIFICATE_UNKNOWN_CA);
255     g_assert_cmpstr(test->host(), ==, soup_uri_get_host(kHttpsServer->baseURI()));
256     g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
257     g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadFailedWithTLSErrors);
258     g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
259     assertIfSSLRequestProcessed = false;
260
261     // Test allowing an exception for this certificate on this host.
262     webkit_web_context_allow_tls_certificate_for_host(context, test->certificate(), test->host());
263     // The page should now load without errors.
264     test->loadURI(kHttpsServer->getURIForPath("/test-tls/").data());
265     test->waitUntilLoadFinished();
266
267     g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
268     g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted);
269     g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
270     g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, TLSExpectedSuccessTitle);
271
272     webkit_web_context_set_tls_errors_policy(context, originalPolicy);
273 }
274
275 class TLSSubresourceTest : public WebViewTest {
276 public:
277     MAKE_GLIB_TEST_FIXTURE(TLSSubresourceTest);
278
279     static void resourceLoadStartedCallback(WebKitWebView* webView, WebKitWebResource* resource, WebKitURIRequest* request, TLSSubresourceTest* test)
280     {
281         if (webkit_web_view_get_main_resource(test->m_webView) == resource)
282             return;
283
284         // Ignore favicons.
285         if (g_str_has_suffix(webkit_uri_request_get_uri(request), "favicon.ico"))
286             return;
287
288         test->subresourceLoadStarted(resource);
289     }
290
291     TLSSubresourceTest()
292         : m_tlsErrors(static_cast<GTlsCertificateFlags>(0))
293     {
294         g_signal_connect(m_webView, "resource-load-started", G_CALLBACK(resourceLoadStartedCallback), this);
295     }
296
297     static void subresourceFailedCallback(WebKitWebResource*, GError*)
298     {
299         g_assert_not_reached();
300     }
301
302     static void subresourceFailedWithTLSErrorsCallback(WebKitWebResource* resource, GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors, TLSSubresourceTest* test)
303     {
304         test->subresourceFailedWithTLSErrors(resource, certificate, tlsErrors);
305     }
306
307     void subresourceLoadStarted(WebKitWebResource* resource)
308     {
309         g_signal_connect(resource, "failed", G_CALLBACK(subresourceFailedCallback), nullptr);
310         g_signal_connect(resource, "failed-with-tls-errors", G_CALLBACK(subresourceFailedWithTLSErrorsCallback), this);
311     }
312
313     void subresourceFailedWithTLSErrors(WebKitWebResource* resource, GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors)
314     {
315         m_certificate = certificate;
316         m_tlsErrors = tlsErrors;
317         g_main_loop_quit(m_mainLoop);
318     }
319
320     void waitUntilSubresourceLoadFail()
321     {
322         g_main_loop_run(m_mainLoop);
323     }
324
325     GRefPtr<GTlsCertificate> m_certificate;
326     GTlsCertificateFlags m_tlsErrors;
327 };
328
329 static void testSubresourceLoadFailedWithTLSErrors(TLSSubresourceTest* test, gconstpointer)
330 {
331     WebKitWebContext* context = webkit_web_view_get_context(test->m_webView);
332     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL);
333
334     assertIfSSLRequestProcessed = true;
335     test->loadURI(kHttpServer->getURIForPath("/").data());
336     test->waitUntilSubresourceLoadFail();
337     g_assert_true(G_IS_TLS_CERTIFICATE(test->m_certificate.get()));
338     g_assert_cmpuint(test->m_tlsErrors, ==, G_TLS_CERTIFICATE_UNKNOWN_CA);
339     assertIfSSLRequestProcessed = false;
340 }
341
342 #if SOUP_CHECK_VERSION(2, 50, 0)
343 class WebSocketTest : public WebViewTest {
344 public:
345     MAKE_GLIB_TEST_FIXTURE(WebSocketTest);
346
347     enum EventFlags {
348         None = 0,
349         DidServerCompleteHandshake = 1 << 0,
350         DidOpen = 1 << 1,
351         DidClose = 1 << 2
352     };
353
354     WebSocketTest()
355     {
356         webkit_user_content_manager_register_script_message_handler(m_userContentManager.get(), "event");
357         g_signal_connect(m_userContentManager.get(), "script-message-received::event", G_CALLBACK(webSocketTestResultCallback), this);
358     }
359
360     virtual ~WebSocketTest()
361     {
362         webkit_user_content_manager_unregister_script_message_handler(m_userContentManager.get(), "event");
363         g_signal_handlers_disconnect_by_data(m_userContentManager.get(), this);
364     }
365
366     static constexpr const char* webSocketTestJSFormat =
367         "var socket = new WebSocket('%s');"
368         "socket.addEventListener('open', onOpen);"
369         "socket.addEventListener('close', onClose);"
370         "function onOpen() {"
371         "    window.webkit.messageHandlers.event.postMessage('open');"
372         "    socket.removeEventListener('close', onClose);"
373         "}"
374         "function onClose() {"
375         "    window.webkit.messageHandlers.event.postMessage('close');"
376         "    socket.removeEventListener('open', onOpen);"
377         "}";
378
379     static void serverWebSocketCallback(SoupServer*, SoupWebsocketConnection*, const char*, SoupClientContext*, gpointer userData)
380     {
381         static_cast<WebSocketTest*>(userData)->m_events |= WebSocketTest::EventFlags::DidServerCompleteHandshake;
382     }
383
384     static void webSocketTestResultCallback(WebKitUserContentManager*, WebKitJavascriptResult* javascriptResult, WebSocketTest* test)
385     {
386         GUniquePtr<char> event(WebViewTest::javascriptResultToCString(javascriptResult));
387         if (!g_strcmp0(event.get(), "open"))
388             test->m_events |= WebSocketTest::EventFlags::DidOpen;
389         else if (!g_strcmp0(event.get(), "close"))
390             test->m_events |= WebSocketTest::EventFlags::DidClose;
391         else
392             g_assert_not_reached();
393         test->quitMainLoop();
394     }
395
396     unsigned connectToServerAndWaitForEvents(WebKitTestServer* server)
397     {
398         m_events = 0;
399
400         server->addWebSocketHandler(serverWebSocketCallback, this);
401         GUniquePtr<char> createWebSocketJS(g_strdup_printf(webSocketTestJSFormat, server->getWebSocketURIForPath("/foo").data()));
402         webkit_web_view_run_javascript(m_webView, createWebSocketJS.get(), nullptr, nullptr, nullptr);
403         g_main_loop_run(m_mainLoop);
404         server->removeWebSocketHandler();
405
406         return m_events;
407     }
408
409     unsigned m_events { 0 };
410 };
411
412 static void testWebSocketTLSErrors(WebSocketTest* test, gconstpointer)
413 {
414     WebKitWebContext* context = webkit_web_view_get_context(test->m_webView);
415     WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context);
416     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL);
417
418     // First, check that insecure ws:// web sockets work fine.
419     unsigned events = test->connectToServerAndWaitForEvents(kHttpServer);
420     g_assert_true(events);
421     g_assert_true(events & WebSocketTest::EventFlags::DidServerCompleteHandshake);
422     g_assert_true(events & WebSocketTest::EventFlags::DidOpen);
423     g_assert_false(events & WebSocketTest::EventFlags::DidClose);
424
425     // Try again using wss:// this time. It should be blocked because the
426     // server certificate is self-signed.
427     events = test->connectToServerAndWaitForEvents(kHttpsServer);
428     g_assert_true(events);
429     g_assert_false(events & WebSocketTest::EventFlags::DidServerCompleteHandshake);
430     g_assert_false(events & WebSocketTest::EventFlags::DidOpen);
431     g_assert_true(events & WebSocketTest::EventFlags::DidClose);
432
433     // Now try wss:// again, this time ignoring TLS errors.
434     webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
435     events = test->connectToServerAndWaitForEvents(kHttpsServer);
436     g_assert_true(events & WebSocketTest::EventFlags::DidServerCompleteHandshake);
437     g_assert_true(events & WebSocketTest::EventFlags::DidOpen);
438     g_assert_false(events & WebSocketTest::EventFlags::DidClose);
439
440     webkit_web_context_set_tls_errors_policy(context, originalPolicy);
441 }
442 #endif
443
444 static void httpsServerCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
445 {
446     if (message->method != SOUP_METHOD_GET) {
447         soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
448         return;
449     }
450
451     g_assert_false(assertIfSSLRequestProcessed);
452
453     if (g_str_equal(path, "/")) {
454         soup_message_set_status(message, SOUP_STATUS_OK);
455         soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, indexHTML, strlen(indexHTML));
456         soup_message_body_complete(message->response_body);
457     } else if (g_str_equal(path, "/insecure-content/")) {
458         GUniquePtr<char> responseHTML(g_strdup_printf(insecureContentHTML, kHttpServer->getURIForPath("/test-script").data(), kHttpServer->getURIForPath("/test-image").data()));
459         soup_message_body_append(message->response_body, SOUP_MEMORY_COPY, responseHTML.get(), strlen(responseHTML.get()));
460         soup_message_set_status(message, SOUP_STATUS_OK);
461         soup_message_body_complete(message->response_body);
462     } else if (g_str_equal(path, "/test-tls/")) {
463         soup_message_set_status(message, SOUP_STATUS_OK);
464         soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, TLSSuccessHTMLString, strlen(TLSSuccessHTMLString));
465         soup_message_body_complete(message->response_body);
466     } else if (g_str_equal(path, "/redirect")) {
467         soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY);
468         soup_message_headers_append(message->response_headers, "Location", kHttpServer->getURIForPath("/test-image").data());
469     } else if (g_str_equal(path, "/auth")) {
470         soup_message_set_status(message, SOUP_STATUS_UNAUTHORIZED);
471         soup_message_headers_append(message->response_headers, "WWW-Authenticate", "Basic realm=\"HTTPS auth\"");
472     } else if (g_str_equal(path, "/style.css")) {
473         soup_message_set_status(message, SOUP_STATUS_OK);
474         static const char* styleCSS = "body { color: black; }";
475         soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, styleCSS, strlen(styleCSS));
476     } else
477         soup_message_set_status(message, SOUP_STATUS_NOT_FOUND);
478 }
479
480 static void httpServerCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
481 {
482     if (message->method != SOUP_METHOD_GET) {
483         soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
484         return;
485     }
486
487     if (g_str_equal(path, "/test-script")) {
488         GUniquePtr<char> pathToFile(g_build_filename(Test::getResourcesDir().data(), "link-title.js", nullptr));
489         char* contents;
490         gsize length;
491         g_file_get_contents(pathToFile.get(), &contents, &length, 0);
492
493         soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, contents, length);
494         soup_message_set_status(message, SOUP_STATUS_OK);
495         soup_message_body_complete(message->response_body);
496     } else if (g_str_equal(path, "/test-image")) {
497         GUniquePtr<char> pathToFile(g_build_filename(Test::getResourcesDir().data(), "blank.ico", nullptr));
498         char* contents;
499         gsize length;
500         g_file_get_contents(pathToFile.get(), &contents, &length, 0);
501
502         soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, contents, length);
503         soup_message_set_status(message, SOUP_STATUS_OK);
504         soup_message_body_complete(message->response_body);
505     } else if (g_str_equal(path, "/")) {
506         soup_message_set_status(message, SOUP_STATUS_OK);
507         char* responseHTML = g_strdup_printf("<html><head><link rel='stylesheet' href='%s' type='text/css'></head><body>SSL subresource test</body></html>",
508             kHttpsServer->getURIForPath("/style.css").data());
509         soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, responseHTML, strlen(responseHTML));
510         soup_message_body_complete(message->response_body);
511     } else
512         soup_message_set_status(message, SOUP_STATUS_NOT_FOUND);
513 }
514
515 void beforeAll()
516 {
517     kHttpsServer = new WebKitTestServer(WebKitTestServer::ServerHTTPS);
518     kHttpsServer->run(httpsServerCallback);
519
520     kHttpServer = new WebKitTestServer(WebKitTestServer::ServerHTTP);
521     kHttpServer->run(httpServerCallback);
522
523     SSLTest::add("WebKitWebView", "ssl", testSSL);
524     InsecureContentTest::add("WebKitWebView", "insecure-content", testInsecureContent);
525     SSLTest::add("WebKitWebView", "tls-errors-policy", testTLSErrorsPolicy);
526     SSLTest::add("WebKitWebView", "tls-errors-redirect-to-http", testTLSErrorsRedirect);
527     SSLTest::add("WebKitWebView", "tls-http-auth", testTLSErrorsHTTPAuth);
528     TLSSubresourceTest::add("WebKitWebView", "tls-subresource", testSubresourceLoadFailedWithTLSErrors);
529     TLSErrorsTest::add("WebKitWebView", "load-failed-with-tls-errors", testLoadFailedWithTLSErrors);
530 #if SOUP_CHECK_VERSION(2, 50, 0)
531     WebSocketTest::add("WebKitWebView", "web-socket-tls-errors", testWebSocketTLSErrors);
532 #endif
533 }
534
535 void afterAll()
536 {
537     delete kHttpsServer;
538     delete kHttpServer;
539 }