Skip to content

Option to customize simulator webinspector socket address #306

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions include/ios-webkit-debug-proxy/ios_webkit_debug_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ typedef struct iwdp_private *iwdp_private_t;

struct iwdp_struct;
typedef struct iwdp_struct *iwdp_t;
iwdp_t iwdp_new(const char* frontend);
iwdp_t iwdp_new(const char* frontend, const char* sim_wi_socket_addr);
void iwdp_free(iwdp_t self);

struct iwdp_struct {
Expand Down Expand Up @@ -83,8 +83,8 @@ struct iwdp_struct {
int (*listen)(iwdp_t self, int port);

// Connect to a host:port for static data.
// @param hostname e.g. "chrome-devtools-frontend.appspot.com"
int (*connect)(iwdp_t self, const char *hostname, int port);
// @param hostname_with_port e.g. "chrome-devtools-frontend.appspot.com:8080"
int (*connect)(iwdp_t self, const char *hostname_with_port);

// Send bytes to fd.
iwdp_status (*send)(iwdp_t self, int fd, const char *data, size_t length);
Expand Down
2 changes: 1 addition & 1 deletion include/ios-webkit-debug-proxy/socket_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extern "C" {
int sm_listen(int port);

// Connect to a server, return the file descriptor (or -1 for error).
int sm_connect(const char *hostname, int port);
int sm_connect(const char *socket_addr);


typedef uint8_t sm_status;
Expand Down
32 changes: 20 additions & 12 deletions src/ios_webkit_debug_proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct iwdp_private {

// frontend url, e.g. "http://bar.com/devtools.html" or "/foo/inspector.html"
char *frontend;
char *sim_wi_socket_addr;
};


Expand Down Expand Up @@ -413,13 +414,12 @@ dl_status iwdp_on_attach(dl_t dl, const char *device_id, int device_num) {
if (is_sim) {
// TODO launch webinspectord
// For now we'll assume Safari starts it for us.
// The port 27753 is from `locate com.apple.webinspectord.plist`.
//
// `launchctl list` shows:
// com.apple.iPhoneSimulator:com.apple.webinspectord
// so the launch is probably something like:
// xpc_connection_create[_mach_service](...webinspectord, ...)?
wi_fd = self->connect(self, "localhost", 27753);
wi_fd = self->connect(self, my->sim_wi_socket_addr);
} else {
wi_fd = self->attach(self, device_id, NULL,
(device_name ? NULL : &device_name), &device_os_version);
Expand Down Expand Up @@ -948,24 +948,28 @@ ws_status iwdp_on_static_request_for_http(ws_t ws, bool is_head,
return iwdp_send_http(ws, is_head, "403 Forbidden", ".txt", "Invalid path");
}
const char *fe_port = strchr(fe_host, ':');
fe_port = (fe_port && fe_port <= fe_path ? fe_port + 1 :
fe_port = (fe_port && fe_port <= fe_path ? fe_port :
NULL); // e.g. "http://foo.com/bar:x"
size_t fe_host_len = ((fe_port ? fe_port - 1 : fe_path) - fe_host);
size_t fe_host_len = ((fe_port ? fe_port : fe_path) - fe_host);
char *host = strndup(fe_host, fe_host_len);
int port = 80;

char *host_with_port;
char *port = NULL;
if (fe_port) {
char *sport = strndup(fe_port, fe_path - fe_port);
int port2 = strtol(fe_port, NULL, 0);
free(sport);
port = (port2 > 0 ? port2 : port);
port = strndup(fe_port, fe_path - fe_port);
}
if (asprintf(&host_with_port, "%s%s", host, port ? port : ":80") < 0) {
return self->on_error(self, "asprintf failed");
};
free(port);

int fs_fd = self->connect(self, host, port);
int fs_fd = self->connect(self, host_with_port);
if (fs_fd < 0) {
char *error;
if (asprintf(&error, "Unable to connect to %s:%d", host, port) < 0) {
if (asprintf(&error, "Unable to connect to %s", host_with_port) < 0) {
return self->on_error(self, "asprintf failed");
}
free(host_with_port);
free(host);
free(path);
ws_status ret = iwdp_send_http(ws, is_head, "500 Server Error", ".txt",
Expand All @@ -978,6 +982,7 @@ ws_status iwdp_on_static_request_for_http(ws_t ws, bool is_head,
ifs->fs_fd = fs_fd;
iws->ifs = ifs;
if (self->add_fd(self, fs_fd, ifs, false)) {
free(host_with_port);
free(host);
free(path);
return self->on_error(self, "Unable to add fd %d", fs_fd);
Expand All @@ -992,6 +997,7 @@ ws_status iwdp_on_static_request_for_http(ws_t ws, bool is_head,
(is_head ? "HEAD" : "GET"), path, host) < 0) {
return self->on_error(self, "asprintf failed");
}
free(host_with_port);
free(host);
free(path);
size_t length = strlen(data);
Expand Down Expand Up @@ -1435,6 +1441,7 @@ void iwdp_free(iwdp_t self) {
if (my) {
ht_free(my->device_id_to_iport);
free(my->frontend);
free(my->sim_wi_socket_addr);
memset(my, 0, sizeof(struct iwdp_private));
free(my);
}
Expand All @@ -1443,7 +1450,7 @@ void iwdp_free(iwdp_t self) {
}
}

iwdp_t iwdp_new(const char *frontend) {
iwdp_t iwdp_new(const char *frontend, const char *sim_wi_socket_addr) {
iwdp_t self = (iwdp_t)malloc(sizeof(struct iwdp_struct));
iwdp_private_t my = (iwdp_private_t)malloc(sizeof(struct iwdp_private));
if (!self || !my) {
Expand All @@ -1459,6 +1466,7 @@ iwdp_t iwdp_new(const char *frontend) {
self->on_error = iwdp_on_error;
self->private_state = my;
my->frontend = (frontend ? strdup(frontend) : NULL);
my->sim_wi_socket_addr = strdup(sim_wi_socket_addr);
my->device_id_to_iport = ht_new(HT_STRING_KEYS);
if (!my->device_id_to_iport) {
iwdp_free(self);
Expand Down
35 changes: 29 additions & 6 deletions src/ios_webkit_debug_proxy_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
struct iwdpm_struct {
char *config;
char *frontend;
char *sim_wi_socket_addr;
bool is_debug;

pc_t pc;
Expand Down Expand Up @@ -138,8 +139,8 @@ iwdp_status iwdpm_select_port(iwdp_t iwdp, const char *device_id,
int iwdpm_listen(iwdp_t iwdp, int port) {
return sm_listen(port);
}
int iwdpm_connect(iwdp_t iwdp, const char *hostname, int port) {
return sm_connect(hostname, port);
int iwdpm_connect(iwdp_t iwdp, const char *socket_addr) {
return sm_connect(socket_addr);
}
iwdp_status iwdpm_send(iwdp_t iwdp, int fd, const char *data, size_t length) {
sm_t sm = ((iwdpm_t)iwdp->state)->sm;
Expand Down Expand Up @@ -174,7 +175,7 @@ sm_status iwdpm_on_close(sm_t sm, int fd, void *value, bool is_server) {

void iwdpm_create_bridge(iwdpm_t self) {
sm_t sm = sm_new(4096);
iwdp_t iwdp = iwdp_new(self->frontend);
iwdp_t iwdp = iwdp_new(self->frontend, self->sim_wi_socket_addr);
if (!sm || !iwdp) {
sm_free(sm);
return;
Expand Down Expand Up @@ -207,6 +208,7 @@ void iwdpm_free(iwdpm_t self) {
sm_free(self->sm);
free(self->config);
free(self->frontend);
free(self->sim_wi_socket_addr);
memset(self, 0, sizeof(struct iwdpm_struct));
free(self);
}
Expand All @@ -228,6 +230,7 @@ int iwdpm_configure(iwdpm_t self, int argc, char **argv) {
{"config", 1, NULL, 'c'},
{"frontend", 1, NULL, 'f'},
{"no-frontend", 0, NULL, 'F'},
{"simulator-webinspector", 1, NULL, 's'},
{"debug", 0, NULL, 'd'},
{"help", 0, NULL, 'h'},
{"version", 0, NULL, 'V'},
Expand All @@ -236,13 +239,16 @@ int iwdpm_configure(iwdpm_t self, int argc, char **argv) {
const char *DEFAULT_CONFIG = "null:9221,:9222-9322";
const char *DEFAULT_FRONTEND =
"http://chrome-devtools-frontend.appspot.com/static/27.0.1453.93/devtools.html";
// The port 27753 is from `locate com.apple.webinspectord.plist`
const char *DEFAULT_SIM_WI_SOCKET_ADDR = "localhost:27753";

self->config = strdup(DEFAULT_CONFIG);
self->frontend = strdup(DEFAULT_FRONTEND);
self->sim_wi_socket_addr = strdup(DEFAULT_SIM_WI_SOCKET_ADDR);

int ret = 0;
while (!ret) {
int c = getopt_long(argc, argv, "hVu:c:f:Fd", longopts, (int *)0);
int c = getopt_long(argc, argv, "hVu:c:f:Fs:d", longopts, (int *)0);
if (c == -1) {
break;
}
Expand Down Expand Up @@ -284,6 +290,10 @@ int iwdpm_configure(iwdpm_t self, int argc, char **argv) {
free(self->config);
self->config = strdup(optarg);
break;
case 's':
free(self->sim_wi_socket_addr);
self->sim_wi_socket_addr = strdup(optarg);
break;
case 'f':
case 'F':
free(self->frontend);
Expand Down Expand Up @@ -327,7 +337,7 @@ int iwdpm_configure(iwdpm_t self, int argc, char **argv) {
"OPTIONS:\n"
"\n"
" -u UDID[:minPort-[maxPort]]\tTarget a specific device by its"
" 40-digit ID.\n"
" digital ID.\n"
" minPort defaults to 9222. maxPort defaults to minPort.\n"
" This is shorthand for the following \"-c\" option.\n"
"\n"
Expand Down Expand Up @@ -362,10 +372,23 @@ int iwdpm_configure(iwdpm_t self, int argc, char **argv) {
"\n"
" -F, --no-frontend\tDisable the DevTools frontend.\n"
"\n"
" -s, --simulator-webinspector\tSimulator web inspector socket\n"
" address. Provided value value needs to be in format\n"
" HOSTNAME:PORT or UNIX:PATH\n"
" Defaults to:\n"
" %s\n"
" Examples:\n"
" * TCP socket:\n"
" 192.168.0.20:27753\n"
" * Unix domain socket:\n"
" unix:/private/tmp/com.apple.launchd.2j5k1TMh6i/"
"com.apple.webinspectord_sim.socket\n"
"\n"
" -d, --debug\t\tEnable debug output.\n"
" -h, --help\t\tPrint this usage information.\n"
" -V, --version\t\tPrint version information and exit.\n"
"\n", (name ? name + 1 : argv[0]), PACKAGE_VERSION, DEFAULT_CONFIG, DEFAULT_FRONTEND);
"\n", (name ? name + 1 : argv[0]), PACKAGE_VERSION, DEFAULT_CONFIG,
DEFAULT_FRONTEND, DEFAULT_SIM_WI_SOCKET_ADDR);
}
return ret;
}
69 changes: 68 additions & 1 deletion src/socket_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#endif

#include "char_buffer.h"
Expand Down Expand Up @@ -124,7 +126,43 @@ int sm_listen(int port) {
return fd;
}

int sm_connect(const char *hostname, int port) {
#ifndef WIN32
int sm_connect_unix(const char *filename) {
struct sockaddr_un name;
int sfd = -1;
struct stat fst;

if (stat(filename, &fst) != 0 || !S_ISSOCK(fst.st_mode)) {
fprintf(stderr, "File '%s' is not a socket: %s\n", filename,
strerror(errno));
return -1;
}

if ((sfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("create socket failed");
return -1;
}

int opts = fcntl(sfd, F_GETFL);
if (fcntl(sfd, F_SETFL, (opts | O_NONBLOCK)) < 0) {
perror("failed to set socket to non-blocking");
return -1;
}

name.sun_family = AF_UNIX;
strncpy(name.sun_path, filename, sizeof(name.sun_path) - 1);

if (connect(sfd, (struct sockaddr*)&name, sizeof(name)) < 0) {
close(sfd);
perror("connect failed");
return -1;
}

return sfd;
}
#endif

int sm_connect_tcp(const char *hostname, int port) {
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
Expand Down Expand Up @@ -222,6 +260,35 @@ int sm_connect(const char *hostname, int port) {
return ret;
}

int sm_connect(const char *socket_addr) {
if (strncmp(socket_addr, "unix:", 5) == 0) {
#ifdef WIN32
return -1;
#else
return sm_connect_unix(socket_addr + 5);
#endif
} else {
const char *s_port = strrchr(socket_addr, ':');
int port = 0;

if (s_port) {
s_port += 1;
port = strtol(s_port, NULL, 0);
}

if (port <= 0) {
return -1;
}

size_t host_len = s_port - 1 - socket_addr;
char *host = strndup(socket_addr, host_len);

int ret = sm_connect_tcp(host, port);
free(host);
return ret;
}
}


sm_status sm_on_debug(sm_t self, const char *format, ...) {
if (self->is_debug && *self->is_debug) {
Expand Down