/* * Copyright (c) 2013, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.github.sdbg.debug.core.internal.webkit.protocol; import com.github.sdbg.debug.core.internal.webkit.protocol.WebkitConnection.NotificationHandler; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * A WIP network domain object. * <p> * Network domain allows tracking network activities of the page. It exposes information about http, * file, data and other requests and responses, their headers, bodies, timing, etc. */ public class WebkitNetwork extends WebkitDomain { public static interface NetworkListener { public void webSocketClosed(String requestId, long timestamp); public void webSocketCreated(String requestId, String url); public void webSocketFrameError(String requestId, long timestamp, String errorMessage); public void webSocketFrameReceived(String requestId, long timestamp, WebSocketFrame frame); public void webSocketFrameSent(String requestId, long timestamp, WebSocketFrame frame); public void webSocketHandshakeResponseReceived(String requestId, long timestamp, WebSocketResponse response); public void webSocketWillSendHandshakeRequest(String requestId, long timestamp, WebSocketRequest request); } public static abstract class NetworkListenerAdapter implements NetworkListener { @Override public void webSocketClosed(String requestId, long timestamp) { } @Override public void webSocketCreated(String requestId, String url) { } @Override public void webSocketFrameError(String requestId, long timestamp, String errorMessage) { } @Override public void webSocketFrameReceived(String requestId, long timestamp, WebSocketFrame frame) { } @Override public void webSocketFrameSent(String requestId, long timestamp, WebSocketFrame frame) { } @Override public void webSocketHandshakeResponseReceived(String requestId, long timestamp, WebSocketResponse response) { } @Override public void webSocketWillSendHandshakeRequest(String requestId, long timestamp, WebSocketRequest request) { } } /** * WebSocket frame data. */ @WebkitUnsupported public static class WebSocketFrame { public static WebSocketFrame createFrom(JSONObject obj) throws JSONException { WebSocketFrame frame = new WebSocketFrame(); frame.opcode = obj.getInt("opcode"); frame.mask = obj.getBoolean("mask"); frame.payloadData = obj.getString("payloadData"); return frame; } /** WebSocket frame opcode. */ public int opcode; /** WebSocket frame mask. */ public boolean mask; /** WebSocket frame payload data. */ public String payloadData; } /** * WebSocket request data. */ @WebkitUnsupported public static class WebSocketRequest { public static WebSocketRequest createFrom(JSONObject obj) throws JSONException { WebSocketRequest request = new WebSocketRequest(); request.headers = obj.getJSONObject("headers"); return request; } /** HTTP response headers, as key/values of a json object. */ public JSONObject headers; } /** * WebSocket response data. */ @WebkitUnsupported public static class WebSocketResponse { public static WebSocketResponse createFrom(JSONObject obj) throws JSONException { WebSocketResponse response = new WebSocketResponse(); response.status = obj.getInt("status"); response.statusText = obj.getString("statusText"); response.headers = obj.getJSONObject("headers"); return response; } /** HTTP response status code. */ public int status; /** HTTP response status text. */ public String statusText; /** HTTP response headers, as key/values of a json object. */ public JSONObject headers; } private static final String WEB_SOCKET_CREATED = "Network.webSocketCreated"; private static final String WEB_SOCKET_HANDSHAKE_REQUEST = "Network.webSocketWillSendHandshakeRequest"; private static final String WEB_SOCKET_HANDSHAKE_RESPONSE = "Network.webSocketHandshakeResponseReceived"; private static final String WEB_SOCKET_FRAME_SENT = "Network.webSocketFrameSent"; private static final String WEB_SOCKET_FRAME_RECEIVED = "Network.webSocketFrameReceived"; private static final String WEB_SOCKET_FRAME_ERROR = "Network.webSocketFrameError"; private static final String WEB_SOCKET_CLOSED = "Network.webSocketClosed"; private List<NetworkListener> listeners = new ArrayList<NetworkListener>(); public WebkitNetwork(WebkitConnection connection) { super(connection); connection.registerNotificationHandler("Network.", new NotificationHandler() { @Override public void handleNotification(String method, JSONObject params) throws JSONException { handleNetworkNotification(method, params); } }); } public void addNetworkListener(NetworkListener listener) { listeners.add(listener); } /** * Disables network tracking, prevents network events from being sent to the client. * * @throws IOException */ public void disable() throws IOException { sendSimpleCommand("Network.disable"); } /** * Enables network tracking, network events will now be delivered to the client. * * @throws IOException */ public void enable() throws IOException { sendSimpleCommand("Network.enable"); } public void removeNetworkListener(NetworkListener listener) { listeners.remove(listener); } protected void handleNetworkNotification(String method, JSONObject params) throws JSONException { if (method.equals(WEB_SOCKET_CREATED)) { String requestId = params.getString("requestId"); String url = params.getString("url"); for (NetworkListener listener : listeners) { listener.webSocketCreated(requestId, url); } } else if (method.equals(WEB_SOCKET_CLOSED)) { String requestId = params.getString("requestId"); long timestamp = params.getLong("timestamp"); for (NetworkListener listener : listeners) { listener.webSocketClosed(requestId, timestamp); } } else if (method.equals(WEB_SOCKET_HANDSHAKE_REQUEST)) { String requestId = params.getString("requestId"); long timestamp = params.getLong("timestamp"); WebSocketRequest request = WebSocketRequest.createFrom(params.getJSONObject("request")); for (NetworkListener listener : listeners) { listener.webSocketWillSendHandshakeRequest(requestId, timestamp, request); } } else if (method.equals(WEB_SOCKET_HANDSHAKE_RESPONSE)) { String requestId = params.getString("requestId"); long timestamp = params.getLong("timestamp"); WebSocketResponse response = WebSocketResponse.createFrom(params.getJSONObject("response")); for (NetworkListener listener : listeners) { listener.webSocketHandshakeResponseReceived(requestId, timestamp, response); } } else if (method.equals(WEB_SOCKET_FRAME_SENT)) { String requestId = params.getString("requestId"); long timestamp = params.getLong("timestamp"); WebSocketFrame frame = WebSocketFrame.createFrom(params.getJSONObject("response")); for (NetworkListener listener : listeners) { listener.webSocketFrameSent(requestId, timestamp, frame); } } else if (method.equals(WEB_SOCKET_FRAME_RECEIVED)) { String requestId = params.getString("requestId"); long timestamp = params.getLong("timestamp"); WebSocketFrame frame = WebSocketFrame.createFrom(params.getJSONObject("response")); for (NetworkListener listener : listeners) { listener.webSocketFrameReceived(requestId, timestamp, frame); } } else if (method.equals(WEB_SOCKET_FRAME_ERROR)) { String requestId = params.getString("requestId"); long timestamp = params.getLong("timestamp"); String errorMessage = params.getString("errorMessage"); for (NetworkListener listener : listeners) { listener.webSocketFrameError(requestId, timestamp, errorMessage); } } else { // There are a lot of other network events - we ignore them for now. //DartDebugCorePlugin.logInfo("unhandled notification: " + method); } } }