2 Copyright (C) 2011 ProFUSION embedded systems
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.
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.
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.
21 #include "ewk_protocol_handler_soup.h"
23 #include "FrameLoaderClientEfl.h"
24 #include "FrameNetworkingContextEfl.h"
25 #include "ResourceHandle.h"
26 #include "ResourceHandleClient.h"
27 #include "ResourceHandleInternal.h"
28 #include "ewk_private.h"
29 #include <glib-object.h>
31 #include <libsoup/soup-requester.h>
32 #include <libsoup/soup.h>
34 struct _EwkProtocolHandlerPrivate {
39 G_DEFINE_TYPE(EwkCustomProtocolHandler, ewk_custom_protocol_handler, SOUP_TYPE_REQUEST)
41 static char** schemes = 0;
42 static unsigned customProtocolAddedCount = 0;
44 static void ewk_custom_protocol_handler_init(EwkCustomProtocolHandler* customProtocolHandler)
46 customProtocolHandler->priv = G_TYPE_INSTANCE_GET_PRIVATE(customProtocolHandler, EWK_TYPE_CUSTOM_PROTOCOL_HANDLER,
47 EwkProtocolHandlerPrivate);
48 EINA_SAFETY_ON_NULL_RETURN(customProtocolHandler->priv);
50 customProtocolHandler->priv->mime = 0;
51 customProtocolHandler->priv->bytesRead = 0;
54 static void ewk_custom_protocol_handler_finalize(GObject* obj)
56 EwkProtocolHandlerPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(obj, EWK_TYPE_CUSTOM_PROTOCOL_HANDLER,
57 EwkProtocolHandlerPrivate);
61 G_OBJECT_CLASS(ewk_custom_protocol_handler_parent_class)->finalize(obj);
64 static gboolean ewk_custom_protocol_handler_check_uri(SoupRequest* request, SoupURI* uri, GError** error)
69 static GInputStream* ewk_custom_protocol_handler_send(SoupRequest* request, GCancellable* cancellable, GError** error)
75 WebCore::ResourceHandle* resource = static_cast<
76 WebCore::ResourceHandle*>(g_object_get_data(G_OBJECT(request), "webkit-resource"));
77 EINA_SAFETY_ON_NULL_RETURN_VAL(resource, 0);
79 const WebCore::FrameNetworkingContextEfl* frameContext = static_cast<
80 WebCore::FrameNetworkingContextEfl*>(resource->getInternal()->m_context.get());
81 EINA_SAFETY_ON_NULL_RETURN_VAL(frameContext, 0);
83 const WebCore::FrameLoaderClientEfl* frameLoaderClient = static_cast<
84 WebCore::FrameLoaderClientEfl*>(frameContext->coreFrame()->loader()->client());
85 EINA_SAFETY_ON_NULL_RETURN_VAL(frameLoaderClient, 0);
87 SoupURI* uri = soup_request_get_uri(request);
88 EINA_SAFETY_ON_NULL_RETURN_VAL(uri, 0);
90 EwkProtocolHandlerPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(
91 reinterpret_cast<EwkCustomProtocolHandler*>(request),
92 EWK_TYPE_CUSTOM_PROTOCOL_HANDLER,
93 EwkProtocolHandlerPrivate);
95 EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0);
98 if (uri->path[0] == '/') {
99 buffer = ewk_view_protocol_handler_resource_get(frameLoaderClient->webView(),
100 &bytesRead, &mime, uri->path + 1); // The path is always initialized with /.
102 buffer = ewk_view_protocol_handler_resource_get(frameLoaderClient->webView(), &bytesRead, &mime, uri->host);
104 priv->bytesRead = bytesRead;
106 priv->mime = strdup(mime);
108 return g_memory_input_stream_new_from_data(buffer, bytesRead, free);
111 static goffset ewk_custom_protocol_handler_get_content_length(SoupRequest* request)
113 EwkProtocolHandlerPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(reinterpret_cast<EwkCustomProtocolHandler*>(request),
114 EWK_TYPE_CUSTOM_PROTOCOL_HANDLER,
115 EwkProtocolHandlerPrivate);
116 return (priv) ? priv->bytesRead : 0;
119 static const char* ewk_custom_protocol_handler_get_content_type(SoupRequest* request)
121 EwkProtocolHandlerPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(reinterpret_cast<EwkCustomProtocolHandler*>(request),
122 EWK_TYPE_CUSTOM_PROTOCOL_HANDLER,
123 EwkProtocolHandlerPrivate);
124 return (priv && priv->mime) ? priv->mime : "text/html";
127 static void ewk_custom_protocol_handler_class_init(EwkCustomProtocolHandlerClass* customProtocolHandlerClass)
129 GObjectClass* gobjectClass = G_OBJECT_CLASS(customProtocolHandlerClass);
130 SoupRequestClass* requestClass = SOUP_REQUEST_CLASS(customProtocolHandlerClass);
132 gobjectClass->finalize = ewk_custom_protocol_handler_finalize;
133 requestClass->schemes = const_cast<const char**>(schemes);
134 requestClass->check_uri = ewk_custom_protocol_handler_check_uri;
135 requestClass->send = ewk_custom_protocol_handler_send;
136 requestClass->get_content_length = ewk_custom_protocol_handler_get_content_length;
137 requestClass->get_content_type = ewk_custom_protocol_handler_get_content_type;
139 g_type_class_add_private(customProtocolHandlerClass, sizeof(EwkProtocolHandlerPrivate));
142 Eina_Bool ewk_custom_protocol_handler_soup_set(const char** protocols)
145 SoupSession* session = WebCore::ResourceHandle::defaultSession();
146 SoupSessionFeature* requester;
148 protocolsSize = g_strv_length(const_cast<gchar**>(protocols));
150 // This array must be null terminated.
151 EINA_SAFETY_ON_TRUE_RETURN_VAL(!protocolsSize || protocols[protocolsSize], EINA_FALSE);
153 requester = soup_session_get_feature(session, SOUP_TYPE_REQUESTER);
155 requester = SOUP_SESSION_FEATURE(soup_requester_new());
156 soup_session_add_feature(session, requester);
157 g_object_unref(requester);
160 if (soup_session_feature_has_feature(requester, EWK_TYPE_CUSTOM_PROTOCOL_HANDLER)) {
161 customProtocolAddedCount++;
165 schemes = g_strdupv(const_cast<gchar**>(protocols));
166 if (!(schemes && soup_session_feature_add_feature(requester, EWK_TYPE_CUSTOM_PROTOCOL_HANDLER)))
169 customProtocolAddedCount++;
173 Eina_Bool ewk_custom_protocol_handler_soup_all_unset()
175 SoupSession* session = WebCore::ResourceHandle::defaultSession();
176 SoupSessionFeature* requester;
178 if (!customProtocolAddedCount)
181 requester = soup_session_get_feature(session, SOUP_TYPE_REQUESTER);
185 if (!soup_session_feature_has_feature(requester, EWK_TYPE_CUSTOM_PROTOCOL_HANDLER))
188 if (customProtocolAddedCount == 1) {
189 if (soup_session_feature_remove_feature(requester, EWK_TYPE_CUSTOM_PROTOCOL_HANDLER))
195 customProtocolAddedCount--;