### Install iOS WebKit Debug Proxy with Scoop (Windows) Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md This command installs the iOS WebKit Debug Proxy on Windows using the Scoop package manager. It first adds the 'extras' bucket and then installs the proxy. The latest version of iTunes must also be installed. ```console scoop bucket add extras scoop install ios-webkit-debug-proxy ``` -------------------------------- ### Basic Usage Examples Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md Examples demonstrating how to launch the ios_webkit_debug_proxy with different frontend inspector URLs. ```APIDOC ## Basic Usage Examples ### Description Examples demonstrating how to launch the ios_webkit_debug_proxy with different frontend inspector URLs. ### Method Command Line ### Endpoint N/A ### Parameters N/A ### Request Example ```bash ios_webkit_debug_proxy -f chrome-devtools://devtools/bundled/inspector.html ios_webkit_debug_proxy -f ~/chromium/src/third_party/WebKit/Source/devtools/front_end/inspector.html ios_webkit_debug_proxy -f http://foo.com:1234/bar/inspector.html ``` ### Response N/A ### Notes - When using `chrome-devtools://devtools/bundled/inspector.html`, links in `localhost:9222` may not be clickable due to Chrome security restrictions. Copy-pasting them into the address bar is a workaround. - The `-f` value must end in `.html`. `https` URLs are not supported due to security; use `http` or allow them manually in Chrome. - As of Chrome 45, the primary URL changed from `devtools.html` to `inspector.html`. ``` -------------------------------- ### Start iOS Simulator and Mobile Safari Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md This shell script demonstrates how to start the iOS Simulator and launch Mobile Safari within it. Note that the SDK and application paths may change between Xcode versions, so verification is recommended. This needs to be done before starting the proxy. ```sh # Xcode changes these paths frequently, so doublecheck them SDK_DIR="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs" SIM_APP="/Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/Contents/MacOS/Simulator" $SIM_APP -SimulateApplication $SDK_DIR/iPhoneSimulator8.4.sdk/Applications/MobileSafari.app/MobileSafari ``` -------------------------------- ### Main Proxy API - C Code Source: https://context7.com/google/ios-webkit-debug-proxy/llms.txt This C code snippet demonstrates the main API for the iOS Webkit Debug Proxy. It includes setup for callbacks like device subscription, attachment, port selection, and socket management. It initializes the proxy, sets up the socket manager, and starts the main event loop for proxy operation. Dependencies include internal headers like 'ios_webkit_debug_proxy.h' and 'socket_manager.h'. ```c #include "ios-webkit-debug-proxy/ios_webkit_debug_proxy.h" #include "ios-webkit-debug-proxy/socket_manager.h" // Callback: Subscribe to device events int subscribe_callback(iwdp_t iwdp) { return dl_connect(5000); } // Callback: Attach to device int attach_callback(iwdp_t iwdp, const char *device_id, char **to_device_id, char **to_device_name, int *to_device_os_version, void **to_ssl_session) { return wi_connect(device_id, to_device_id, to_device_name, to_device_os_version, to_ssl_session, 1000); } // Callback: Select port for device iwdp_status select_port_callback(iwdp_t iwdp, const char *device_id, int *to_port, int *to_min_port, int *to_max_port) { *to_port = 0; // Let proxy assign automatically *to_min_port = 9222; *to_max_port = 9322; return IWDP_SUCCESS; } // Callback: Listen on port int listen_callback(iwdp_t iwdp, int port) { return sm_listen(port); } // Callback: Connect to host int connect_callback(iwdp_t iwdp, const char *hostname_with_port) { return sm_connect(hostname_with_port); } // Socket manager callbacks sm_status on_accept(sm_t sm, int server_fd, void *server_value, int client_fd, void **to_value) { iwdp_t iwdp = (iwdp_t)sm->state; return iwdp->on_accept(iwdp, server_fd, server_value, client_fd, to_value); } sm_status on_recv(sm_t sm, int fd, void *value, const char *buf, ssize_t length) { iwdp_t iwdp = (iwdp_t)sm->state; return iwdp->on_recv(iwdp, fd, value, buf, length); } sm_status on_close(sm_t sm, int fd, void *value, bool is_server) { iwdp_t iwdp = (iwdp_t)sm->state; return iwdp->on_close(iwdp, fd, value, is_server); } int main() { // Create proxy instance const char *frontend = "http://chrome-devtools-frontend.appspot.com/static/27.0.1453.93/devtools.html"; const char *sim_socket = NULL; // Or "localhost:27753" for simulator iwdp_t iwdp = iwdp_new(frontend, sim_socket); // Setup proxy callbacks iwdp->subscribe = subscribe_callback; iwdp->attach = attach_callback; iwdp->select_port = select_port_callback; iwdp->listen = listen_callback; iwdp->connect = connect_callback; // Create socket manager sm_t sm = sm_new(4096); sm->state = iwdp; sm->on_accept = on_accept; sm->on_recv = on_recv; sm->on_close = on_close; // Setup proxy's socket manager callbacks iwdp->send = (iwdp_status (*)(iwdp_t, int, const char*, size_t))sm->send; iwdp->add_fd = (iwdp_status (*)(iwdp_t, int, void*, void*, bool))sm->add_fd; iwdp->remove_fd = (iwdp_status (*)(iwdp_t, int))sm->remove_fd; // Start proxy if (iwdp->start(iwdp)) { fprintf(stderr, "Failed to start proxy\n"); iwdp_free(iwdp); sm_free(sm); return -1; } printf("Proxy started. Device list: http://localhost:9221\n"); // Event loop while (1) { int ready = sm->select(sm, 2); if (ready < 0) break; sm->cleanup(sm); } // Cleanup sm_free(sm); iwdp_free(iwdp); return 0; } ``` -------------------------------- ### iOS WebKit Debug Proxy CLI Usage Examples Source: https://context7.com/google/ios-webkit-debug-proxy/llms.txt Examples demonstrating various command-line options for running the ios_webkit_debug_proxy. This covers basic startup, enabling debug logging, targeting specific devices, custom port configurations, using different DevTools frontends, disabling the frontend, and supporting iOS Simulators. ```bash # Basic usage: start proxy with defaults ios_webkit_debug_proxy # Device list: http://localhost:9221 # First device: http://localhost:9222 # Second device: http://localhost:9223 # Enable debug logging ios_webkit_debug_proxy --debug # Target specific device by UDID ios_webkit_debug_proxy -u 4ea8dd11e8c4fbc1a2deadbeefa0fd3bbbb268c7 # Custom port configuration ios_webkit_debug_proxy -c null:9221,:9222-9322 # Assign specific device to specific port ios_webkit_debug_proxy -c 4ea8dd11e8c4fbc1a2deadbeefa0fd3bbbb268c7:9227 # Multiple device configuration ios_webkit_debug_proxy -c null:9221,DEVICE_ID_1:9222,DEVICE_ID_2:9223,:9224-9322 # Load configuration from file ios_webkit_debug_proxy -c /etc/ios-webkit-debug-proxy.conf # Use Chrome DevTools frontend ios_webkit_debug_proxy -f chrome-devtools://devtools/bundled/inspector.html # Use local DevTools checkout ios_webkit_debug_proxy -f ~/chromium/src/third_party/WebKit/Source/devtools/front_end/inspector.html # Use custom frontend URL ios_webkit_debug_proxy -f http://custom-frontend.example.com/inspector.html # Disable frontend proxy ios_webkit_debug_proxy --no-frontend # iOS Simulator support ios_webkit_debug_proxy -s localhost:27753 # Custom simulator socket path ios_webkit_debug_proxy -s unix:/private/tmp/com.apple.launchd.xyz/com.apple.webinspectord_sim.socket # Get help ios_webkit_debug_proxy --help # Configuration file format (/etc/ios-webkit-debug-proxy.conf): ``` -------------------------------- ### Build and Install iOS WebKit Debug Proxy from Source (Linux) Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md This sequence of commands clones the iOS WebKit Debug Proxy repository, navigates into the directory, runs the autogen script, builds the project using make, and installs it system-wide. This method is typically used on Linux after installing dependencies. ```console git clone https://github.com/google/ios-webkit-debug-proxy.git cd ios-webkit-debug-proxy ./autogen.sh make sudo make install ``` -------------------------------- ### Device Listener Client Example in C Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/design.md Illustrates how a client can set up and use the device listener. It shows creating a listener, setting its callbacks (send, on_attach, on_detach), and passing received socket data to the listener's on_recv handler. ```c int fd = dl_connect(); dl_t dl = dl_new(); // sets the "start" and "on_recv" functions dl->state = fd; // for use by "my_send" dl->send = my_send; // --> send((int)dl->state, buf, length); dl->on_attach = my_on_attach; // --> printf("%s", device_id); dl->on_detach = my_on_detach; // --> ditto dl->start(); char buf[1024]; while (1) { int len = recv(fd, buf, 1024); if (dl->on_recv(dl, buf, len)) break; } ``` -------------------------------- ### JSON Debugging Command Example Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/examples/wdp_client.html An example of a JSON object representing a debugging command to be sent to the iOS WebKit Debug Proxy. This specific command uses the 'Page.navigate' method to instruct the target page to load a new URL. It includes an 'id' for tracking the command and 'params' object containing the necessary arguments for the method. ```json {"id":1,"method":"Page.navigate","params": {"url":"http://www.google.com/"}} ``` -------------------------------- ### Install iOS WebKit Debug Proxy with Homebrew (macOS) Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md This command installs the iOS WebKit Debug Proxy on macOS using the Homebrew package manager. Ensure Homebrew is installed before running this command. ```console brew install ios-webkit-debug-proxy ``` -------------------------------- ### Install Linux Dependencies for iOS WebKit Debug Proxy Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md These commands install the necessary system dependencies on Debian/Ubuntu-based Linux systems for building the iOS WebKit Debug Proxy. Ensure you have 'sudo' privileges. ```console sudo apt-get install autoconf automake libusb-dev libusb-1.0-0-dev libplist-dev libtool libssl-dev ``` -------------------------------- ### Install Fedora Dependencies for iOS WebKit Debug Proxy Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md These commands install the necessary system dependencies on Fedora-based Linux systems for building the iOS WebKit Debug Proxy. Ensure you have 'sudo' privileges. ```console sudo dnf install autoconf automake libusb1-devel libusb-compat-0.1-devel libtool openssl-devel sudo dnf install libplist-devel usbmuxd libimobiledevice-devel libimobiledevice-utils libimobiledevice-glue-devel ``` -------------------------------- ### Set Custom DevTools UI URL for iOS WebKit Debug Proxy Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md This command demonstrates how to start the iOS WebKit Debug Proxy and specify a different frontend URL using the '-f' argument. This is useful for using local versions of DevTools or alternative frontend sources. The example shows setting a local Chromium checkout as the frontend. ```console ios_webkit_debug_proxy -f ``` -------------------------------- ### Start iOS WebKit Debug Proxy Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md This command starts the iOS WebKit Debug Proxy. By default, it listens on port 9221. Use the '--debug' flag for verbose output, '--frontend' to specify a custom frontend URL, or '--help' for a list of all available options. Press Ctrl-C to quit. ```console ios_webkit_debug_proxy ``` -------------------------------- ### Device Listener API in C Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/design.md Defines the structure and function pointers for a device listener in the iOS WebKit Debug Proxy. It includes public API functions like 'start' and 'on_recv', and abstract callback functions for 'send', 'on_attach', and 'on_detach'. The 'state' field is available for client-specific data. ```c typedef struct { dl_status (*start)(dl_t self); dl_status (*on_recv)(dl_t self, const char *buf, ); dl_status (*send)(dl_t self, const char *buf, size_t length); dl_status (*on_attach)(dl_t self, const char *device_id); dl_status (*on_detach)(dl_t self, const char *device_id); void *state; } dl_t; ``` -------------------------------- ### Manage Sockets with Socket Manager API (C) Source: https://context7.com/google/ios-webkit-debug-proxy/llms.txt Illustrates the use of the Socket Manager API for non-blocking socket multiplexing. This example sets up a server to listen on a port, defines callbacks for connection events (accept, sent, receive, close), and enters an event loop to handle socket activity. It utilizes SSL/TLS support. Dependencies include the 'ios-webkit-debug-proxy/socket_manager.h' header. ```c #include "ios-webkit-debug-proxy/socket_manager.h" typedef struct { int connection_count; } manager_state_t; // Callback: Accept new connection sm_status on_accept(sm_t sm, int server_fd, void *server_value, int client_fd, void **to_value) { printf("New connection accepted: fd=%d\n", client_fd); int *conn_id = malloc(sizeof(int)); *conn_id = client_fd; *to_value = conn_id; return SM_SUCCESS; } // Callback: Data sent successfully sm_status on_sent(sm_t sm, int fd, void *value, const char *buf, ssize_t length) { printf("Sent %zd bytes to fd=%d\n", length, fd); return SM_SUCCESS; } // Callback: Data received sm_status on_recv(sm_t sm, int fd, void *value, const char *buf, ssize_t length) { printf("Received %zd bytes from fd=%d: %.*s\n", length, fd, (int)length, buf); // Echo back return sm->send(sm, fd, buf, length, value); } // Callback: Connection closed sm_status on_close(sm_t sm, int fd, void *value, bool is_server) { printf("Connection closed: fd=%d, is_server=%d\n", fd, is_server); if (value) free(value); return SM_SUCCESS; } int main() { // Create socket manager with 8KB buffers sm_t sm = sm_new(8192); // Setup callbacks manager_state_t state = {.connection_count = 0}; sm->state = &state; sm->on_accept = on_accept; sm->on_sent = on_sent; sm->on_recv = on_recv; sm->on_close = on_close; // Create server socket int server_fd = sm_listen(9222); if (server_fd < 0) { fprintf(stderr, "Failed to bind to port 9222\n"); sm_free(sm); return -1; } // Add server socket to manager int server_value = 1; sm->add_fd(sm, server_fd, NULL, &server_value, true); printf("Server listening on port 9222\n"); // Event loop while (1) { int ready = sm->select(sm, 5); // 5 second timeout if (ready < 0) { fprintf(stderr, "Select error\n"); break; } else if (ready == 0) { printf("Timeout, no activity\n"); } // Process any cleanup sm->cleanup(sm); } // Cleanup sm_free(sm); return 0; } ``` -------------------------------- ### REST API - List Devices - Bash Source: https://context7.com/google/ios-webkit-debug-proxy/llms.txt This Bash command uses `curl` to query the REST API for a list of all connected devices. It sends an HTTP GET request to the `/json` endpoint on the default proxy port (9221). The expected output is a JSON array containing details about each connected device. No specific inputs are required other than the base URL. ```bash curl http://localhost:9221/json ``` -------------------------------- ### REST API - HTML Device Listing - Bash Source: https://context7.com/google/ios-webkit-debug-proxy/llms.txt This Bash command uses `curl` to fetch the HTML-based device listing. It sends an HTTP GET request to the root URL of the proxy (e.g., `http://localhost:9221`). This endpoint provides a browser-friendly view of connected devices, typically rendering an HTML page instead of JSON. It's useful for quick visual inspection. ```bash curl http://localhost:9221 ``` -------------------------------- ### Running ios-webkit-debug-proxy with Frontend URL Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md Demonstrates how to launch the ios-webkit-debug-proxy with a specified frontend debugging page. It highlights URL variations and security considerations for `https` protocols. Note that `chrome-devtools://` URLs may have limitations with clickable links. ```bash ios_webkit_debug_proxy -f chrome-devtools://devtools/bundled/inspector.html ios_webkit_debug_proxy -f ~/chromium/src/third_party/WebKit/Source/devtools/front_end/inspector.html ios_webkit_debug_proxy -f http://foo.com:1234/bar/inspector.html ``` -------------------------------- ### Main Proxy API Source: https://context7.com/google/ios-webkit-debug-proxy/llms.txt The Main Proxy API orchestrates all components for full debugging proxy functionality. It involves setting up callbacks for device subscription, attachment, port selection, listening, and connecting to hosts. The provided C code demonstrates the initialization and event loop of the proxy. ```APIDOC ## Main Proxy API ### Description Complete proxy orchestration integrating all components for full debugging proxy functionality. ### Method N/A (C code demonstrating library usage) ### Endpoint N/A (This is a library API, not a network endpoint) ### Parameters N/A ### Request Example ```c #include "ios-webkit-debug-proxy/ios_webkit_debug_proxy.h" #include "ios-webkit-debug-proxy/socket_manager.h" // Callback: Subscribe to device events int subscribe_callback(iwdp_t iwdp) { return dl_connect(5000); } // Callback: Attach to device int attach_callback(iwdp_t iwdp, const char *device_id, char **to_device_id, char **to_device_name, int *to_device_os_version, void **to_ssl_session) { return wi_connect(device_id, to_device_id, to_device_name, to_device_os_version, to_ssl_session, 1000); } // Callback: Select port for device iwdp_status select_port_callback(iwdp_t iwdp, const char *device_id, int *to_port, int *to_min_port, int *to_max_port) { *to_port = 0; // Let proxy assign automatically *to_min_port = 9222; *to_max_port = 9322; return IWDP_SUCCESS; } // Callback: Listen on port int listen_callback(iwdp_t iwdp, int port) { return sm_listen(port); } // Callback: Connect to host int connect_callback(iwdp_t iwdp, const char *hostname_with_port) { return sm_connect(hostname_with_port); } // Socket manager callbacks sm_status on_accept(sm_t sm, int server_fd, void *server_value, int client_fd, void **to_value) { iwdp_t iwdp = (iwdp_t)sm->state; return iwdp->on_accept(iwdp, server_fd, server_value, client_fd, to_value); } sm_status on_recv(sm_t sm, int fd, void *value, const char *buf, ssize_t length) { iwdp_t iwdp = (iwdp_t)sm->state; return iwdp->on_recv(iwdp, fd, value, buf, length); } sm_status on_close(sm_t sm, int fd, void *value, bool is_server) { iwdp_t iwdp = (iwdp_t)sm->state; return iwdp->on_close(iwdp, fd, value, is_server); } int main() { // Create proxy instance const char *frontend = "http://chrome-devtools-frontend.appspot.com/static/27.0.1453.93/devtools.html"; const char *sim_socket = NULL; // Or "localhost:27753" for simulator iwdp_t iwdp = iwdp_new(frontend, sim_socket); // Setup proxy callbacks iwdp->subscribe = subscribe_callback; iwdp->attach = attach_callback; iwdp->select_port = select_port_callback; iwdp->listen = listen_callback; iwdp->connect = connect_callback; // Create socket manager sm_t sm = sm_new(4096); sm->state = iwdp; sm->on_accept = on_accept; sm->on_recv = on_recv; sm->on_close = on_close; // Setup proxy's socket manager callbacks iwdp->send = (iwdp_status (*)(iwdp_t, int, const char*, size_t))sm->send; iwdp->add_fd = (iwdp_status (*)(iwdp_t, int, void*, void*, bool))sm->add_fd; iwdp->remove_fd = (iwdp_status (*)(iwdp_t, int))sm->remove_fd; // Start proxy if (iwdp->start(iwdp)) { fprintf(stderr, "Failed to start proxy\n"); iwdp_free(iwdp); sm_free(sm); return -1; } printf("Proxy started. Device list: http://localhost:9221\n"); // Event loop while (1) { int ready = sm->select(sm, 2); if (ready < 0) break; sm->cleanup(sm); } // Cleanup sm_free(sm); iwdp_free(iwdp); return 0; } ``` ``` -------------------------------- ### Troubleshooting Common Issues Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md Solutions for frequently encountered problems when using the ios_webkit_debug_proxy. ```APIDOC ## Troubleshooting Common Issues ### Description Solutions for frequently encountered problems when using the ios_webkit_debug_proxy. ### Method N/A ### Endpoint N/A ### Issues and Solutions #### Undefined reference to symbol 'log10@@GLIBC_2.2.5' ```console /usr/bin/ld: ios_webkit_debug_proxy-char_buffer.o: undefined reference to symbol 'log10@@GLIBC_2.2.5' //lib/x86_64-linux-gnu/libm.so.6: error adding symbols: DSO missing from command line ``` Run this before `make`: `./configure LIBS="-lm"` #### Error while loading shared libraries: libimobiledevice.so.6 ```console ios_webkit_debug_proxy: error while loading shared libraries: libimobiledevice.so.6: cannot open shared object file: No such file or directory ``` Run `sudo ldconfig` #### idevice_id not found The `idevice_id` executable may be found as part of the `libimobiledevice-utils` package. #### Could not start com.apple.webinspector! success [Remove and rebuild libimobiledevice](https://github.com/google/ios-webkit-debug-proxy/issues/82#issuecomment-74205898). #### Could not connect to lockdownd (or doesn't work with iOS10+) * **"No such file or directory. Unable to attach ... inspector"**: Check the device for a prompt to trust the connected computer. Choose "Trust" and try again. * **"Broken pipe. Unable to attach ... inspector"** or **"Could not connect to lockdownd, error code -. Exiting."**: Make sure you are using the latest version of `ios-webkit-debug-proxy`. #### Inspectable pages list is empty for iOS >= 12.2 Make sure you are using the latest version of `ios-webkit-debug-proxy`. #### Can not see Simulator * Ensure the simulator is started before the proxy. * Verify that the "Web Inspector" switch is enabled in Settings -> Safari -> Advanced. * Check `/etc/hosts` for the `::1 localhost` line, as the simulator's web inspector daemon likely listens on an IPv6 interface. #### Building under Rosetta (OS X) `libimobildevice` formulae depends on `openssl@1.1`, which is key-only and requires the following environment paths for the build: ```bash export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig" export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" ``` #### If no luck so far... Try replugging the USB cable. ``` -------------------------------- ### Troubleshooting Shared Library Load Errors Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md Offers a fix for the 'error while loading shared libraries: libimobiledevice.so.6' error. This issue arises when the `libimobiledevice` shared library cannot be found by the system's dynamic linker. ```bash sudo ldconfig ``` -------------------------------- ### JavaScript WebSocket Test Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/examples/ws_client.html This JavaScript function demonstrates how to establish a WebSocket connection to a local server (ws://localhost:8080/) and send/receive messages. It includes handlers for connection open, message reception, closure, and errors. This is useful for testing real-time communication features. ```javascript function WebSocketTest() { if ("WebSocket" in window) { var ws = new WebSocket("ws://localhost:8080/"); var count = 3; ws.onopen = function() { alert("Sending "+count); ws.send("count["+count+"]"); }; ws.onmessage = function (evt) { alert("Received ("+evt.data+"), sending " + (count > 1 ? (count-1) : "close")); if (count > 1) { ws.send("count["+(--count)+"]"); } else { ws.close(); } }; ws.onclose = function() { alert("Closed"); }; ws.onerror = function(e) { alert("Error: "+e.data); }; } else { alert("WebSocket NOT supported by your Browser!"); } } ``` -------------------------------- ### Troubleshooting Rosetta Build Environment Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md Details the environment variable settings required for building ios-webkit-debug-proxy on macOS using Rosetta, specifically when dependencies like `openssl@1.1` need to be correctly located by the build tools. ```bash export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig" export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" ``` -------------------------------- ### Configure Device Ports with Port Configuration API (C) Source: https://context7.com/google/ios-webkit-debug-proxy/llms.txt Demonstrates how to create and configure port mappings for iOS devices using the Port Configuration API. It includes adding rules for specific devices, ranges, and default configurations, as well as selecting a port for a given device ID. Dependencies include the 'ios-webkit-debug-proxy/port_config.h' header. ```c #include "ios-webkit-debug-proxy/port_config.h" int main() { // Create port configuration pc_t pc = pc_new(); // Add configuration rules (device_id:port or device_id:min_port-max_port) const char *rules[] = { "null:9221", // Device list on port 9221 "4ea8dd11e8c4fbc1a2deadbeefa0fd3bbbb268c7:9227", // Specific device "ddc86a51827948e13bdeadbeef5bc588ea35fcf2:9225-9240", // Device range ":9222-9322" // All other devices in range 9222-9322 }; for (int i = 0; i < 4; i++) { const char *error = pc_add_line(pc, rules[i], strlen(rules[i])); if (error) { fprintf(stderr, "Configuration error: %s\n", error); pc_free(pc); return -1; } } // Or load from file // if (pc_add_file(pc, "/etc/ios-webkit-debug-proxy.conf") < 0) { // fprintf(stderr, "Failed to load config file\n"); // } // Select port for device const char *device_id = "4ea8dd11e8c4fbc1a2deadbeefa0fd3bbbb268c7"; int port = 0, min_port = 0, max_port = 0; int result = pc_select_port(pc, device_id, &port, &min_port, &max_port); if (result == 0) { printf("Device %s assigned to port %d\n", device_id, port); printf("Port range: %d-%d\n", min_port, max_port); } else { printf("Device %s will scan ports %d-%d\n", device_id, min_port, max_port); } // Cleanup pc_free(pc); return 0; } ``` -------------------------------- ### Troubleshooting Linker Errors with libm Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md Provides a solution for the 'undefined reference to symbol 'log10@@GLIBC_2.2.5'' linker error. This typically occurs when the math library is not correctly linked during the build process. ```bash ./configure LIBS="-lm" ``` -------------------------------- ### Node.js Integration with ios-webkit-debug-proxy Source: https://context7.com/google/ios-webkit-debug-proxy/llms.txt This Node.js script demonstrates how to use the proxy's REST and WebSocket APIs. It fetches the device list, lists pages for a selected device, and connects to a page's debugging WebSocket to send commands like Page.navigate. Ensure the proxy is running on the default port (9221). ```javascript const WebSocket = require('ws'); const http = require('http'); // Fetch device list function getDevices() { return new Promise((resolve, reject) => { http.get('http://localhost:9221/json', (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => resolve(JSON.parse(data))); }).on('error', reject); }); } // Fetch pages for device function getPages(port) { return new Promise((resolve, reject) => { http.get(`http://localhost:${port}/json`, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => resolve(JSON.parse(data))); }).on('error', reject); }); } // Debug page async function debugPage(port, pageId) { const url = `ws://localhost:${port}/devtools/page/${pageId}`; const ws = new WebSocket(url); let targetId = null; let cmdId = 1; ws.on('open', () => { console.log(`Connected to ${url}`); }); ws.on('message', (data) => { const msg = JSON.parse(data); console.log('Received:', JSON.stringify(msg, null, 2)); if (msg.method === 'Target.targetCreated') { targetId = msg.params.targetInfo.targetId; // Navigate to URL sendCommand('Page.navigate', { url: 'https://www.apple.com' }); } }); function sendCommand(method, params) { if (!targetId) { console.error('Target ID not available'); return; } const message = { id: cmdId++, method: 'Target.sendMessageToTarget', params: { targetId: targetId, message: JSON.stringify({ id: cmdId, method: method, params: params }) } }; console.log('Sending:', JSON.stringify(message, null, 2)); ws.send(JSON.stringify(message)); } ws.on('error', (err) => { console.error('WebSocket error:', err); }); ws.on('close', () => { console.log('Connection closed'); }); } // Main (async () => { try { // List devices const devices = await getDevices(); console.log('Devices:', devices); if (devices.length === 0) { console.log('No devices connected'); return; } // Use first device (extract port from webSocketDebuggerUrl) const deviceUrl = devices[0].webSocketDebuggerUrl; const port = new URL(deviceUrl).port; // List pages const pages = await getPages(port); console.log('Pages:', pages); if (pages.length === 0) { console.log('No pages open'); return; } // Debug first page await debugPage(port, pages[0].id); } catch (err) { console.error('Error:', err); } })(); ``` -------------------------------- ### IWDP Clients API Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md JSON-formatted APIs for programmatic clients to interact with the proxy. ```APIDOC ## IWDP Clients API ### Description JSON-formatted APIs for programmatic clients to interact with the proxy. ### Method GET ### Endpoint Examples * `http://localhost:9221/json`: Lists all connected devices. * `http://localhost:9222/json`: Lists tabs for the device connected to port `9222`. * `ws://localhost:9222/devtools/page/1`: WebSocket URL to inspect a specific tab. Refer to the [examples/README](examples/README.md) for example clients in NodeJS, C, clientside JS, and more. ``` -------------------------------- ### JavaScript WebSocket Connection and Message Handling Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/examples/wdp_client.html Establishes a WebSocket connection to the iOS WebKit Debug Proxy, handles connection events (open, message, close, error), and parses incoming JSON messages. It specifically listens for 'Target.targetCreated' to capture the target ID needed for subsequent commands. This function is crucial for setting up communication with the debugging proxy. ```javascript var ws, target_id, cmd_id = 1000, commands = []; function onConnect() { ol_clear("send_ol"); ol_clear("recv_ol"); ws && ws.close(); var form = document.getElementById("f"); var port = form.elements["port"].value; var page_num = form.elements["page_num"].value; var url = "ws://localhost:" + port + "/devtools/page/" + page_num; ws = new WebSocket(url); ws.onopen = function() { ol_append("recv_ol", "opened " + url); }; ws.onmessage = function(evt) { ol_append("recv_ol", evt.data); var in_cmd = JSON.parse(evt.data); if (in_cmd.method === "Target.targetCreated") { target_id = in_cmd.params.targetInfo.targetId; } send_next_command(); }; ws.onclose = function() { ol_append("recv_ol", "closed"); }; ws.onerror = function(e) { ol_append("recv_ol", "error: " + e.data); }; } ``` -------------------------------- ### Connect to iOS WebInspector Service with C API Source: https://context7.com/google/ios-webkit-debug-proxy/llms.txt This C code snippet demonstrates how to establish a direct connection to an iOS device's WebInspector service using the iwdp library. It includes setting up callbacks for sending and receiving data, establishing the connection, sending an RPC command, and entering an event loop to process incoming data. Dependencies include the 'ios-webkit-debug-proxy/webinspector.h' header and standard socket functions. ```c #include "ios-webkit-debug-proxy/webinspector.h" // Custom state for callbacks typedef struct { int fd; char *device_id; } my_state_t; // Callback: Send packet to device wi_status send_packet(wi_t wi, const char *packet, size_t length) { my_state_t *state = (my_state_t*)wi->state; ssize_t sent = send(state->fd, packet, length, 0); return (sent == length) ? WI_SUCCESS : WI_ERROR; } // Callback: Receive parsed plist from device wi_status recv_plist(wi_t wi, const plist_t rpc_dict) { char *xml = NULL; uint32_t length = 0; plist_to_xml(rpc_dict, &xml, &length); printf("Received: %s\n", xml); free(xml); return WI_SUCCESS; } int main() { // Connect to device char *device_id = NULL; char *device_name = NULL; void *ssl_session = NULL; int fd = wi_connect(NULL, &device_id, &device_name, NULL, &ssl_session, 1000); if (fd < 0) return -1; // Create WebInspector instance wi_t wi = wi_new(false, false); // Setup callbacks and state my_state_t state = {.fd = fd, .device_id = device_id}; wi->state = &state; wi->send_packet = send_packet; wi->recv_plist = recv_plist; // Send reportIdentifier command const char *xml = "\n" "\n" " __selector_rpc_reportIdentifier:\n" " __argument\n" " WIRConnectionIdentifierKey\n" " 077BA242-564F-443B-B83A-EFBB337DAE35\n" " "; plist_t rpc_dict = NULL; plist_from_xml(xml, strlen(xml), &rpc_dict); wi->send_plist(wi, rpc_dict); plist_free(rpc_dict); // Event loop: forward socket data to WebInspector char buf[4096]; while (1) { ssize_t bytes = recv(fd, buf, sizeof(buf), 0); if (bytes <= 0) break; if (wi->on_recv(wi, buf, bytes)) break; } // Cleanup free(device_id); free(device_name); wi_free(wi); close(fd); return 0; } ``` -------------------------------- ### Port Assignment Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/README.md Details on how ports are assigned to devices and the device list. ```APIDOC ## Port Assignment ### Description Details on how ports are assigned to devices and the device list. ### Method N/A ### Endpoint N/A ### Parameters N/A ### Default Port Assignment - `:9221`: Device list - `:9222`: First iOS device attached - `:9223`: Second iOS device attached - ... - `:9322`: Maximum device If a port is in use, the next available port within the range will be used. ### Port Assignment Persistence Ports are assigned on a first-come, first-served basis but are preserved if a device is detached and reattached, provided the proxy is not restarted. Example: 1. Start the proxy. 2. Device list gets `:9221`. 3. Attach Device A, gets `:9222`. 4. Attach Device B, gets `:9223`. 5. Detach Device A (doesn't affect Device B's port). 6. Attach Device C, gets `:9224` (not `:9222`). 7. Reattach Device A, gets `:9222` again (not `:9225`). ### Custom Port Assignment Port assignment rules can be set via the command line with the `-c` flag. The default is equivalent to: ```bash ios_webkit_debug_proxy -c null:9221,:9222-9322 ``` Where `null` represents the device list. The following example restricts the proxy to a single device and port: ```bash ios_webkit_debug_proxy -c 4ea8dd11e8c4fbc1a2deadbeefa0fd3bbbb268c7:9227 ``` ``` -------------------------------- ### REST API - List Pages on Device - Bash Source: https://context7.com/google/ios-webkit-debug-proxy/llms.txt This Bash command utilizes `curl` to retrieve a list of debuggable pages on a specific device. It targets the `/json` endpoint, but on a port associated with an individual device (e.g., 9222). The output is a JSON array detailing each debuggable page, including its URL and WebSocket debugger URL. This command is useful for inspecting specific devices once they are proxied. ```bash curl http://localhost:9222/json ``` -------------------------------- ### JavaScript Command Sending and Queue Management Source: https://github.com/google/ios-webkit-debug-proxy/blob/master/examples/wdp_client.html Manages the sending of debugging commands over the established WebSocket connection. It validates the connection state and ensures a target ID is available before processing commands from a text area. Commands are added to a queue and sent sequentially using 'send_next_command'. This function is essential for executing debugging actions on the target page. ```javascript function onCommand() { if (!ws) { return alert("WebSocket is not connected!"); } else if (ws.readyState !== 1) { return alert("WebSocket is not open, current state: " + ws.readyState); } else if (!target_id) { return alert("Page target was not received yet, waiting for \"Target.targetCreated\" message"); } var text = document.getElementById("commands"); var lines = text.value.split("\n"); lines.forEach((line) => { var msg = line.trim(); if (msg) { commands.push({id: cmd_id++, method: "Target.sendMessageToTarget", params: {targetId: target_id, message: msg}}); } }); send_next_command(); } function send_next_command() { if (commands.length > 0) { var out_msg = JSON.stringify(commands.shift()); ol_append("send_ol", out_msg); ws.send(out_msg); } }; ```