diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 1a4d988a23..ef8d7c1cb1 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -1025,52 +1025,6 @@ static esl_ssize_t handle_recv(esl_handle_t *handle, void *data, esl_size_t data return recv(handle->sock, data, datalen, 0); } -static int add_array(esl_event_t *event, const char *var, const char *val) -{ - char *data; - char **array; - int idx; - int max = 0; - int len; - const char *p; - int i; - - if (strlen(val) < 8) { - return -1; - } - - p = val + 7; - - while((p = strstr(p, "::"))) { - max++; - p += 2; - } - - if (!max) { - return -2; - } - - data = strdup(val + 7); - - len = (sizeof(char *) * max) + 1; - - array = malloc(len); - memset(array, 0, len); - - idx = esl_separate_string_string(data, "::", array, max); - - for(i = 0; i < max; i++) { - esl_event_add_header_string(event, ESL_STACK_PUSH, var, array[i]); - } - - free(array); - free(data); - - return 0; -} - - - ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event) { char *c; @@ -1135,7 +1089,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ esl_url_decode(hval); esl_log(ESL_LOG_DEBUG, "RECV HEADER [%s] = [%s]\n", hname, hval); if (!strncmp(hval, "ARRAY::", 7)) { - add_array(revent, hname, hval); + esl_event_add_array(revent, hname, hval); } else { esl_event_add_header_string(revent, ESL_STACK_BOTTOM, hname, hval); } @@ -1269,7 +1223,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ } if (!strncmp(hval, "ARRAY::", 7)) { - add_array(handle->last_ievent, hname, hval); + esl_event_add_array(handle->last_ievent, hname, hval); } else { esl_event_add_header_string(handle->last_ievent, ESL_STACK_BOTTOM, hname, hval); } diff --git a/libs/esl/src/esl_event.c b/libs/esl/src/esl_event.c index 75d9cad8c9..e1b2663995 100644 --- a/libs/esl/src/esl_event.c +++ b/libs/esl/src/esl_event.c @@ -338,30 +338,9 @@ ESL_DECLARE(esl_status_t) esl_event_del_header_val(esl_event_t *event, const cha return status; } -static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t stack, const char *header_name, char *data) +static esl_event_header_t *new_header(const char *header_name) { - esl_event_header_t *header = NULL; - esl_ssize_t hlen = -1; - int exists = 0; - - if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT) || esl_test_flag(event, ESL_EF_CONTAINS_ARRAYS)) { - - if ((header = esl_event_get_header_ptr(event, header_name))) { - - if (!(stack & ESL_STACK_PUSH) && !(stack & ESL_STACK_UNSHIFT) && header->idx) { - stack |= ESL_STACK_PUSH; - } - - if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) { - exists++; - stack &= ~(ESL_STACK_TOP | ESL_STACK_BOTTOM); - } else { - header = NULL; - } - } - } - - if (!header) { + esl_event_header_t *header; #ifdef ESL_EVENT_RECYCLE void *pop; @@ -373,16 +352,144 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st esl_assert(header); #ifdef ESL_EVENT_RECYCLE } -#endif - +#endif + memset(header, 0, sizeof(*header)); + header->name = DUP(header_name); + + return header; + +} + +ESL_DECLARE(int) esl_event_add_array(esl_event_t *event, const char *var, const char *val) +{ + char *data; + char **array; + int idx; + int max = 0; + int len; + const char *p; + int i; + + if (strlen(val) < 8) { + return -1; + } + + p = val + 7; + + max = 1; + + while((p = strstr(p, "|:"))) { + max++; + p += 2; + } + + if (!max) { + return -2; + } + + data = strdup(val + 7); + + len = (sizeof(char *) * max) + 1; + array = malloc(len); + memset(array, 0, len); + + idx = esl_separate_string_string(data, "|:", array, max); + + for(i = 0; i < max; i++) { + esl_event_add_header_string(event, ESL_STACK_PUSH, var, array[i]); + } + + free(array); + free(data); + + return 0; +} + +static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t stack, const char *header_name, char *data) +{ + esl_event_header_t *header = NULL; + esl_ssize_t hlen = -1; + int exists = 0, fly = 0; + char *index_ptr; + int index = 0; + char *real_header_name = NULL; + + if ((index_ptr = strchr(header_name, '['))) { + index_ptr++; + index = atoi(index_ptr); + real_header_name = DUP(header_name); + if ((index_ptr = strchr(real_header_name, '['))) { + *index_ptr++ = '\0'; + } + header_name = real_header_name; + } + + if (index_ptr || (stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) { + + if (!(header = esl_event_get_header_ptr(event, header_name)) && index_ptr) { + + header = new_header(header_name); + + if (esl_test_flag(event, ESL_EF_UNIQ_HEADERS)) { + esl_event_del_header(event, header_name); + } + + fly++; + } + + if ((header = esl_event_get_header_ptr(event, header_name))) { + + if (index_ptr) { + if (index > -1 && index <= 4000) { + if (index < header->idx) { + FREE(header->array[index]); + header->array[index] = DUP(data); + } else { + int i; + char **m; + + m = realloc(header->array, sizeof(char *) * (index + 1)); + esl_assert(m); + header->array = m; + for (i = header->idx; i < index; i++) { + m[i] = DUP(""); + } + m[index] = DUP(data); + header->idx = index + 1; + if (!fly) { + exists = 1; + } + + goto redraw; + } + } + goto end; + } else { + if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) { + exists++; + stack &= ~(ESL_STACK_TOP | ESL_STACK_BOTTOM); + } else { + header = NULL; + } + } + } + } + + + if (!header) { if (esl_test_flag(event, ESL_EF_UNIQ_HEADERS)) { esl_event_del_header(event, header_name); } - memset(header, 0, sizeof(*header)); + if (strstr(data, "ARRAY::")) { + esl_event_add_array(event, header_name, data); + FREE(data); + goto end; + } - header->name = DUP(header_name); + + header = new_header(header_name); } if ((stack & ESL_STACK_PUSH) || (stack & ESL_STACK_UNSHIFT)) { @@ -391,8 +498,6 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st char *hv; int i = 0, j = 0; - esl_set_flag(event, ESL_EF_CONTAINS_ARRAYS); - if (header->value && !header->idx) { m = malloc(sizeof(char *)); esl_assert(m); @@ -419,6 +524,8 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st header->idx++; header->array = m; + redraw: + len = 0; for(j = 0; j < header->idx; j++) { len += strlen(header->array[j]) + 2; } @@ -428,9 +535,10 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st hv = realloc(header->value, len); esl_assert(hv); header->value = hv; + esl_snprintf(header->value, len, "ARRAY::"); for(j = 0; j < header->idx; j++) { - esl_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "::", header->array[j]); + esl_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "|:", header->array[j]); } } @@ -458,6 +566,10 @@ static esl_status_t esl_event_base_add_header(esl_event_t *event, esl_stack_t st } } + end: + + esl_safe_free(real_header_name); + return ESL_SUCCESS; } diff --git a/libs/esl/src/include/esl_event.h b/libs/esl/src/include/esl_event.h index 10af7264b9..d6be0470e8 100644 --- a/libs/esl/src/include/esl_event.h +++ b/libs/esl/src/include/esl_event.h @@ -180,8 +180,7 @@ struct esl_event { }; typedef enum { - ESL_EF_UNIQ_HEADERS = (1 << 0), - ESL_EF_CONTAINS_ARRAYS = (1 << 1) + ESL_EF_UNIQ_HEADERS = (1 << 0) } esl_event_flag_t; @@ -234,6 +233,8 @@ ESL_DECLARE(char *)esl_event_get_body(esl_event_t *event); ESL_DECLARE(esl_status_t) esl_event_add_header(esl_event_t *event, esl_stack_t stack, const char *header_name, const char *fmt, ...); //PRINTF_FUNCTION(4, 5); +ESL_DECLARE(int) esl_event_add_array(esl_event_t *event, const char *var, const char *val); + /*! \brief Add a string header to an event \param event the event to add the header to diff --git a/src/include/switch_event.h b/src/include/switch_event.h index 4c5a3be931..c6b1d64c35 100644 --- a/src/include/switch_event.h +++ b/src/include/switch_event.h @@ -103,8 +103,7 @@ struct switch_event { }; typedef enum { - EF_UNIQ_HEADERS = (1 << 0), - EF_CONTAINS_ARRAYS = (1 << 1), + EF_UNIQ_HEADERS = (1 << 0) } switch_event_flag_t; @@ -192,7 +191,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_add_header_string(switch_event_t *e SWITCH_DECLARE(switch_status_t) switch_event_del_header_val(switch_event_t *event, const char *header_name, const char *val); #define switch_event_del_header(_e, _h) switch_event_del_header_val(_e, _h, NULL) - +SWITCH_DECLARE(int) switch_event_add_array(switch_event_t *event, const char *var, const char *val); /*! \brief Destroy an event \param event pointer to the pointer to event to destroy diff --git a/src/switch_event.c b/src/switch_event.c index c414107664..5bff7a9400 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -829,6 +829,74 @@ SWITCH_DECLARE(switch_status_t) switch_event_del_header_val(switch_event_t *even return status; } +static switch_event_header_t *new_header(const char *header_name) +{ + switch_event_header_t *header; + +#ifdef SWITCH_EVENT_RECYCLE + void *pop; + if (switch_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { + header = (switch_event_header_t *) pop; + } else { +#endif + header = ALLOC(sizeof(*header)); + switch_assert(header); +#ifdef SWITCH_EVENT_RECYCLE + } +#endif + + memset(header, 0, sizeof(*header)); + header->name = DUP(header_name); + + return header; + +} + +SWITCH_DECLARE(int) switch_event_add_array(switch_event_t *event, const char *var, const char *val) +{ + char *data; + char **array; + int idx; + int max = 0; + int len; + const char *p; + int i; + + if (strlen(val) < 8) { + return -1; + } + + p = val + 7; + + max = 1; + + while((p = strstr(p, "|:"))) { + max++; + p += 2; + } + + if (!max) { + return -2; + } + + data = strdup(val + 7); + + len = (sizeof(char *) * max) + 1; + array = malloc(len); + memset(array, 0, len); + + idx = switch_separate_string_string(data, "|:", array, max); + + for(i = 0; i < max; i++) { + switch_event_add_header_string(event, SWITCH_STACK_PUSH, var, array[i]); + } + + free(array); + free(data); + + return 0; +} + static switch_status_t switch_event_base_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, char *data) { switch_event_header_t *header = NULL; @@ -848,19 +916,19 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc header_name = real_header_name; } - if (index_ptr || (stack & SWITCH_STACK_PUSH) || (stack & SWITCH_STACK_UNSHIFT) || switch_test_flag(event, EF_CONTAINS_ARRAYS)) { + if (index_ptr || (stack & SWITCH_STACK_PUSH) || (stack & SWITCH_STACK_UNSHIFT)) { if (!(header = switch_event_get_header_ptr(event, header_name)) && index_ptr) { - header = ALLOC(sizeof(*header)); - switch_assert(header); - memset(header, 0, sizeof(*header)); - header->name = DUP(header_name); + + header = new_header(header_name); + if (switch_test_flag(event, EF_UNIQ_HEADERS)) { switch_event_del_header(event, header_name); } + fly++; } - + if ((header = switch_event_get_header_ptr(event, header_name))) { if (index_ptr) { @@ -889,11 +957,6 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc } goto end; } else { - - if (!(stack & SWITCH_STACK_PUSH) && !(stack & SWITCH_STACK_UNSHIFT) && header->idx) { - stack |= SWITCH_STACK_PUSH; - } - if ((stack & SWITCH_STACK_PUSH) || (stack & SWITCH_STACK_UNSHIFT)) { exists++; stack &= ~(SWITCH_STACK_TOP | SWITCH_STACK_BOTTOM); @@ -904,28 +967,20 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc } } + if (!header) { - -#ifdef SWITCH_EVENT_RECYCLE - void *pop; - if (switch_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { - header = (switch_event_header_t *) pop; - } else { -#endif - header = ALLOC(sizeof(*header)); - switch_assert(header); -#ifdef SWITCH_EVENT_RECYCLE - } -#endif - - if (switch_test_flag(event, EF_UNIQ_HEADERS)) { switch_event_del_header(event, header_name); } - memset(header, 0, sizeof(*header)); + if (strstr(data, "ARRAY::")) { + switch_event_add_array(event, header_name, data); + FREE(data); + goto end; + } - header->name = DUP(header_name); + + header = new_header(header_name); } if ((stack & SWITCH_STACK_PUSH) || (stack & SWITCH_STACK_UNSHIFT)) { @@ -934,8 +989,6 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc char *hv; int i = 0, j = 0; - switch_set_flag(event, EF_CONTAINS_ARRAYS); - if (header->value && !header->idx) { m = malloc(sizeof(char *)); switch_assert(m); @@ -976,7 +1029,7 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc switch_snprintf(header->value, len, "ARRAY::"); for(j = 0; j < header->idx; j++) { - switch_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "::", header->array[j]); + switch_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "|:", header->array[j]); } }