diff --git a/examples/wi_client.c b/examples/wi_client.c index 15bf1ab0..0d404372 100644 --- a/examples/wi_client.c +++ b/examples/wi_client.c @@ -110,7 +110,7 @@ int main(int argc, char **argv) { // create inspector my_wi_t my_wi = (my_wi_t)malloc(sizeof(struct my_wi_struct)); - wi_t wi = wi_new(false); + wi_t wi = wi_new(false, false); memset(my_wi, 0, sizeof(struct my_wi_struct)); my_wi->device_id = device_id2; my_wi->fd = fd; diff --git a/include/ios-webkit-debug-proxy/webinspector.h b/include/ios-webkit-debug-proxy/webinspector.h index cdcaf87b..8c66f4e4 100644 --- a/include/ios-webkit-debug-proxy/webinspector.h +++ b/include/ios-webkit-debug-proxy/webinspector.h @@ -38,7 +38,7 @@ int wi_connect(const char *device_id, char **to_device_id, struct wi_struct; typedef struct wi_struct *wi_t; -wi_t wi_new(bool partials_supported); +wi_t wi_new(bool is_sim, bool partials_supported); void wi_free(wi_t self); struct wi_private; diff --git a/src/ios_webkit_debug_proxy.c b/src/ios_webkit_debug_proxy.c index 284b353e..058ab723 100644 --- a/src/ios_webkit_debug_proxy.c +++ b/src/ios_webkit_debug_proxy.c @@ -130,7 +130,7 @@ struct iwdp_iwi_struct { ht_t page_num_to_ipage; }; -iwdp_iwi_t iwdp_iwi_new(bool partials_supported, bool *is_debug); +iwdp_iwi_t iwdp_iwi_new(bool is_sim, bool partials_supported, bool *is_debug); void iwdp_iwi_free(iwdp_iwi_t iwi); struct iwdp_ifs_struct; @@ -434,7 +434,7 @@ dl_status iwdp_on_attach(dl_t dl, const char *device_id, int device_num) { } iport->device_name = (device_name ? device_name : strdup(device_id)); iport->device_os_version = device_os_version; - iwdp_iwi_t iwi = iwdp_iwi_new(!is_sim && device_os_version < 0xb0000, + iwdp_iwi_t iwi = iwdp_iwi_new(is_sim, !is_sim && device_os_version < 0xb0000, self->is_debug); iwi->iport = iport; iport->iwi = iwi; @@ -1683,7 +1683,7 @@ void iwdp_iwi_free(iwdp_iwi_t iwi) { } } -iwdp_iwi_t iwdp_iwi_new(bool partials_supported, bool *is_debug) { +iwdp_iwi_t iwdp_iwi_new(bool is_sim, bool partials_supported, bool *is_debug) { iwdp_iwi_t iwi = (iwdp_iwi_t)malloc(sizeof(struct iwdp_iwi_struct)); if (!iwi) { return NULL; @@ -1693,7 +1693,7 @@ iwdp_iwi_t iwdp_iwi_new(bool partials_supported, bool *is_debug) { iwi->app_id_to_true = ht_new(HT_STRING_KEYS); iwi->page_num_to_ipage = ht_new(HT_INT_KEYS); rpc_t rpc = rpc_new(); - wi_t wi = wi_new(partials_supported); + wi_t wi = wi_new(is_sim, partials_supported); if (!rpc || !wi || !iwi->page_num_to_ipage || !iwi->app_id_to_true) { iwdp_iwi_free(iwi); return NULL; diff --git a/src/webinspector.c b/src/webinspector.c index aff7ec29..f0301a54 100644 --- a/src/webinspector.c +++ b/src/webinspector.c @@ -43,6 +43,7 @@ #define MAX_BODY_LENGTH 1<<26 struct wi_private { + bool is_sim; bool partials_supported; cb_t in; cb_t partial; @@ -231,6 +232,31 @@ wi_status wi_on_debug(wi_t self, const char *message, return WI_SUCCESS; } +wi_status wi_send(wi_t self, const char *data, size_t data_len) { + size_t length = data_len + 4; + char *out_head = (char*)malloc(length); + if (!out_head) { + return WI_ERROR; + } + char *out_tail = out_head; + + // write big-endian int + *out_tail++ = ((data_len >> 24) & 0xFF); + *out_tail++ = ((data_len >> 16) & 0xFF); + *out_tail++ = ((data_len >> 8) & 0xFF); + *out_tail++ = (data_len & 0xFF); + + if (data) { + memcpy(out_tail, data, data_len); + } + + wi_on_debug(self, "wi.send_packet", out_head, length); + wi_status ret = self->send_packet(self, out_head, length); + + free(out_head); + return ret; +} + /* WIRFinalMessageKey __selector @@ -241,57 +267,37 @@ wi_status wi_send_plist(wi_t self, plist_t rpc_dict) { char *rpc_bin = NULL; uint32_t rpc_len = 0; plist_to_bin(rpc_dict, &rpc_bin, &rpc_len); - // if our message is <8k, we'll send a single final_msg, - // otherwise we'll send <8k partial_msg "chunks" then a final_msg "chunk" + wi_status ret = WI_ERROR; + if (!my->partials_supported) { + ret = wi_send(self, rpc_bin, rpc_len); + free(rpc_bin); + if (!my->is_sim) { + // webinspectord may not ack the message with relatively big payloads + // sending an empty payload to prompt the processing of the last message + wi_send(self, NULL, 0); + } + return ret; + } + uint32_t i; for (i = 0; ; i += MAX_RPC_LEN) { - bool is_partial = false; + bool is_partial = (rpc_len - i > MAX_RPC_LEN); char *data = NULL; uint32_t data_len = 0; - if (!my->partials_supported) { - data = rpc_bin; - data_len = rpc_len; - rpc_bin = NULL; - } else { - is_partial = (rpc_len - i > MAX_RPC_LEN); - plist_t wi_dict = plist_new_dict(); - plist_t wi_rpc = plist_new_data(rpc_bin + i, - (is_partial ? MAX_RPC_LEN : rpc_len - i)); - plist_dict_set_item(wi_dict, - (is_partial ? "WIRPartialMessageKey" : "WIRFinalMessageKey"), wi_rpc); - plist_to_bin(wi_dict, &data, &data_len); - plist_free(wi_dict); - wi_dict = NULL; - wi_rpc = NULL; // freed by wi_dict - if (!data) { - break; - } - } - - size_t length = data_len + 4; - char *out_head = (char*)malloc(length * sizeof(char)); - if (!out_head) { - if (my->partials_supported) { - free(data); - } + plist_t wi_dict = plist_new_dict(); + plist_t wi_rpc = plist_new_data(rpc_bin + i, + (is_partial ? MAX_RPC_LEN : rpc_len - i)); + plist_dict_set_item(wi_dict, + (is_partial ? "WIRPartialMessageKey" : "WIRFinalMessageKey"), wi_rpc); + plist_to_bin(wi_dict, &data, &data_len); + plist_free(wi_dict); + if (!data) { break; } - char *out_tail = out_head; - // write big-endian int - *out_tail++ = ((data_len >> 24) & 0xFF); - *out_tail++ = ((data_len >> 16) & 0xFF); - *out_tail++ = ((data_len >> 8) & 0xFF); - *out_tail++ = (data_len & 0xFF); - - // write data - memcpy(out_tail, data, data_len); + wi_status not_sent = wi_send(self, data, data_len); free(data); - - wi_on_debug(self, "wi.send_packet", out_head, length); - wi_status not_sent = self->send_packet(self, out_head, length); - free(out_head); if (not_sent) { break; } @@ -509,7 +515,7 @@ void wi_free(wi_t self) { free(self); } } -wi_t wi_new(bool partials_supported) { +wi_t wi_new(bool is_sim, bool partials_supported) { wi_t self = (wi_t)malloc(sizeof(struct wi_struct)); if (!self) { return NULL; @@ -524,6 +530,7 @@ wi_t wi_new(bool partials_supported) { wi_free(self); return NULL; } + self->private_state->is_sim = is_sim; self->private_state->partials_supported = partials_supported; return self; }