1/* 2 * Copyright (C) 2012 Samsung Electronics Ltd. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25#include "config.h" 26 27#if ENABLE(INSPECTOR_SERVER) 28#include "WebInspectorServer.h" 29 30#include "WebInspectorProxy.h" 31#include "WebPageProxy.h" 32#include <WebCore/FileSystem.h> 33#include <WebCore/MIMETypeRegistry.h> 34#include <gio/gio.h> 35#include <glib.h> 36#include <wtf/gobject/GUniquePtr.h> 37#include <wtf/text/CString.h> 38#include <wtf/text/StringBuilder.h> 39#include <wtf/text/StringConcatenate.h> 40 41namespace WebKit { 42 43bool WebInspectorServer::platformResourceForPath(const String& path, Vector<char>& data, String& contentType) 44{ 45 // The page list contains an unformated list of pages that can be inspected with a link to open a session. 46 if (path == "/pagelist.json" || path == "/json") { 47 buildPageList(data, contentType); 48 return true; 49 } 50 51 // Point the default path to a formatted page that queries the page list and display them. 52 CString resourceURI = makeString("resource:///org/webkitgtk/inspector/UserInterface", ((path == "/") ? "/inspectorPageIndex.html" : path)).utf8(); 53 if (resourceURI.isNull()) 54 return false; 55 56 GRefPtr<GFile> file = adoptGRef(g_file_new_for_uri(resourceURI.data())); 57 GUniqueOutPtr<GError> error; 58 GRefPtr<GFileInfo> fileInfo = adoptGRef(g_file_query_info(file.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE "," G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, 0, &error.outPtr())); 59 if (!fileInfo) { 60 StringBuilder builder; 61 builder.appendLiteral("<!DOCTYPE html><html><head></head><body>Error: "); 62 builder.appendNumber(error->code); 63 builder.appendLiteral(", "); 64 builder.append(error->message); 65 builder.appendLiteral(" occurred during fetching inspector resource files.</body></html>"); 66 CString cstr = builder.toString().utf8(); 67 data.append(cstr.data(), cstr.length()); 68 contentType = "text/html; charset=utf-8"; 69 g_warning("Error fetching webinspector resource files: %d, %s", error->code, error->message); 70 return true; 71 } 72 73 GRefPtr<GFileInputStream> inputStream = adoptGRef(g_file_read(file.get(), 0, 0)); 74 if (!inputStream) 75 return false; 76 77 data.grow(g_file_info_get_size(fileInfo.get())); 78 if (!g_input_stream_read_all(G_INPUT_STREAM(inputStream.get()), data.data(), data.size(), 0, 0, 0)) 79 return false; 80 81 contentType = GUniquePtr<gchar>(g_file_info_get_attribute_as_string(fileInfo.get(), G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE)).get(); 82 return true; 83} 84 85void WebInspectorServer::buildPageList(Vector<char>& data, String& contentType) 86{ 87 // chromedevtools (http://code.google.com/p/chromedevtools) 0.3.8 expected JSON format: 88 // { 89 // "title": "Foo", 90 // "url": "http://foo", 91 // "devtoolsFrontendUrl": "/Main.html?ws=localhost:9222/devtools/page/1", 92 // "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/1" 93 // }, 94 95 StringBuilder builder; 96 builder.appendLiteral("[ "); 97 ClientMap::iterator end = m_clientMap.end(); 98 for (ClientMap::iterator it = m_clientMap.begin(); it != end; ++it) { 99 WebPageProxy* webPage = it->value->page(); 100 if (it != m_clientMap.begin()) 101 builder.appendLiteral(", "); 102 builder.appendLiteral("{ \"id\": "); 103 builder.appendNumber(it->key); 104 builder.appendLiteral(", \"title\": \""); 105 builder.append(webPage->pageLoadState().title()); 106 builder.appendLiteral("\", \"url\": \""); 107 builder.append(webPage->pageLoadState().activeURL()); 108 builder.appendLiteral("\", \"inspectorUrl\": \""); 109 builder.appendLiteral("/Main.html?page="); 110 builder.appendNumber(it->key); 111 builder.appendLiteral("\", \"devtoolsFrontendUrl\": \""); 112 builder.appendLiteral("/Main.html?ws="); 113 builder.append(bindAddress()); 114 builder.appendLiteral(":"); 115 builder.appendNumber(port()); 116 builder.appendLiteral("/devtools/page/"); 117 builder.appendNumber(it->key); 118 builder.appendLiteral("\", \"webSocketDebuggerUrl\": \""); 119 builder.appendLiteral("ws://"); 120 builder.append(bindAddress()); 121 builder.appendLiteral(":"); 122 builder.appendNumber(port()); 123 builder.appendLiteral("/devtools/page/"); 124 builder.appendNumber(it->key); 125 builder.appendLiteral("\" }"); 126 } 127 builder.appendLiteral(" ]"); 128 CString cstr = builder.toString().utf8(); 129 data.append(cstr.data(), cstr.length()); 130 contentType = "application/json; charset=utf-8"; 131} 132 133} 134#endif 135