From af8247831154ca4b3e9813b3ba959e2a8d090c2d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Jan 2009 19:31:45 +0000 Subject: [PATCH] indent pass MODAPP-202 git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11335 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/applications/mod_http/arraylist.c | 92 +- src/mod/applications/mod_http/arraylist.h | 29 +- src/mod/applications/mod_http/debug.c | 57 +- src/mod/applications/mod_http/http_req.c | 1075 +++++++++-------- src/mod/applications/mod_http/http_req.h | 80 +- src/mod/applications/mod_http/json.h | 1 - src/mod/applications/mod_http/json_object.c | 601 ++++----- src/mod/applications/mod_http/json_object.h | 55 +- .../mod_http/json_object_private.h | 37 +- src/mod/applications/mod_http/json_tokener.c | 820 ++++++------- src/mod/applications/mod_http/json_tokener.h | 109 +- src/mod/applications/mod_http/json_util.c | 106 +- src/mod/applications/mod_http/json_util.h | 2 +- src/mod/applications/mod_http/linkhash.c | 87 +- src/mod/applications/mod_http/linkhash.h | 21 +- src/mod/applications/mod_http/mod_http.c | 540 ++++----- src/mod/applications/mod_http/printbuf.c | 131 +- src/mod/applications/mod_http/printbuf.h | 21 +- src/mod/applications/mod_http/url_encoding.c | 143 +-- src/mod/applications/mod_http/url_encoding.h | 1 - 20 files changed, 2029 insertions(+), 1979 deletions(-) diff --git a/src/mod/applications/mod_http/arraylist.c b/src/mod/applications/mod_http/arraylist.c index dbd075d80d..1daca48790 100644 --- a/src/mod/applications/mod_http/arraylist.c +++ b/src/mod/applications/mod_http/arraylist.c @@ -23,71 +23,73 @@ #include "bits.h" #include "arraylist.h" -struct array_list* -array_list_new(array_list_free_fn *free_fn) +struct array_list *array_list_new(array_list_free_fn * free_fn) { - struct array_list *this; + struct array_list *this; - if(!(this = calloc(1, sizeof(struct array_list)))) return NULL; - this->size = ARRAY_LIST_DEFAULT_SIZE; - this->length = 0; - this->free_fn = free_fn; - if(!(this->array = calloc(sizeof(void*), this->size))) { - free(this); - return NULL; - } - return this; + if (!(this = calloc(1, sizeof(struct array_list)))) + return NULL; + this->size = ARRAY_LIST_DEFAULT_SIZE; + this->length = 0; + this->free_fn = free_fn; + if (!(this->array = calloc(sizeof(void *), this->size))) { + free(this); + return NULL; + } + return this; } -extern void -array_list_free(struct array_list *this) +extern void array_list_free(struct array_list *this) { - int i; - for(i = 0; i < this->length; i++) - if(this->array[i]) this->free_fn(this->array[i]); - free(this->array); - free(this); + int i; + for (i = 0; i < this->length; i++) + if (this->array[i]) + this->free_fn(this->array[i]); + free(this->array); + free(this); } -void* -array_list_get_idx(struct array_list *this, int i) +void *array_list_get_idx(struct array_list *this, int i) { - if(i >= this->length) return NULL; - return this->array[i]; + if (i >= this->length) + return NULL; + return this->array[i]; } static int array_list_expand_internal(struct array_list *this, int max) { - void *t; - int new_size; + void *t; + int new_size; - if(max < this->size) return 0; - new_size = max(this->size << 1, max); - if(!(t = realloc(this->array, new_size*sizeof(void*)))) return -1; - this->array = t; - (void)memset(this->array + this->size, 0, (new_size-this->size)*sizeof(void*)); - this->size = new_size; - return 0; + if (max < this->size) + return 0; + new_size = max(this->size << 1, max); + if (!(t = realloc(this->array, new_size * sizeof(void *)))) + return -1; + this->array = t; + (void) memset(this->array + this->size, 0, (new_size - this->size) * sizeof(void *)); + this->size = new_size; + return 0; } -int -array_list_put_idx(struct array_list *this, int idx, void *data) +int array_list_put_idx(struct array_list *this, int idx, void *data) { - if(array_list_expand_internal(this, idx)) return -1; - if(this->array[idx]) this->free_fn(this->array[idx]); - this->array[idx] = data; - if(this->length <= idx) this->length = idx + 1; - return 0; + if (array_list_expand_internal(this, idx)) + return -1; + if (this->array[idx]) + this->free_fn(this->array[idx]); + this->array[idx] = data; + if (this->length <= idx) + this->length = idx + 1; + return 0; } -int -array_list_add(struct array_list *this, void *data) +int array_list_add(struct array_list *this, void *data) { - return array_list_put_idx(this, this->length, data); + return array_list_put_idx(this, this->length, data); } -int -array_list_length(struct array_list *this) +int array_list_length(struct array_list *this) { - return this->length; + return this->length; } diff --git a/src/mod/applications/mod_http/arraylist.h b/src/mod/applications/mod_http/arraylist.h index 2948e042a9..24de666c0c 100644 --- a/src/mod/applications/mod_http/arraylist.h +++ b/src/mod/applications/mod_http/arraylist.h @@ -16,30 +16,23 @@ typedef void (array_list_free_fn) (void *data); -struct array_list -{ - void **array; - int length; - int size; - array_list_free_fn *free_fn; +struct array_list { + void **array; + int length; + int size; + array_list_free_fn *free_fn; }; -extern struct array_list* -array_list_new(array_list_free_fn *free_fn); +extern struct array_list *array_list_new(array_list_free_fn * free_fn); -extern void -array_list_free(struct array_list *al); +extern void array_list_free(struct array_list *al); -extern void* -array_list_get_idx(struct array_list *al, int i); +extern void *array_list_get_idx(struct array_list *al, int i); -extern int -array_list_put_idx(struct array_list *al, int i, void *data); +extern int array_list_put_idx(struct array_list *al, int i, void *data); -extern int -array_list_add(struct array_list *al, void *data); +extern int array_list_add(struct array_list *al, void *data); -extern int -array_list_length(struct array_list *al); +extern int array_list_length(struct array_list *al); #endif diff --git a/src/mod/applications/mod_http/debug.c b/src/mod/applications/mod_http/debug.c index eaa6fca33c..5660e70097 100644 --- a/src/mod/applications/mod_http/debug.c +++ b/src/mod/applications/mod_http/debug.c @@ -33,48 +33,55 @@ static int _syslog = 0; static int _debug = 0; -void mc_set_debug(int debug) { _debug = debug; } -int mc_get_debug() { return _debug; } +void mc_set_debug(int debug) +{ + _debug = debug; +} + +int mc_get_debug() +{ + return _debug; +} extern void mc_set_syslog(int syslog) { - _syslog = syslog; + _syslog = syslog; } void mc_abort(const char *msg, ...) { - va_list ap; - va_start(ap, msg); + va_list ap; + va_start(ap, msg); #if HAVE_VSYSLOG - if(_syslog) { - vsyslog(LOG_ERR, msg, ap); - } else + if (_syslog) { + vsyslog(LOG_ERR, msg, ap); + } else #endif - vprintf(msg, ap); - exit(1); + vprintf(msg, ap); + exit(1); } void mc_debug(const char *msg, ...) { - va_list ap; - if(_debug) { - va_start(ap, msg); + va_list ap; + if (_debug) { + va_start(ap, msg); #if HAVE_VSYSLOG - if(_syslog) { - vsyslog(LOG_DEBUG, msg, ap); - } else + if (_syslog) { + vsyslog(LOG_DEBUG, msg, ap); + } else #endif - vprintf(msg, ap); - } + vprintf(msg, ap); + } } void mc_error(const char *msg, ...) { - va_list ap; - va_start(ap, msg); + va_list ap; + va_start(ap, msg); #if HAVE_VSYSLOG - if(_syslog) { + if (_syslog) { vsyslog(LOG_ERR, msg, ap); } else #endif @@ -83,12 +90,12 @@ void mc_error(const char *msg, ...) void mc_info(const char *msg, ...) { - va_list ap; - va_start(ap, msg); + va_list ap; + va_start(ap, msg); #if HAVE_VSYSLOG - if(_syslog) { + if (_syslog) { vsyslog(LOG_INFO, msg, ap); - } else + } else #endif vfprintf(stderr, msg, ap); } diff --git a/src/mod/applications/mod_http/http_req.c b/src/mod/applications/mod_http/http_req.c index 70647dad39..23d572565e 100644 --- a/src/mod/applications/mod_http/http_req.c +++ b/src/mod/applications/mod_http/http_req.c @@ -34,646 +34,695 @@ extern int isblank(int); */ /* NOTE: v = version, header = h, status = s, newline = n, phrase = p */ -static accept_state_t state_start(char c, state_machine_t *sm); -static accept_state_t state_shp (char c, state_machine_t *sm); -static accept_state_t state_n (char c, state_machine_t *sm); -static accept_state_t state_vhp_A(char c, state_machine_t *sm); -static accept_state_t state_vhp_B(char c, state_machine_t *sm); -static accept_state_t state_vhp_C(char c, state_machine_t *sm); -static accept_state_t state_vhp_D(char c, state_machine_t *sm); -static accept_state_t state_vhp_E(char c, state_machine_t *sm); -static accept_state_t state_vhp_F(char c, state_machine_t *sm); -static accept_state_t state_vhp_G(char c, state_machine_t *sm); -static accept_state_t state_vhp_H(char c, state_machine_t *sm); -static accept_state_t state_hp_A (char c, state_machine_t *sm); -static accept_state_t state_hp_B (char c, state_machine_t *sm); -static accept_state_t state_p (char c, state_machine_t *sm); -static accept_state_t state_error(char c, state_machine_t *sm); +static accept_state_t state_start(char c, state_machine_t * sm); +static accept_state_t state_shp(char c, state_machine_t * sm); +static accept_state_t state_n(char c, state_machine_t * sm); +static accept_state_t state_vhp_A(char c, state_machine_t * sm); +static accept_state_t state_vhp_B(char c, state_machine_t * sm); +static accept_state_t state_vhp_C(char c, state_machine_t * sm); +static accept_state_t state_vhp_D(char c, state_machine_t * sm); +static accept_state_t state_vhp_E(char c, state_machine_t * sm); +static accept_state_t state_vhp_F(char c, state_machine_t * sm); +static accept_state_t state_vhp_G(char c, state_machine_t * sm); +static accept_state_t state_vhp_H(char c, state_machine_t * sm); +static accept_state_t state_hp_A(char c, state_machine_t * sm); +static accept_state_t state_hp_B(char c, state_machine_t * sm); +static accept_state_t state_p(char c, state_machine_t * sm); +static accept_state_t state_error(char c, state_machine_t * sm); static int read_all(int s, char *buf, size_t len); #ifdef DEBUG int main(int argc, char *argv[]) { - http_response_t response; - http_request_t request; - int ret; - int i; + http_response_t response; + http_request_t request; + int ret; + int i; - if(argc != 2) return EXIT_FAILURE; + if (argc != 2) + return EXIT_FAILURE; - request.method = GET; - request.version = DEFAULT_HTTP_VERSION; - request.url = argv[1]; - request.header_len = 0; - request.body_len = 0; + request.method = GET; + request.version = DEFAULT_HTTP_VERSION; + request.url = argv[1]; + request.header_len = 0; + request.body_len = 0; - ret = http_req(&request, &response); - if(ret == ERROR) return EXIT_FAILURE; - - printf("Version : %s\n", response.version); - printf("Status Code : %d\n", response.status_code); - printf("Phrase : %s\n", response.phrase); - - for(i = 0; i < response.header_len; i++){ - printf( - "Header : key = [%s] value = [%s]\n", - response.headers[i].field_name, response.headers[i].value - ); - } + ret = http_req(&request, &response); + if (ret == ERROR) + return EXIT_FAILURE; - fflush(stdout); - write(STDOUT_FILENO, response.body, response.body_len); - printf("\n"); + printf("Version : %s\n", response.version); + printf("Status Code : %d\n", response.status_code); + printf("Phrase : %s\n", response.phrase); - free_http_response(&response); + for (i = 0; i < response.header_len; i++) { + printf("Header : key = [%s] value = [%s]\n", response.headers[i].field_name, response.headers[i].value); + } - return EXIT_SUCCESS; + fflush(stdout); + write(STDOUT_FILENO, response.body, response.body_len); + printf("\n"); + + free_http_response(&response); + + return EXIT_SUCCESS; } #endif -int http_req(http_request_t *req, http_response_t *res) +int http_req(http_request_t * req, http_response_t * res) { - uint32_t addr; - int s; - int ret; - uint16_t port = 0; - size_t len; - struct sockaddr_in sck; - struct hostent *hst; - char *hostname; - char *method; - char *buf; - int buf_len; - ssize_t i; - int j; - int l; - int m; - int p; - int q = 0; - char f = HTTP_FALSE; - char port_s[MAX_PORT_LEN]; - sighandler_t sig; - struct timeval tv; + uint32_t addr; + int s; + int ret; + uint16_t port = 0; + size_t len; + struct sockaddr_in sck; + struct hostent *hst; + char *hostname; + char *method; + char *buf; + int buf_len; + ssize_t i; + int j; + int l; + int m; + int p; + int q = 0; + char f = HTTP_FALSE; + char port_s[MAX_PORT_LEN]; + sighandler_t sig; + struct timeval tv; - tv.tv_sec = 1; - tv.tv_usec = 0; + tv.tv_sec = 1; + tv.tv_usec = 0; - (void)memset(&sck, 0, sizeof(sck)); + (void) memset(&sck, 0, sizeof(sck)); - sig = signal(SIGPIPE, SIG_IGN); - if(sig == SIG_ERR){ - fprintf(stderr, "Cannot ignore SIGPIPE signal\n"); - return ERROR; - } - - s = socket(PF_INET, SOCK_STREAM, 0); - if(s == ERROR){ - perror("Could not create socket"); - return ERROR; - } + sig = signal(SIGPIPE, SIG_IGN); + if (sig == SIG_ERR) { + fprintf(stderr, "Cannot ignore SIGPIPE signal\n"); + return ERROR; + } - (void)setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); - (void)setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + s = socket(PF_INET, SOCK_STREAM, 0); + if (s == ERROR) { + perror("Could not create socket"); + return ERROR; + } - len = strlen(req->url); - hostname = (char *)malloc(len * sizeof(char) + 1); - if(hostname == NULL){ - perror("Could not allocate memory for hostname"); - close(s); - return ERROR; - } - - EMPTY_STRING(hostname); + (void) setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + (void) setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); - l = strlen(req->url) + 1; - m = strlen("http://"); - for(p = 0, j = m; j < l; j++){ - if(req->url[j] == ':'){ - strncpy(hostname, req->url + m, j - m); - hostname[j - m] = '\0'; - f = HTTP_TRUE; - p = j; - continue; - } + len = strlen(req->url); + hostname = (char *) malloc(len * sizeof(char) + 1); + if (hostname == NULL) { + perror("Could not allocate memory for hostname"); + close(s); + return ERROR; + } - if((req->url[j] == '/' || req->url[j] == '\0') && f == HTTP_TRUE){ - if((j - p) < MAX_PORT_LEN){ - strncpy(port_s, req->url + p + 1, j - p); - port_s[j - p] = '\0'; - port = (uint16_t)atoi(port_s); - }else port = 0; - q = j; - break; - } + EMPTY_STRING(hostname); - if((req->url[j] == '/' || req->url[j] == '\0') && f == HTTP_FALSE){ - strncpy(hostname, req->url + m, j - m); - hostname[j - m] = '\0'; - port = DEFAULT_HTTP_PORT; - q = j; - break; - } - } + l = strlen(req->url) + 1; + m = strlen("http://"); + for (p = 0, j = m; j < l; j++) { + if (req->url[j] == ':') { + strncpy(hostname, req->url + m, j - m); + hostname[j - m] = '\0'; + f = HTTP_TRUE; + p = j; + continue; + } - if(port == 0 || hostname[0] == '\0'){ - fprintf(stderr, "Invalid URL\n"); - close(s); - free(hostname); - return ERROR; - } + if ((req->url[j] == '/' || req->url[j] == '\0') && f == HTTP_TRUE) { + if ((j - p) < MAX_PORT_LEN) { + strncpy(port_s, req->url + p + 1, j - p); + port_s[j - p] = '\0'; + port = (uint16_t) atoi(port_s); + } else + port = 0; + q = j; + break; + } - l = strlen(hostname); - for(j = 0; j < l; j++){ - if(hostname[j] == '/'){ - hostname[j] = '\0'; - break; - } - } + if ((req->url[j] == '/' || req->url[j] == '\0') && f == HTTP_FALSE) { + strncpy(hostname, req->url + m, j - m); + hostname[j - m] = '\0'; + port = DEFAULT_HTTP_PORT; + q = j; + break; + } + } - hst = gethostbyname(hostname); - if(hst == NULL){ - herror("Could not find host"); - close(s); - free(hostname); - return ERROR; - } + if (port == 0 || hostname[0] == '\0') { + fprintf(stderr, "Invalid URL\n"); + close(s); + free(hostname); + return ERROR; + } - addr = *((uint32_t *)hst->h_addr_list[0]); - - sck.sin_family = AF_INET; - sck.sin_port = htons(port); - sck.sin_addr.s_addr = addr; + l = strlen(hostname); + for (j = 0; j < l; j++) { + if (hostname[j] == '/') { + hostname[j] = '\0'; + break; + } + } - ret = connect(s, (struct sockaddr *)&sck, sizeof(sck)); - if(ret == ERROR){ - perror("Could not connect to host"); - close(s); - free(hostname); - return ERROR; - } - - switch(req->method){ - case GET: - method = HTTP_GET_METHOD; - break; - case HEAD: - method = HTTP_HEAD_METHOD; - break; - case POST: - method = HTTP_POST_METHOD; - break; - case DELETE: - method = HTTP_DELETE_METHOD; - break; - case PUT: - method = HTTP_PUT_METHOD; - break; - default: - method = HTTP_GET_METHOD; - } - - if(req->url[q] == '/'){ - dprintf(s, "%s %s HTTP/%s\r\n", method, req->url + q, req->version); - }else{ - dprintf(s, "%s /%s HTTP/%s\r\n", method, req->url + q, req->version); - } - - if(port != DEFAULT_HTTP_PORT) - dprintf(s, "Host: %s:%d\r\n", hostname, port); - else dprintf(s, "Host: %s\r\n", hostname); - dprintf(s, "Connection: close\r\n"); - dprintf(s, "Content-Length: %ld\r\n", req->body_len); + hst = gethostbyname(hostname); + if (hst == NULL) { + herror("Could not find host"); + close(s); + free(hostname); + return ERROR; + } - for(i = 0; i < req->header_len; i++){ - dprintf( - s, - "%s: %s\r\n", - req->headers[i].field_name, - req->headers[i].value - ); - } + addr = *((uint32_t *) hst->h_addr_list[0]); - dprintf(s, "\r\n"); + sck.sin_family = AF_INET; + sck.sin_port = htons(port); + sck.sin_addr.s_addr = addr; - - if(req->body != NULL && req->body_len != 0){ - ret = write(s, req->body, req->body_len); - if(ret == ERROR){ - perror("Could not write body to socket"); - free(hostname); - return ERROR; - } - } + ret = connect(s, (struct sockaddr *) &sck, sizeof(sck)); + if (ret == ERROR) { + perror("Could not connect to host"); + close(s); + free(hostname); + return ERROR; + } - buf = (char *)malloc(RECV_BUFF_SIZE * sizeof(char)); - if(buf == NULL){ - perror("Could not allocate memory for buffer"); - close(s); - free(hostname); - return ERROR; - } + switch (req->method) { + case GET: + method = HTTP_GET_METHOD; + break; + case HEAD: + method = HTTP_HEAD_METHOD; + break; + case POST: + method = HTTP_POST_METHOD; + break; + case DELETE: + method = HTTP_DELETE_METHOD; + break; + case PUT: + method = HTTP_PUT_METHOD; + break; + default: + method = HTTP_GET_METHOD; + } - buf_len = read_all(s, buf, RECV_BUFF_SIZE -1); - if(buf_len == ERROR){ - perror("Could not read into buffer"); - free(hostname); - return ERROR; - } - buf[buf_len] = '\0'; - - close(s); - - (void)signal(SIGPIPE, sig); - free(hostname); - return http_parse_response(buf, buf_len, res); + if (req->url[q] == '/') { + dprintf(s, "%s %s HTTP/%s\r\n", method, req->url + q, req->version); + } else { + dprintf(s, "%s /%s HTTP/%s\r\n", method, req->url + q, req->version); + } + + if (port != DEFAULT_HTTP_PORT) + dprintf(s, "Host: %s:%d\r\n", hostname, port); + else + dprintf(s, "Host: %s\r\n", hostname); + dprintf(s, "Connection: close\r\n"); + dprintf(s, "Content-Length: %ld\r\n", req->body_len); + + for (i = 0; i < req->header_len; i++) { + dprintf(s, "%s: %s\r\n", req->headers[i].field_name, req->headers[i].value); + } + + dprintf(s, "\r\n"); + + + if (req->body != NULL && req->body_len != 0) { + ret = write(s, req->body, req->body_len); + if (ret == ERROR) { + perror("Could not write body to socket"); + free(hostname); + return ERROR; + } + } + + buf = (char *) malloc(RECV_BUFF_SIZE * sizeof(char)); + if (buf == NULL) { + perror("Could not allocate memory for buffer"); + close(s); + free(hostname); + return ERROR; + } + + buf_len = read_all(s, buf, RECV_BUFF_SIZE - 1); + if (buf_len == ERROR) { + perror("Could not read into buffer"); + free(hostname); + return ERROR; + } + buf[buf_len] = '\0'; + + close(s); + + (void) signal(SIGPIPE, sig); + free(hostname); + return http_parse_response(buf, buf_len, res); } -int http_parse_response(char *buf, ssize_t buf_len, http_response_t *response) +int http_parse_response(char *buf, ssize_t buf_len, http_response_t * response) { - token_t token; - state_machine_t sm; - int pos; - ssize_t size; - char buff[STATUS_CODE_LEN]; - int old_pos; - int nt; - int i; - int j; - int f; + token_t token; + state_machine_t sm; + int pos; + ssize_t size; + char buff[STATUS_CODE_LEN]; + int old_pos; + int nt; + int i; + int j; + int f; - INIT_STATE_MACHINE(&sm); - - sm.buf = buf; - sm.buf_len = buf_len; + INIT_STATE_MACHINE(&sm); - pos = sm.pos; - token = get_next_token(&sm); - if(token != VERSION){ - fprintf(stderr, "ERROR %d-%d\n", VERSION, token); - return ERROR; - } - - size = sm.pos - pos; - response->version = (char *)malloc((size + 1) * sizeof(char)); - if(response->version == NULL){ - perror("Cannot allocate memory for version number"); - return ERROR; - } - strncpy(response->version, sm.buf + pos, size); - response->version[size] = '\0'; + sm.buf = buf; + sm.buf_len = buf_len; - pos = sm.pos; - token = get_next_token(&sm); - if(token != STATUS_CODE){ - fprintf(stderr, "ERROR %d-%d\n", STATUS_CODE, token); - return ERROR; - } + pos = sm.pos; + token = get_next_token(&sm); + if (token != VERSION) { + fprintf(stderr, "ERROR %d-%d\n", VERSION, token); + return ERROR; + } - size = sm.pos - pos; + size = sm.pos - pos; + response->version = (char *) malloc((size + 1) * sizeof(char)); + if (response->version == NULL) { + perror("Cannot allocate memory for version number"); + return ERROR; + } + strncpy(response->version, sm.buf + pos, size); + response->version[size] = '\0'; - buff[STATUS_CODE_LEN - 1] = '\0'; - strncpy(buff, sm.buf + pos, STATUS_CODE_LEN - 1); + pos = sm.pos; + token = get_next_token(&sm); + if (token != STATUS_CODE) { + fprintf(stderr, "ERROR %d-%d\n", STATUS_CODE, token); + return ERROR; + } - response->status_code = atoi(buff); + size = sm.pos - pos; - pos = sm.pos; - token = get_next_token(&sm); - if(token != PHRASE){ - fprintf(stderr, "ERROR %d-%d\n", PHRASE, token); - return ERROR; - } + buff[STATUS_CODE_LEN - 1] = '\0'; + strncpy(buff, sm.buf + pos, STATUS_CODE_LEN - 1); - size = sm.pos - pos - 2; - response->phrase = (char *)malloc((size + 1) * sizeof(char)); - if(response->phrase == NULL){ - perror("Cannot allocate memory for phrase"); - return ERROR; - } - strncpy(response->phrase, sm.buf + pos, size); - response->phrase[size] = '\0'; + response->status_code = atoi(buff); - old_pos = sm.pos; - nt = 0; - f = HTTP_FALSE; - do{ - token = get_next_token(&sm); - switch(token){ - case PHRASE: - case STATUS_CODE: - f = HTTP_FALSE; - case VERSION: - case NEWLINE: - break; - case HEADER: - if(f == HTTP_FALSE){ - nt++; - f = HTTP_TRUE; - } - else f = HTTP_FALSE; - break; - case SYNTAX_ERROR: - return ERROR; - } - - if(token != HEADER && token != PHRASE && token != STATUS_CODE) break; - }while(token != SYNTAX_ERROR); + pos = sm.pos; + token = get_next_token(&sm); + if (token != PHRASE) { + fprintf(stderr, "ERROR %d-%d\n", PHRASE, token); + return ERROR; + } - if(nt != 0){ - response->headers = (http_header_t *)malloc(sizeof(http_header_t)*nt); - if(response->headers == NULL){ - perror("Could not allocate memory for headers"); - return ERROR; - } - }else response->headers = NULL; + size = sm.pos - pos - 2; + response->phrase = (char *) malloc((size + 1) * sizeof(char)); + if (response->phrase == NULL) { + perror("Cannot allocate memory for phrase"); + return ERROR; + } + strncpy(response->phrase, sm.buf + pos, size); + response->phrase[size] = '\0'; - response->header_len = nt; + old_pos = sm.pos; + nt = 0; + f = HTTP_FALSE; + do { + token = get_next_token(&sm); + switch (token) { + case PHRASE: + case STATUS_CODE: + f = HTTP_FALSE; + case VERSION: + case NEWLINE: + break; + case HEADER: + if (f == HTTP_FALSE) { + nt++; + f = HTTP_TRUE; + } else + f = HTTP_FALSE; + break; + case SYNTAX_ERROR: + return ERROR; + } - sm.pos = old_pos; - for(i = 0; i < nt; i++){ - pos = sm.pos; - sm.state = state_start; - sm.stop = HTTP_FALSE; - token = get_next_token(&sm); - size = sm.pos - pos; - size -= 2; + if (token != HEADER && token != PHRASE && token != STATUS_CODE) + break; + } while (token != SYNTAX_ERROR); - response->headers[i].field_name = - (char *)malloc((size + 1) * sizeof(char)); + if (nt != 0) { + response->headers = (http_header_t *) malloc(sizeof(http_header_t) * nt); + if (response->headers == NULL) { + perror("Could not allocate memory for headers"); + return ERROR; + } + } else + response->headers = NULL; - if(response->headers[i].field_name == NULL){ - perror("Could not allocate memory for header"); - return ERROR; - } + response->header_len = nt; - strncpy(response->headers[i].field_name, sm.buf + pos, size); - response->headers[i].field_name[size] = '\0'; + sm.pos = old_pos; + for (i = 0; i < nt; i++) { + pos = sm.pos; + sm.state = state_start; + sm.stop = HTTP_FALSE; + token = get_next_token(&sm); + size = sm.pos - pos; + size -= 2; - pos = sm.pos; - token = get_next_token(&sm); - if(token == HEADER || token == STATUS_CODE){ - for(j = 0; - ((sm.buf + pos)[j] == '\r' - && (sm.buf + pos)[j + 1] == '\n') == 0; - j++ - ); - size = j; - sm.pos = j + 2; - }else size = sm.pos - pos - 2; + response->headers[i].field_name = (char *) malloc((size + 1) * sizeof(char)); - response->headers[i].value = - (char *)malloc((size + 1) * sizeof(char)); + if (response->headers[i].field_name == NULL) { + perror("Could not allocate memory for header"); + return ERROR; + } - if(response->headers[i].value == NULL){ - perror("Could not allocate memory for header"); - return ERROR; - } - strncpy(response->headers[i].value, sm.buf + pos, size); - response->headers[i].value[size] = '\0'; - - } + strncpy(response->headers[i].field_name, sm.buf + pos, size); + response->headers[i].field_name[size] = '\0'; - pos = sm.pos; - token = get_next_token(&sm); - if(token != NEWLINE){ - fprintf(stderr, "ERROR %d-%d\n", NEWLINE, token); - return ERROR; - } + pos = sm.pos; + token = get_next_token(&sm); + if (token == HEADER || token == STATUS_CODE) { + for (j = 0; ((sm.buf + pos)[j] == '\r' && (sm.buf + pos)[j + 1] == '\n') == 0; j++); + size = j; + sm.pos = j + 2; + } else + size = sm.pos - pos - 2; - response->body = (char *)malloc((buf_len - sm.pos + 1) * sizeof(char)); - if(response->body == NULL){ - perror("Could not allocate memory for body"); - return ERROR; - } + response->headers[i].value = (char *) malloc((size + 1) * sizeof(char)); - response->body_len = buf_len - sm.pos; - response->body[response->body_len] = '\0'; + if (response->headers[i].value == NULL) { + perror("Could not allocate memory for header"); + return ERROR; + } + strncpy(response->headers[i].value, sm.buf + pos, size); + response->headers[i].value[size] = '\0'; - (void)memcpy(response->body, buf + sm.pos, response->body_len); + } - return SUCCESS; + pos = sm.pos; + token = get_next_token(&sm); + if (token != NEWLINE) { + fprintf(stderr, "ERROR %d-%d\n", NEWLINE, token); + return ERROR; + } + + response->body = (char *) malloc((buf_len - sm.pos + 1) * sizeof(char)); + if (response->body == NULL) { + perror("Could not allocate memory for body"); + return ERROR; + } + + response->body_len = buf_len - sm.pos; + response->body[response->body_len] = '\0'; + + (void) memcpy(response->body, buf + sm.pos, response->body_len); + + return SUCCESS; } -void free_http_response(http_response_t *response) +void free_http_response(http_response_t * response) { - free(response->version); - free(response->phrase); - if(response->headers != NULL) free(response->headers); - if(response->body != NULL) free(response->body); + free(response->version); + free(response->phrase); + if (response->headers != NULL) + free(response->headers); + if (response->body != NULL) + free(response->body); } -token_t get_next_token(state_machine_t *sm) +token_t get_next_token(state_machine_t * sm) { - char c; - accept_state_t accept; + char c; + accept_state_t accept; - while(sm->stop != HTTP_TRUE){ - c = sm->buf[sm->pos]; - accept = sm->state(c, sm); - switch(accept){ - case NOAS: - case ASNR: - sm->pos++; - case ASWR: - break; - } + while (sm->stop != HTTP_TRUE) { + c = sm->buf[sm->pos]; + accept = sm->state(c, sm); + switch (accept) { + case NOAS: + case ASNR: + sm->pos++; + case ASWR: + break; + } - switch(accept){ - case ASNR: - case ASWR: - sm->state = state_start; - return sm->token; - case NOAS: - break; - } - - if(sm->pos >= sm->buf_len){ - sm->stop = HTTP_TRUE; - break; - } - } - - return SYNTAX_ERROR; + switch (accept) { + case ASNR: + case ASWR: + sm->state = state_start; + return sm->token; + case NOAS: + break; + } + + if (sm->pos >= sm->buf_len) { + sm->stop = HTTP_TRUE; + break; + } + } + + return SYNTAX_ERROR; } -static accept_state_t state_start(char c, state_machine_t *sm) +static accept_state_t state_start(char c, state_machine_t * sm) { - if(toupper(c) == 'H') sm->state = state_vhp_A; - else if(isdigit(c)) sm->state = state_shp; - else if(c == '\r' || c == '\n') sm->state = state_n; - else if(isprint(c)) sm->state = state_hp_A; - else sm->state = state_error; + if (toupper(c) == 'H') + sm->state = state_vhp_A; + else if (isdigit(c)) + sm->state = state_shp; + else if (c == '\r' || c == '\n') + sm->state = state_n; + else if (isprint(c)) + sm->state = state_hp_A; + else + sm->state = state_error; - return NOAS; + return NOAS; } -static accept_state_t state_shp(char c, state_machine_t *sm) +static accept_state_t state_shp(char c, state_machine_t * sm) { - if(isdigit(c)) sm->state = state_shp; - else if(isblank(c)){ - sm->token = STATUS_CODE; - return ASNR; - }else if(c == ':') sm->state = state_hp_B; - else if(c == '\r' || c == '\n') sm->state = state_p; - else if(isprint(c)) sm->state = state_hp_A; - else sm->state = state_error; - - return NOAS; + if (isdigit(c)) + sm->state = state_shp; + else if (isblank(c)) { + sm->token = STATUS_CODE; + return ASNR; + } else if (c == ':') + sm->state = state_hp_B; + else if (c == '\r' || c == '\n') + sm->state = state_p; + else if (isprint(c)) + sm->state = state_hp_A; + else + sm->state = state_error; + + return NOAS; } -static accept_state_t state_n(char c, state_machine_t *sm) +static accept_state_t state_n(char c, state_machine_t * sm) { - if(c == '\r' || c == '\n'){ - sm->token = NEWLINE; - return ASNR; - }else if(c == ':') sm->state = state_hp_B; - else if(isprint(c)) sm->state = state_hp_A; - else sm->state = state_error; + if (c == '\r' || c == '\n') { + sm->token = NEWLINE; + return ASNR; + } else if (c == ':') + sm->state = state_hp_B; + else if (isprint(c)) + sm->state = state_hp_A; + else + sm->state = state_error; - return NOAS; + return NOAS; } -static accept_state_t state_vhp_A(char c, state_machine_t *sm) +static accept_state_t state_vhp_A(char c, state_machine_t * sm) { - if(toupper(c) == 'T') sm->state = state_vhp_B; - else if(isprint(c)) sm->state = state_hp_A; - else if(c == '\n' || c == '\r') sm->state = state_p; - else sm->state = state_error; + if (toupper(c) == 'T') + sm->state = state_vhp_B; + else if (isprint(c)) + sm->state = state_hp_A; + else if (c == '\n' || c == '\r') + sm->state = state_p; + else + sm->state = state_error; - return NOAS; + return NOAS; } -static accept_state_t state_vhp_B(char c, state_machine_t *sm) +static accept_state_t state_vhp_B(char c, state_machine_t * sm) { - if(toupper(c) == 'T') sm->state = state_vhp_C; - else if(isprint(c)) sm->state = state_hp_A; - else if(c == '\n' || c == '\r') sm->state = state_p; - else sm->state = state_error; + if (toupper(c) == 'T') + sm->state = state_vhp_C; + else if (isprint(c)) + sm->state = state_hp_A; + else if (c == '\n' || c == '\r') + sm->state = state_p; + else + sm->state = state_error; - return NOAS; + return NOAS; } -static accept_state_t state_vhp_C(char c, state_machine_t *sm) +static accept_state_t state_vhp_C(char c, state_machine_t * sm) { - if(toupper(c) == 'P') sm->state = state_vhp_D; - else if(isprint(c)) sm->state = state_hp_A; - else if(c == '\n' || c == '\r') sm->state = state_p; - else sm->state = state_error; - - return NOAS; + if (toupper(c) == 'P') + sm->state = state_vhp_D; + else if (isprint(c)) + sm->state = state_hp_A; + else if (c == '\n' || c == '\r') + sm->state = state_p; + else + sm->state = state_error; + + return NOAS; } -static accept_state_t state_vhp_D(char c, state_machine_t *sm) +static accept_state_t state_vhp_D(char c, state_machine_t * sm) { - if(toupper(c) == '/') sm->state = state_vhp_E; - else if(isprint(c)) sm->state = state_hp_A; - else if(c == '\n' || c == '\r') sm->state = state_p; - else sm->state = state_error; - - return NOAS; + if (toupper(c) == '/') + sm->state = state_vhp_E; + else if (isprint(c)) + sm->state = state_hp_A; + else if (c == '\n' || c == '\r') + sm->state = state_p; + else + sm->state = state_error; + + return NOAS; } -static accept_state_t state_vhp_E(char c, state_machine_t *sm) +static accept_state_t state_vhp_E(char c, state_machine_t * sm) { - if(isdigit(c)) sm->state = state_vhp_F; - else if(isprint(c)) sm->state = state_hp_A; - else if(c == '\n' || c == '\r') sm->state = state_p; - else sm->state = state_error; - - return NOAS; + if (isdigit(c)) + sm->state = state_vhp_F; + else if (isprint(c)) + sm->state = state_hp_A; + else if (c == '\n' || c == '\r') + sm->state = state_p; + else + sm->state = state_error; + + return NOAS; } -static accept_state_t state_vhp_F(char c, state_machine_t *sm) +static accept_state_t state_vhp_F(char c, state_machine_t * sm) { - if(isdigit(c)) sm->state = state_vhp_F; - else if(c == '.') sm->state = state_vhp_G; - else if(isprint(c)) sm->state = state_hp_A; - else if(c == '\n' || c == '\r') sm->state = state_p; - else sm->state = state_error; - - return NOAS; + if (isdigit(c)) + sm->state = state_vhp_F; + else if (c == '.') + sm->state = state_vhp_G; + else if (isprint(c)) + sm->state = state_hp_A; + else if (c == '\n' || c == '\r') + sm->state = state_p; + else + sm->state = state_error; + + return NOAS; } -static accept_state_t state_vhp_G(char c, state_machine_t *sm) +static accept_state_t state_vhp_G(char c, state_machine_t * sm) { - if(isdigit(c)) sm->state = state_vhp_H; - else if(isprint(c)) sm->state = state_hp_A; - else if(c == '\n' || c == '\r') sm->state = state_p; - else sm->state = state_error; - - return NOAS; + if (isdigit(c)) + sm->state = state_vhp_H; + else if (isprint(c)) + sm->state = state_hp_A; + else if (c == '\n' || c == '\r') + sm->state = state_p; + else + sm->state = state_error; + + return NOAS; } -static accept_state_t state_vhp_H(char c, state_machine_t *sm) +static accept_state_t state_vhp_H(char c, state_machine_t * sm) { - if(isdigit(c)) sm->state = state_vhp_H; - else if(isblank(c)){ - sm->token = VERSION; - return ASNR; + if (isdigit(c)) + sm->state = state_vhp_H; + else if (isblank(c)) { + sm->token = VERSION; + return ASNR; - }else if(isprint(c)) sm->state = state_hp_A; + } else if (isprint(c)) + sm->state = state_hp_A; - return NOAS; + return NOAS; } -static accept_state_t state_hp_A(char c, state_machine_t *sm) +static accept_state_t state_hp_A(char c, state_machine_t * sm) { - if(c == ':') sm->state = state_hp_B; - else if(c == '\r' || c == '\n') sm->state = state_p; - else if(isprint(c)) sm->state = state_hp_A; - else sm->state = state_error; + if (c == ':') + sm->state = state_hp_B; + else if (c == '\r' || c == '\n') + sm->state = state_p; + else if (isprint(c)) + sm->state = state_hp_A; + else + sm->state = state_error; - return NOAS; + return NOAS; } -static accept_state_t state_hp_B(char c, state_machine_t *sm) +static accept_state_t state_hp_B(char c, state_machine_t * sm) { - if(isblank(c)){ - sm->token = HEADER; - return ASNR; - } else if(c == '\r' || c == '\n') sm->state = state_p; - else if(c == ':') sm->state = state_hp_B; - else if(isprint(c)) sm->state = state_hp_A; - else sm->state = state_error; + if (isblank(c)) { + sm->token = HEADER; + return ASNR; + } else if (c == '\r' || c == '\n') + sm->state = state_p; + else if (c == ':') + sm->state = state_hp_B; + else if (isprint(c)) + sm->state = state_hp_A; + else + sm->state = state_error; - return NOAS; + return NOAS; } -static accept_state_t state_p(char c, state_machine_t *sm) +static accept_state_t state_p(char c, state_machine_t * sm) { - if(c == '\r' || c == '\n'){ - sm->token = PHRASE; - return ASNR; - }else if(c == ':') sm->state = state_hp_B; - else if(isprint(c)) sm->state = state_hp_A; - else sm->state = state_error; + if (c == '\r' || c == '\n') { + sm->token = PHRASE; + return ASNR; + } else if (c == ':') + sm->state = state_hp_B; + else if (isprint(c)) + sm->state = state_hp_A; + else + sm->state = state_error; - return NOAS; + return NOAS; } -static accept_state_t state_error(char c, state_machine_t *sm) +static accept_state_t state_error(char c, state_machine_t * sm) { - c = 0; - sm->token = SYNTAX_ERROR; + c = 0; + sm->token = SYNTAX_ERROR; - return ASNR; + return ASNR; } static int read_all(int s, char *buf, size_t len) { - size_t t; - size_t r = ERROR; - - for(t = 0; t < len && r != 0;){ - r = read(s, buf + t, len - t); - if((int)r == ERROR){ - return ERROR; - }else{ - t += r; - } - } + size_t t; + size_t r = ERROR; - return (int)t; + for (t = 0; t < len && r != 0;) { + r = read(s, buf + t, len - t); + if ((int) r == ERROR) { + return ERROR; + } else { + t += r; + } + } + + return (int) t; } - diff --git a/src/mod/applications/mod_http/http_req.h b/src/mod/applications/mod_http/http_req.h index e91f591eac..05d6656c7a 100644 --- a/src/mod/applications/mod_http/http_req.h +++ b/src/mod/applications/mod_http/http_req.h @@ -74,65 +74,65 @@ do {\ #define STATUS_CODE_LEN 4 typedef enum tokens { - VERSION, - STATUS_CODE, - PHRASE, - HEADER, - NEWLINE, - SYNTAX_ERROR + VERSION, + STATUS_CODE, + PHRASE, + HEADER, + NEWLINE, + SYNTAX_ERROR } token_t; typedef enum accept_states { - ASWR, - ASNR, - NOAS + ASWR, + ASNR, + NOAS } accept_state_t; typedef struct state_machines { - accept_state_t (*state)(char, struct state_machines *); - int pos; - char *buf; - ssize_t buf_len; - int stop; - token_t token; + accept_state_t(*state) (char, struct state_machines *); + int pos; + char *buf; + ssize_t buf_len; + int stop; + token_t token; } state_machine_t; typedef enum http_methods { - GET, - HEAD, - POST, - DELETE, - PUT + GET, + HEAD, + POST, + DELETE, + PUT } http_method_t; typedef struct http_headers { - char *field_name; - char *value; + char *field_name; + char *value; } http_header_t; typedef struct http_requests { - http_method_t method; - char *version; - char *url; - http_header_t *headers; - ssize_t header_len; - char *body; - ssize_t body_len; + http_method_t method; + char *version; + char *url; + http_header_t *headers; + ssize_t header_len; + char *body; + ssize_t body_len; } http_request_t; typedef struct http_responses { - char *version; - int status_code; - char *phrase; - http_header_t *headers; - ssize_t header_len; - char *body; - int body_len; + char *version; + int status_code; + char *phrase; + http_header_t *headers; + ssize_t header_len; + char *body; + int body_len; } http_response_t; -token_t get_next_token(state_machine_t *sm); -int http_parse_response(char *buf, ssize_t buf_len, http_response_t *response); -int http_req(http_request_t *req, http_response_t *res); -void free_http_response(http_response_t *response); +token_t get_next_token(state_machine_t * sm); +int http_parse_response(char *buf, ssize_t buf_len, http_response_t * response); +int http_req(http_request_t * req, http_response_t * res); +void free_http_response(http_response_t * response); #endif diff --git a/src/mod/applications/mod_http/json.h b/src/mod/applications/mod_http/json.h index a5a3432b2c..7773f4af3d 100644 --- a/src/mod/applications/mod_http/json.h +++ b/src/mod/applications/mod_http/json.h @@ -27,5 +27,4 @@ extern "C" { #ifdef __cplusplus } #endif - #endif diff --git a/src/mod/applications/mod_http/json_object.c b/src/mod/applications/mod_http/json_object.c index 55782b9f5e..f1c9226998 100644 --- a/src/mod/applications/mod_http/json_object.c +++ b/src/mod/applications/mod_http/json_object.c @@ -25,7 +25,7 @@ #if !HAVE_STRNDUP - char* strndup(const char* str, size_t n); +char *strndup(const char *str, size_t n); #endif /* !HAVE_STRNDUP */ @@ -35,19 +35,19 @@ char *json_number_chars = "0123456789.+-e"; char *json_hex_chars = "0123456789abcdef"; #ifdef REFCOUNT_DEBUG -static char* json_type_name[] = { - "null", - "boolean", - "double", - "int", - "object", - "array", - "string", +static char *json_type_name[] = { + "null", + "boolean", + "double", + "int", + "object", + "array", + "string", }; #endif /* REFCOUNT_DEBUG */ -static void json_object_generic_delete(struct json_object* this); -static struct json_object* json_object_new(enum json_type o_type); +static void json_object_generic_delete(struct json_object *this); +static struct json_object *json_object_new(enum json_type o_type); /* ref count debugging */ @@ -57,24 +57,25 @@ static struct json_object* json_object_new(enum json_type o_type); static struct lh_table *json_object_table; static void json_object_init() __attribute__ ((constructor)); -static void json_object_init() { - mc_debug("json_object_init: creating object table\n"); - json_object_table = lh_kptr_table_new(128, "json_object_table", NULL); +static void json_object_init() +{ + mc_debug("json_object_init: creating object table\n"); + json_object_table = lh_kptr_table_new(128, "json_object_table", NULL); } static void json_object_fini() __attribute__ ((destructor)); -static void json_object_fini() { - struct lh_entry *ent; - if(mc_get_debug() && json_object_table->count) { - mc_debug("json_object_fini: %d referenced objects at exit\n", - json_object_table->count); - lh_foreach(json_object_table, ent) { - struct json_object* obj = (struct json_object*)ent->v; - mc_debug("\t%s:%p\n", json_type_name[obj->o_type], obj); - } - } - mc_debug("json_object_fini: freeing object table\n"); - lh_table_free(json_object_table); +static void json_object_fini() +{ + struct lh_entry *ent; + if (mc_get_debug() && json_object_table->count) { + mc_debug("json_object_fini: %d referenced objects at exit\n", json_object_table->count); + lh_foreach(json_object_table, ent) { + struct json_object *obj = (struct json_object *) ent->v; + mc_debug("\t%s:%p\n", json_type_name[obj->o_type], obj); + } + } + mc_debug("json_object_fini: freeing object table\n"); + lh_table_free(json_object_table); } #endif /* REFCOUNT_DEBUG */ @@ -83,92 +84,99 @@ static void json_object_fini() { static int json_escape_str(struct printbuf *pb, char *str) { - int pos = 0, start_offset = 0; - unsigned char c; - do { - c = str[pos]; - switch(c) { - case '\0': - break; - case '\b': - case '\n': - case '\r': - case '\t': - case '"': - case '\\': - case '/': - if(pos - start_offset > 0) - printbuf_memappend(pb, str + start_offset, pos - start_offset); - if(c == '\b') printbuf_memappend(pb, "\\b", 2); - else if(c == '\n') printbuf_memappend(pb, "\\n", 2); - else if(c == '\r') printbuf_memappend(pb, "\\r", 2); - else if(c == '\t') printbuf_memappend(pb, "\\t", 2); - else if(c == '"') printbuf_memappend(pb, "\\\"", 2); - else if(c == '\\') printbuf_memappend(pb, "\\\\", 2); - else if(c == '/') printbuf_memappend(pb, "\\/", 2); - start_offset = ++pos; - break; - default: - if(c < ' ') { - if(pos - start_offset > 0) - printbuf_memappend(pb, str + start_offset, pos - start_offset); - sprintbuf(pb, "\\u00%c%c", - json_hex_chars[c >> 4], - json_hex_chars[c & 0xf]); - start_offset = ++pos; - } else pos++; - } - } while(c); - if(pos - start_offset > 0) - printbuf_memappend(pb, str + start_offset, pos - start_offset); - return 0; + int pos = 0, start_offset = 0; + unsigned char c; + do { + c = str[pos]; + switch (c) { + case '\0': + break; + case '\b': + case '\n': + case '\r': + case '\t': + case '"': + case '\\': + case '/': + if (pos - start_offset > 0) + printbuf_memappend(pb, str + start_offset, pos - start_offset); + if (c == '\b') + printbuf_memappend(pb, "\\b", 2); + else if (c == '\n') + printbuf_memappend(pb, "\\n", 2); + else if (c == '\r') + printbuf_memappend(pb, "\\r", 2); + else if (c == '\t') + printbuf_memappend(pb, "\\t", 2); + else if (c == '"') + printbuf_memappend(pb, "\\\"", 2); + else if (c == '\\') + printbuf_memappend(pb, "\\\\", 2); + else if (c == '/') + printbuf_memappend(pb, "\\/", 2); + start_offset = ++pos; + break; + default: + if (c < ' ') { + if (pos - start_offset > 0) + printbuf_memappend(pb, str + start_offset, pos - start_offset); + sprintbuf(pb, "\\u00%c%c", json_hex_chars[c >> 4], json_hex_chars[c & 0xf]); + start_offset = ++pos; + } else + pos++; + } + } while (c); + if (pos - start_offset > 0) + printbuf_memappend(pb, str + start_offset, pos - start_offset); + return 0; } /* reference counting */ -extern struct json_object* json_object_get(struct json_object *this) +extern struct json_object *json_object_get(struct json_object *this) { - if(this) { - this->_ref_count++; - } - return this; + if (this) { + this->_ref_count++; + } + return this; } extern void json_object_put(struct json_object *this) { - if(this) { - this->_ref_count--; - if(!this->_ref_count) this->_delete(this); - } + if (this) { + this->_ref_count--; + if (!this->_ref_count) + this->_delete(this); + } } /* generic object construction and destruction parts */ -static void json_object_generic_delete(struct json_object* this) +static void json_object_generic_delete(struct json_object *this) { #ifdef REFCOUNT_DEBUG - mc_debug("json_object_delete_%s: %p\n", - json_type_name[this->o_type], this); - lh_table_delete(json_object_table, this); + mc_debug("json_object_delete_%s: %p\n", json_type_name[this->o_type], this); + lh_table_delete(json_object_table, this); #endif /* REFCOUNT_DEBUG */ - printbuf_free(this->_pb); - free(this); + printbuf_free(this->_pb); + free(this); } -static struct json_object* json_object_new(enum json_type o_type) +static struct json_object *json_object_new(enum json_type o_type) { - struct json_object *this = calloc(sizeof(struct json_object), 1); - if(!this) return NULL; - this->o_type = o_type; - this->_ref_count = 1; - this->_delete = &json_object_generic_delete; + struct json_object *this = calloc(sizeof(struct json_object), 1); + if (!this) + return NULL; + this->o_type = o_type; + this->_ref_count = 1; + this->_delete = &json_object_generic_delete; #ifdef REFCOUNT_DEBUG - lh_table_insert(json_object_table, this, this); - mc_debug("json_object_new_%s: %p\n", json_type_name[this->o_type], this); + lh_table_insert(json_object_table, this, this); + mc_debug("json_object_new_%s: %p\n", json_type_name[this->o_type], this); #endif /* REFCOUNT_DEBUG */ - return this; + return this; } @@ -176,335 +184,354 @@ static struct json_object* json_object_new(enum json_type o_type) int json_object_is_type(struct json_object *this, enum json_type type) { - return (this->o_type == type); + return (this->o_type == type); } enum json_type json_object_get_type(struct json_object *this) { - return this->o_type; + return this->o_type; } /* json_object_to_json_string */ -char* json_object_to_json_string(struct json_object *this) +char *json_object_to_json_string(struct json_object *this) { - if(!this) return "null"; - if(!this->_pb) { - if(!(this->_pb = printbuf_new())) return NULL; - } else { - printbuf_reset(this->_pb); - } - if(this->_to_json_string(this, this->_pb) < 0) return NULL; - return this->_pb->buf; + if (!this) + return "null"; + if (!this->_pb) { + if (!(this->_pb = printbuf_new())) + return NULL; + } else { + printbuf_reset(this->_pb); + } + if (this->_to_json_string(this, this->_pb) < 0) + return NULL; + return this->_pb->buf; } /* json_object_object */ -static int json_object_object_to_json_string(struct json_object* this, - struct printbuf *pb) +static int json_object_object_to_json_string(struct json_object *this, struct printbuf *pb) { - int i=0; - struct json_object_iter iter; - sprintbuf(pb, "{"); + int i = 0; + struct json_object_iter iter; + sprintbuf(pb, "{"); - /* CAW: scope operator to make ANSI correctness */ - /* CAW: switched to json_object_object_foreachC which uses an iterator struct */ + /* CAW: scope operator to make ANSI correctness */ + /* CAW: switched to json_object_object_foreachC which uses an iterator struct */ json_object_object_foreachC(this, iter) { - if(i) sprintbuf(pb, ","); - sprintbuf(pb, " \""); - json_escape_str(pb, iter.key); - sprintbuf(pb, "\": "); - if(iter.val == NULL) sprintbuf(pb, "null"); - else iter.val->_to_json_string(iter.val, pb); - i++; + if (i) + sprintbuf(pb, ","); + sprintbuf(pb, " \""); + json_escape_str(pb, iter.key); + sprintbuf(pb, "\": "); + if (iter.val == NULL) + sprintbuf(pb, "null"); + else + iter.val->_to_json_string(iter.val, pb); + i++; } - return sprintbuf(pb, " }"); + return sprintbuf(pb, " }"); } static void json_object_lh_entry_free(struct lh_entry *ent) { - free(ent->k); - json_object_put((struct json_object*)ent->v); + free(ent->k); + json_object_put((struct json_object *) ent->v); } -static void json_object_object_delete(struct json_object* this) +static void json_object_object_delete(struct json_object *this) { - lh_table_free(this->o.c_object); - json_object_generic_delete(this); + lh_table_free(this->o.c_object); + json_object_generic_delete(this); } -struct json_object* json_object_new_object() +struct json_object *json_object_new_object() { - struct json_object *this = json_object_new(json_type_object); - if(!this) return NULL; - this->_delete = &json_object_object_delete; - this->_to_json_string = &json_object_object_to_json_string; - this->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTIRES, - NULL, &json_object_lh_entry_free); - return this; + struct json_object *this = json_object_new(json_type_object); + if (!this) + return NULL; + this->_delete = &json_object_object_delete; + this->_to_json_string = &json_object_object_to_json_string; + this->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTIRES, NULL, &json_object_lh_entry_free); + return this; } -struct lh_table* json_object_get_object(struct json_object *this) +struct lh_table *json_object_get_object(struct json_object *this) { - if(!this) return NULL; - switch(this->o_type) { - case json_type_object: - return this->o.c_object; - default: - return NULL; - } + if (!this) + return NULL; + switch (this->o_type) { + case json_type_object: + return this->o.c_object; + default: + return NULL; + } } -void json_object_object_add(struct json_object* this, char *key, - struct json_object *val) +void json_object_object_add(struct json_object *this, char *key, struct json_object *val) { - lh_table_delete(this->o.c_object, key); - lh_table_insert(this->o.c_object, strdup(key), val); + lh_table_delete(this->o.c_object, key); + lh_table_insert(this->o.c_object, strdup(key), val); } -struct json_object* json_object_object_get(struct json_object* this, char *key) +struct json_object *json_object_object_get(struct json_object *this, char *key) { - return (struct json_object*) lh_table_lookup(this->o.c_object, key); + return (struct json_object *) lh_table_lookup(this->o.c_object, key); } -void json_object_object_del(struct json_object* this, char *key) +void json_object_object_del(struct json_object *this, char *key) { - lh_table_delete(this->o.c_object, key); + lh_table_delete(this->o.c_object, key); } /* json_object_boolean */ -static int json_object_boolean_to_json_string(struct json_object* this, - struct printbuf *pb) +static int json_object_boolean_to_json_string(struct json_object *this, struct printbuf *pb) { - if(this->o.c_boolean) return sprintbuf(pb, "true"); - else return sprintbuf(pb, "false"); + if (this->o.c_boolean) + return sprintbuf(pb, "true"); + else + return sprintbuf(pb, "false"); } -struct json_object* json_object_new_boolean(boolean b) +struct json_object *json_object_new_boolean(boolean b) { - struct json_object *this = json_object_new(json_type_boolean); - if(!this) return NULL; - this->_to_json_string = &json_object_boolean_to_json_string; - this->o.c_boolean = b; - return this; + struct json_object *this = json_object_new(json_type_boolean); + if (!this) + return NULL; + this->_to_json_string = &json_object_boolean_to_json_string; + this->o.c_boolean = b; + return this; } -boolean json_object_get_boolean(struct json_object *this) +boolean json_object_get_boolean(struct json_object * this) { - if(!this) return FALSE; - switch(this->o_type) { - case json_type_boolean: - return this->o.c_boolean; - case json_type_int: - return (this->o.c_int != 0); - case json_type_double: - return (this->o.c_double != 0); - case json_type_string: - if(strlen(this->o.c_string)) return TRUE; - default: - return TRUE; - } + if (!this) + return FALSE; + switch (this->o_type) { + case json_type_boolean: + return this->o.c_boolean; + case json_type_int: + return (this->o.c_int != 0); + case json_type_double: + return (this->o.c_double != 0); + case json_type_string: + if (strlen(this->o.c_string)) + return TRUE; + default: + return TRUE; + } } /* json_object_int */ -static int json_object_int_to_json_string(struct json_object* this, - struct printbuf *pb) +static int json_object_int_to_json_string(struct json_object *this, struct printbuf *pb) { - return sprintbuf(pb, "%d", this->o.c_int); + return sprintbuf(pb, "%d", this->o.c_int); } -struct json_object* json_object_new_int(int i) +struct json_object *json_object_new_int(int i) { - struct json_object *this = json_object_new(json_type_int); - if(!this) return NULL; - this->_to_json_string = &json_object_int_to_json_string; - this->o.c_int = i; - return this; + struct json_object *this = json_object_new(json_type_int); + if (!this) + return NULL; + this->_to_json_string = &json_object_int_to_json_string; + this->o.c_int = i; + return this; } int json_object_get_int(struct json_object *this) { - int cint; + int cint; - if(!this) return 0; - switch(this->o_type) { - case json_type_int: - return this->o.c_int; - case json_type_double: - return (int)this->o.c_double; - case json_type_boolean: - return this->o.c_boolean; - case json_type_string: - if(sscanf(this->o.c_string, "%d", &cint) == 1) return cint; - default: - return 0; - } + if (!this) + return 0; + switch (this->o_type) { + case json_type_int: + return this->o.c_int; + case json_type_double: + return (int) this->o.c_double; + case json_type_boolean: + return this->o.c_boolean; + case json_type_string: + if (sscanf(this->o.c_string, "%d", &cint) == 1) + return cint; + default: + return 0; + } } /* json_object_double */ -static int json_object_double_to_json_string(struct json_object* this, - struct printbuf *pb) +static int json_object_double_to_json_string(struct json_object *this, struct printbuf *pb) { - return sprintbuf(pb, "%lf", this->o.c_double); + return sprintbuf(pb, "%lf", this->o.c_double); } -struct json_object* json_object_new_double(double d) +struct json_object *json_object_new_double(double d) { - struct json_object *this = json_object_new(json_type_double); - if(!this) return NULL; - this->_to_json_string = &json_object_double_to_json_string; - this->o.c_double = d; - return this; + struct json_object *this = json_object_new(json_type_double); + if (!this) + return NULL; + this->_to_json_string = &json_object_double_to_json_string; + this->o.c_double = d; + return this; } double json_object_get_double(struct json_object *this) { - double cdouble; + double cdouble; - if(!this) return 0.0; - switch(this->o_type) { - case json_type_double: - return this->o.c_double; - case json_type_int: - return this->o.c_int; - case json_type_boolean: - return this->o.c_boolean; - case json_type_string: - if(sscanf(this->o.c_string, "%lf", &cdouble) == 1) return cdouble; - default: - return 0.0; - } + if (!this) + return 0.0; + switch (this->o_type) { + case json_type_double: + return this->o.c_double; + case json_type_int: + return this->o.c_int; + case json_type_boolean: + return this->o.c_boolean; + case json_type_string: + if (sscanf(this->o.c_string, "%lf", &cdouble) == 1) + return cdouble; + default: + return 0.0; + } } /* json_object_string */ -static int json_object_string_to_json_string(struct json_object* this, - struct printbuf *pb) +static int json_object_string_to_json_string(struct json_object *this, struct printbuf *pb) { - sprintbuf(pb, "\""); - json_escape_str(pb, this->o.c_string); - sprintbuf(pb, "\""); - return 0; + sprintbuf(pb, "\""); + json_escape_str(pb, this->o.c_string); + sprintbuf(pb, "\""); + return 0; } -static void json_object_string_delete(struct json_object* this) +static void json_object_string_delete(struct json_object *this) { - free(this->o.c_string); - json_object_generic_delete(this); + free(this->o.c_string); + json_object_generic_delete(this); } -struct json_object* json_object_new_string(char *s) +struct json_object *json_object_new_string(char *s) { - struct json_object *this = json_object_new(json_type_string); - if(!this) return NULL; - this->_delete = &json_object_string_delete; - this->_to_json_string = &json_object_string_to_json_string; - this->o.c_string = strdup(s); - return this; + struct json_object *this = json_object_new(json_type_string); + if (!this) + return NULL; + this->_delete = &json_object_string_delete; + this->_to_json_string = &json_object_string_to_json_string; + this->o.c_string = strdup(s); + return this; } -struct json_object* json_object_new_string_len(char *s, int len) +struct json_object *json_object_new_string_len(char *s, int len) { - struct json_object *this = json_object_new(json_type_string); - if(!this) return NULL; - this->_delete = &json_object_string_delete; - this->_to_json_string = &json_object_string_to_json_string; - this->o.c_string = strndup(s, len); - return this; + struct json_object *this = json_object_new(json_type_string); + if (!this) + return NULL; + this->_delete = &json_object_string_delete; + this->_to_json_string = &json_object_string_to_json_string; + this->o.c_string = strndup(s, len); + return this; } -char* json_object_get_string(struct json_object *this) +char *json_object_get_string(struct json_object *this) { - if(!this) return NULL; - switch(this->o_type) { - case json_type_string: - return this->o.c_string; - default: - return json_object_to_json_string(this); - } + if (!this) + return NULL; + switch (this->o_type) { + case json_type_string: + return this->o.c_string; + default: + return json_object_to_json_string(this); + } } /* json_object_array */ -static int json_object_array_to_json_string(struct json_object* this, - struct printbuf *pb) +static int json_object_array_to_json_string(struct json_object *this, struct printbuf *pb) { - int i; - sprintbuf(pb, "["); - for(i=0; i < json_object_array_length(this); i++) { - struct json_object *val; - if(i) { sprintbuf(pb, ", "); } - else { sprintbuf(pb, " "); } + int i; + sprintbuf(pb, "["); + for (i = 0; i < json_object_array_length(this); i++) { + struct json_object *val; + if (i) { + sprintbuf(pb, ", "); + } else { + sprintbuf(pb, " "); + } - val = json_object_array_get_idx(this, i); - if(val == NULL) { sprintbuf(pb, "null"); } - else { val->_to_json_string(val, pb); } - } - return sprintbuf(pb, " ]"); + val = json_object_array_get_idx(this, i); + if (val == NULL) { + sprintbuf(pb, "null"); + } else { + val->_to_json_string(val, pb); + } + } + return sprintbuf(pb, " ]"); } static void json_object_array_entry_free(void *data) { - json_object_put((struct json_object*)data); + json_object_put((struct json_object *) data); } -static void json_object_array_delete(struct json_object* this) +static void json_object_array_delete(struct json_object *this) { - array_list_free(this->o.c_array); - json_object_generic_delete(this); + array_list_free(this->o.c_array); + json_object_generic_delete(this); } -struct json_object* json_object_new_array() +struct json_object *json_object_new_array() { - struct json_object *this = json_object_new(json_type_array); - if(!this) return NULL; - this->_delete = &json_object_array_delete; - this->_to_json_string = &json_object_array_to_json_string; - this->o.c_array = array_list_new(&json_object_array_entry_free); - return this; + struct json_object *this = json_object_new(json_type_array); + if (!this) + return NULL; + this->_delete = &json_object_array_delete; + this->_to_json_string = &json_object_array_to_json_string; + this->o.c_array = array_list_new(&json_object_array_entry_free); + return this; } -struct array_list* json_object_get_array(struct json_object *this) +struct array_list *json_object_get_array(struct json_object *this) { - if(!this) return NULL; - switch(this->o_type) { - case json_type_array: - return this->o.c_array; - default: - return NULL; - } + if (!this) + return NULL; + switch (this->o_type) { + case json_type_array: + return this->o.c_array; + default: + return NULL; + } } int json_object_array_length(struct json_object *this) { - return array_list_length(this->o.c_array); + return array_list_length(this->o.c_array); } -int json_object_array_add(struct json_object *this,struct json_object *val) +int json_object_array_add(struct json_object *this, struct json_object *val) { - return array_list_add(this->o.c_array, val); + return array_list_add(this->o.c_array, val); } -int json_object_array_put_idx(struct json_object *this, int idx, - struct json_object *val) +int json_object_array_put_idx(struct json_object *this, int idx, struct json_object *val) { - return array_list_put_idx(this->o.c_array, idx, val); + return array_list_put_idx(this->o.c_array, idx, val); } -struct json_object* json_object_array_get_idx(struct json_object *this, - int idx) +struct json_object *json_object_array_get_idx(struct json_object *this, int idx) { - return (struct json_object*)array_list_get_idx(this->o.c_array, idx); + return (struct json_object *) array_list_get_idx(this->o.c_array, idx); } - diff --git a/src/mod/applications/mod_http/json_object.h b/src/mod/applications/mod_http/json_object.h index 71f956b297..37a6392549 100644 --- a/src/mod/applications/mod_http/json_object.h +++ b/src/mod/applications/mod_http/json_object.h @@ -35,13 +35,13 @@ struct json_object_iter; /* supported object types */ enum json_type { - json_type_null, - json_type_boolean, - json_type_double, - json_type_int, - json_type_object, - json_type_array, - json_type_string + json_type_null, + json_type_boolean, + json_type_double, + json_type_int, + json_type_object, + json_type_array, + json_type_string }; /* reference counting functions */ @@ -50,7 +50,7 @@ enum json_type { * Increment the reference count of json_object * @param obj the json_object instance */ -extern struct json_object* json_object_get(struct json_object *obj); +extern struct json_object *json_object_get(struct json_object *obj); /** * Decrement the reference count of json_object and free if it reaches zero @@ -90,7 +90,7 @@ extern enum json_type json_object_get_type(struct json_object *obj); * @param obj the json_object instance * @returns a string in JSON format */ -extern char* json_object_to_json_string(struct json_object *obj); +extern char *json_object_to_json_string(struct json_object *obj); /* object type methods */ @@ -98,13 +98,13 @@ extern char* json_object_to_json_string(struct json_object *obj); /** Create a new empty object * @returns a json_object of type json_type_object */ -extern struct json_object* json_object_new_object(); +extern struct json_object *json_object_new_object(); /** Get the hashtable of a json_object of type json_type_object * @param obj the json_object instance * @returns a linkhash */ -extern struct lh_table* json_object_get_object(struct json_object *obj); +extern struct lh_table *json_object_get_object(struct json_object *obj); /** Add an object field to a json_object of type json_type_object * @@ -116,16 +116,14 @@ extern struct lh_table* json_object_get_object(struct json_object *obj); * @param key the object field name (a private copy will be duplicated) * @param val a json_object or NULL member to associate with the given field */ -extern void json_object_object_add(struct json_object* obj, char *key, - struct json_object *val); +extern void json_object_object_add(struct json_object *obj, char *key, struct json_object *val); /** Get the json_object associate with a given object field * @param obj the json_object instance * @param key the object field name * @returns the json_object associated with the given field name */ -extern struct json_object* json_object_object_get(struct json_object* obj, - char *key); +extern struct json_object *json_object_object_get(struct json_object *obj, char *key); /** Delete the given json_object field * @@ -134,7 +132,7 @@ extern struct json_object* json_object_object_get(struct json_object* obj, * @param obj the json_object instance * @param key the object field name */ -extern void json_object_object_del(struct json_object* obj, char *key); +extern void json_object_object_del(struct json_object *obj, char *key); /** Iterate through all keys and values of an object * @param obj the json_object instance @@ -165,13 +163,13 @@ extern void json_object_object_del(struct json_object* obj, char *key); /** Create a new empty json_object of type json_type_array * @returns a json_object of type json_type_array */ -extern struct json_object* json_object_new_array(); +extern struct json_object *json_object_new_array(); /** Get the arraylist of a json_object of type json_type_array * @param obj the json_object instance * @returns an arraylist */ -extern struct array_list* json_object_get_array(struct json_object *obj); +extern struct array_list *json_object_get_array(struct json_object *obj); /** Get the length of a json_object of type json_type_array * @param obj the json_object instance @@ -188,8 +186,7 @@ extern int json_object_array_length(struct json_object *obj); * @param obj the json_object instance * @param val the json_object to be added */ -extern int json_object_array_add(struct json_object *obj, - struct json_object *val); +extern int json_object_array_add(struct json_object *obj, struct json_object *val); /** Insert or replace an element at a specified index in an array (a json_object of type json_type_array) * @@ -206,16 +203,14 @@ extern int json_object_array_add(struct json_object *obj, * @param idx the index to insert the element at * @param val the json_object to be added */ -extern int json_object_array_put_idx(struct json_object *obj, int idx, - struct json_object *val); +extern int json_object_array_put_idx(struct json_object *obj, int idx, struct json_object *val); /** Get the element at specificed index of the array (a json_object of type json_type_array) * @param obj the json_object instance * @param idx the index to get the element at * @returns the json_object at the specified index (or NULL) */ -extern struct json_object* json_object_array_get_idx(struct json_object *obj, - int idx); +extern struct json_object *json_object_array_get_idx(struct json_object *obj, int idx); /* boolean type methods */ @@ -223,7 +218,7 @@ extern struct json_object* json_object_array_get_idx(struct json_object *obj, * @param b a boolean TRUE or FALSE (0 or 1) * @returns a json_object of type json_type_boolean */ -extern struct json_object* json_object_new_boolean(boolean b); +extern struct json_object *json_object_new_boolean(boolean b); /** Get the boolean value of a json_object * @@ -245,7 +240,7 @@ extern boolean json_object_get_boolean(struct json_object *obj); * @param i the integer * @returns a json_object of type json_type_int */ -extern struct json_object* json_object_new_int(int i); +extern struct json_object *json_object_new_int(int i); /** Get the int value of a json_object * @@ -265,7 +260,7 @@ extern int json_object_get_int(struct json_object *obj); * @param d the double * @returns a json_object of type json_type_double */ -extern struct json_object* json_object_new_double(double d); +extern struct json_object *json_object_new_double(double d); /** Get the double value of a json_object * @@ -288,9 +283,9 @@ extern double json_object_get_double(struct json_object *obj); * @param s the string * @returns a json_object of type json_type_string */ -extern struct json_object* json_object_new_string(char *s); +extern struct json_object *json_object_new_string(char *s); -extern struct json_object* json_object_new_string_len(char *s, int len); +extern struct json_object *json_object_new_string_len(char *s, int len); /** Get the string value of a json_object * @@ -303,6 +298,6 @@ extern struct json_object* json_object_new_string_len(char *s, int len); * @param obj the json_object instance * @returns a string */ -extern char* json_object_get_string(struct json_object *obj); +extern char *json_object_get_string(struct json_object *obj); #endif diff --git a/src/mod/applications/mod_http/json_object_private.h b/src/mod/applications/mod_http/json_object_private.h index 35a44f3a09..8b565efef5 100644 --- a/src/mod/applications/mod_http/json_object_private.h +++ b/src/mod/applications/mod_http/json_object_private.h @@ -12,30 +12,27 @@ #ifndef _json_object_private_h_ #define _json_object_private_h_ -typedef void (json_object_delete_fn)(struct json_object *o); -typedef int (json_object_to_json_string_fn)(struct json_object *o, - struct printbuf *pb); +typedef void (json_object_delete_fn) (struct json_object * o); +typedef int (json_object_to_json_string_fn) (struct json_object * o, struct printbuf * pb); -struct json_object -{ - enum json_type o_type; - json_object_delete_fn *_delete; - json_object_to_json_string_fn *_to_json_string; - int _ref_count; - struct printbuf *_pb; - union data { - boolean c_boolean; - double c_double; - int c_int; - struct lh_table *c_object; - struct array_list *c_array; - char *c_string; - } o; +struct json_object { + enum json_type o_type; + json_object_delete_fn *_delete; + json_object_to_json_string_fn *_to_json_string; + int _ref_count; + struct printbuf *_pb; + union data { + boolean c_boolean; + double c_double; + int c_int; + struct lh_table *c_object; + struct array_list *c_array; + char *c_string; + } o; }; /* CAW: added for ANSI C iteration correctness */ -struct json_object_iter -{ +struct json_object_iter { char *key; struct json_object *val; struct lh_entry *entry; diff --git a/src/mod/applications/mod_http/json_tokener.c b/src/mod/applications/mod_http/json_tokener.c index 8f743289bf..fc83d6c22d 100644 --- a/src/mod/applications/mod_http/json_tokener.c +++ b/src/mod/applications/mod_http/json_tokener.c @@ -32,94 +32,95 @@ #endif /* HAVE_STRNCASECMP */ -static const char* json_null_str = "null"; -static const char* json_true_str = "true"; -static const char* json_false_str = "false"; +static const char *json_null_str = "null"; +static const char *json_true_str = "true"; +static const char *json_false_str = "false"; -const char* json_tokener_errors[] = { - "success", - "continue", - "nesting to deep", - "unexpected end of data", - "unexpected character", - "null expected", - "boolean expected", - "number expected", - "array value separator ',' expected", - "quoted object property name expected", - "object property name separator ':' expected", - "object value separator ',' expected", - "invalid string sequence", - "expected comment", +const char *json_tokener_errors[] = { + "success", + "continue", + "nesting to deep", + "unexpected end of data", + "unexpected character", + "null expected", + "boolean expected", + "number expected", + "array value separator ',' expected", + "quoted object property name expected", + "object property name separator ':' expected", + "object value separator ',' expected", + "invalid string sequence", + "expected comment", }; -struct json_tokener* json_tokener_new() +struct json_tokener *json_tokener_new() { - struct json_tokener *tok = calloc(1, sizeof(struct json_tokener)); - tok->pb = printbuf_new(); - json_tokener_reset(tok); - return tok; + struct json_tokener *tok = calloc(1, sizeof(struct json_tokener)); + tok->pb = printbuf_new(); + json_tokener_reset(tok); + return tok; } void json_tokener_free(struct json_tokener *tok) { - json_tokener_reset(tok); - if(tok) printbuf_free(tok->pb); - free(tok); + json_tokener_reset(tok); + if (tok) + printbuf_free(tok->pb); + free(tok); } static void json_tokener_reset_level(struct json_tokener *tok, int depth) { - tok->stack[depth].state = json_tokener_state_eatws; - tok->stack[depth].saved_state = json_tokener_state_start; - json_object_put(tok->stack[depth].current); - tok->stack[depth].current = NULL; - free(tok->stack[depth].obj_field_name); - tok->stack[depth].obj_field_name = NULL; + tok->stack[depth].state = json_tokener_state_eatws; + tok->stack[depth].saved_state = json_tokener_state_start; + json_object_put(tok->stack[depth].current); + tok->stack[depth].current = NULL; + free(tok->stack[depth].obj_field_name); + tok->stack[depth].obj_field_name = NULL; } void json_tokener_reset(struct json_tokener *tok) { - int i; - for(i = tok->depth; i >= 0; i--) - json_tokener_reset_level(tok, i); - tok->depth = 0; - tok->err = json_tokener_success; + int i; + for (i = tok->depth; i >= 0; i--) + json_tokener_reset_level(tok, i); + tok->depth = 0; + tok->err = json_tokener_success; } -struct json_object* json_tokener_parse(char *str) +struct json_object *json_tokener_parse(char *str) { - struct json_tokener* tok; - struct json_object* obj; + struct json_tokener *tok; + struct json_object *obj; - tok = json_tokener_new(); - obj = json_tokener_parse_ex(tok, str, -1); - if(tok->err != json_tokener_success) - obj = error_ptr(-tok->err); - json_tokener_free(tok); - return obj; + tok = json_tokener_new(); + obj = json_tokener_parse_ex(tok, str, -1); + if (tok->err != json_tokener_success) + obj = error_ptr(-tok->err); + json_tokener_free(tok); + return obj; } #if !HAVE_STRNDUP /* CAW: compliant version of strndup() */ -char* strndup(const char* str, size_t n) +char *strndup(const char *str, size_t n) { - if(str) { - size_t len = strlen(str); - size_t nn = min(len,n); - char* s = (char*)malloc(sizeof(char) * (nn + 1)); + if (str) { + size_t len = strlen(str); + size_t nn = min(len, n); + char *s = (char *) malloc(sizeof(char) * (nn + 1)); - if(s) { - memcpy(s, str, nn); - s[nn] = '\0'; - } + if (s) { + memcpy(s, str, nn); + s[nn] = '\0'; + } - return s; - } + return s; + } - return NULL; + return NULL; } #endif @@ -129,392 +130,393 @@ char* strndup(const char* str, size_t n) #define current tok->stack[tok->depth].current #define obj_field_name tok->stack[tok->depth].obj_field_name -struct json_object* json_tokener_parse_ex(struct json_tokener *tok, - char *str, int len) +struct json_object *json_tokener_parse_ex(struct json_tokener *tok, char *str, int len) { - struct json_object *obj = NULL; - char c; + struct json_object *obj = NULL; + char c; - tok->char_offset = 0; - tok->err = json_tokener_success; - - do { - if(tok->char_offset == len) { - if(tok->depth == 0 && state == json_tokener_state_eatws && - saved_state == json_tokener_state_finish) + tok->char_offset = 0; tok->err = json_tokener_success; - else - tok->err = json_tokener_continue; - goto out; - } - c = *str; - redo_char: - switch(state) { + do { + if (tok->char_offset == len) { + if (tok->depth == 0 && state == json_tokener_state_eatws && saved_state == json_tokener_state_finish) + tok->err = json_tokener_success; + else + tok->err = json_tokener_continue; + goto out; + } - case json_tokener_state_eatws: - if(isspace(c)) { - /* okay */ - } else if(c == '/') { - printbuf_reset(tok->pb); - printbuf_memappend(tok->pb, &c, 1); - state = json_tokener_state_comment_start; - } else { - state = saved_state; - goto redo_char; - } - break; + c = *str; + redo_char: + switch (state) { - case json_tokener_state_start: - switch(c) { - case '{': - state = json_tokener_state_eatws; - saved_state = json_tokener_state_object_field_start; - current = json_object_new_object(); - break; - case '[': - state = json_tokener_state_eatws; - saved_state = json_tokener_state_array; - current = json_object_new_array(); - break; - case 'N': - case 'n': - state = json_tokener_state_null; - printbuf_reset(tok->pb); - tok->st_pos = 0; - goto redo_char; - case '"': - case '\'': - state = json_tokener_state_string; - printbuf_reset(tok->pb); - tok->quote_char = c; - break; - case 'T': - case 't': - case 'F': - case 'f': - state = json_tokener_state_boolean; - printbuf_reset(tok->pb); - tok->st_pos = 0; - goto redo_char; + case json_tokener_state_eatws: + if (isspace(c)) { + /* okay */ + } else if (c == '/') { + printbuf_reset(tok->pb); + printbuf_memappend(tok->pb, &c, 1); + state = json_tokener_state_comment_start; + } else { + state = saved_state; + goto redo_char; + } + break; + + case json_tokener_state_start: + switch (c) { + case '{': + state = json_tokener_state_eatws; + saved_state = json_tokener_state_object_field_start; + current = json_object_new_object(); + break; + case '[': + state = json_tokener_state_eatws; + saved_state = json_tokener_state_array; + current = json_object_new_array(); + break; + case 'N': + case 'n': + state = json_tokener_state_null; + printbuf_reset(tok->pb); + tok->st_pos = 0; + goto redo_char; + case '"': + case '\'': + state = json_tokener_state_string; + printbuf_reset(tok->pb); + tok->quote_char = c; + break; + case 'T': + case 't': + case 'F': + case 'f': + state = json_tokener_state_boolean; + printbuf_reset(tok->pb); + tok->st_pos = 0; + goto redo_char; /* #if defined(__GNUC__) case '0' ... '9': #else */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': /* #endif */ - case '-': - state = json_tokener_state_number; - printbuf_reset(tok->pb); - tok->is_double = 0; - goto redo_char; - default: - tok->err = json_tokener_error_parse_unexpected; - goto out; - } - break; + case '-': + state = json_tokener_state_number; + printbuf_reset(tok->pb); + tok->is_double = 0; + goto redo_char; + default: + tok->err = json_tokener_error_parse_unexpected; + goto out; + } + break; - case json_tokener_state_finish: - if(tok->depth == 0) goto out; - obj = json_object_get(current); - json_tokener_reset_level(tok, tok->depth); - tok->depth--; - goto redo_char; + case json_tokener_state_finish: + if (tok->depth == 0) + goto out; + obj = json_object_get(current); + json_tokener_reset_level(tok, tok->depth); + tok->depth--; + goto redo_char; - case json_tokener_state_null: - printbuf_memappend(tok->pb, &c, 1); - if(strncasecmp(json_null_str, tok->pb->buf, - min(tok->st_pos+1, strlen(json_null_str))) == 0) { - if(tok->st_pos == strlen(json_null_str)) { - current = NULL; - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - goto redo_char; - } - } else { - tok->err = json_tokener_error_parse_null; - goto out; - } - tok->st_pos++; - break; + case json_tokener_state_null: + printbuf_memappend(tok->pb, &c, 1); + if (strncasecmp(json_null_str, tok->pb->buf, min(tok->st_pos + 1, strlen(json_null_str))) == 0) { + if (tok->st_pos == strlen(json_null_str)) { + current = NULL; + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + goto redo_char; + } + } else { + tok->err = json_tokener_error_parse_null; + goto out; + } + tok->st_pos++; + break; - case json_tokener_state_comment_start: - if(c == '*') { - state = json_tokener_state_comment; - } else if(c == '/') { - state = json_tokener_state_comment_eol; - } else { - tok->err = json_tokener_error_parse_comment; - goto out; - } - printbuf_memappend(tok->pb, &c, 1); - break; + case json_tokener_state_comment_start: + if (c == '*') { + state = json_tokener_state_comment; + } else if (c == '/') { + state = json_tokener_state_comment_eol; + } else { + tok->err = json_tokener_error_parse_comment; + goto out; + } + printbuf_memappend(tok->pb, &c, 1); + break; - case json_tokener_state_comment: - if(c == '*') state = json_tokener_state_comment_end; - printbuf_memappend(tok->pb, &c, 1); - break; + case json_tokener_state_comment: + if (c == '*') + state = json_tokener_state_comment_end; + printbuf_memappend(tok->pb, &c, 1); + break; - case json_tokener_state_comment_eol: - if(c == '\n') { - mc_debug("json_tokener_comment: %s\n", tok->pb->buf); - state = json_tokener_state_eatws; - } else { - printbuf_memappend(tok->pb, &c, 1); - } - break; + case json_tokener_state_comment_eol: + if (c == '\n') { + mc_debug("json_tokener_comment: %s\n", tok->pb->buf); + state = json_tokener_state_eatws; + } else { + printbuf_memappend(tok->pb, &c, 1); + } + break; - case json_tokener_state_comment_end: - printbuf_memappend(tok->pb, &c, 1); - if(c == '/') { - mc_debug("json_tokener_comment: %s\n", tok->pb->buf); - state = json_tokener_state_eatws; - } else { - state = json_tokener_state_comment; - } - break; + case json_tokener_state_comment_end: + printbuf_memappend(tok->pb, &c, 1); + if (c == '/') { + mc_debug("json_tokener_comment: %s\n", tok->pb->buf); + state = json_tokener_state_eatws; + } else { + state = json_tokener_state_comment; + } + break; - case json_tokener_state_string: - if(c == tok->quote_char) { - current = json_object_new_string(tok->pb->buf); - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - } else if(c == '\\') { - saved_state = json_tokener_state_string; - state = json_tokener_state_string_escape; - } else { - printbuf_memappend(tok->pb, &c, 1); - } - break; + case json_tokener_state_string: + if (c == tok->quote_char) { + current = json_object_new_string(tok->pb->buf); + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + } else if (c == '\\') { + saved_state = json_tokener_state_string; + state = json_tokener_state_string_escape; + } else { + printbuf_memappend(tok->pb, &c, 1); + } + break; - case json_tokener_state_string_escape: - switch(c) { - case '"': - case '\\': - case '/': - printbuf_memappend(tok->pb, &c, 1); - state = saved_state; - break; - case 'b': - case 'n': - case 'r': - case 't': - if(c == 'b') printbuf_memappend(tok->pb, "\b", 1); - else if(c == 'n') printbuf_memappend(tok->pb, "\n", 1); - else if(c == 'r') printbuf_memappend(tok->pb, "\r", 1); - else if(c == 't') printbuf_memappend(tok->pb, "\t", 1); - state = saved_state; - break; - case 'u': - tok->ucs_char = 0; - tok->st_pos = 0; - state = json_tokener_state_escape_unicode; - break; - default: - tok->err = json_tokener_error_parse_string; - goto out; - } - break; + case json_tokener_state_string_escape: + switch (c) { + case '"': + case '\\': + case '/': + printbuf_memappend(tok->pb, &c, 1); + state = saved_state; + break; + case 'b': + case 'n': + case 'r': + case 't': + if (c == 'b') + printbuf_memappend(tok->pb, "\b", 1); + else if (c == 'n') + printbuf_memappend(tok->pb, "\n", 1); + else if (c == 'r') + printbuf_memappend(tok->pb, "\r", 1); + else if (c == 't') + printbuf_memappend(tok->pb, "\t", 1); + state = saved_state; + break; + case 'u': + tok->ucs_char = 0; + tok->st_pos = 0; + state = json_tokener_state_escape_unicode; + break; + default: + tok->err = json_tokener_error_parse_string; + goto out; + } + break; - case json_tokener_state_escape_unicode: - if(strchr(json_hex_chars, c)) { - tok->ucs_char += ((unsigned int)hexdigit(c) << ((3-tok->st_pos++)*4)); - if(tok->st_pos == 4) { - unsigned char utf_out[3]; - if (tok->ucs_char < 0x80) { - utf_out[0] = tok->ucs_char; - printbuf_memappend(tok->pb, (char*)utf_out, 1); - } else if (tok->ucs_char < 0x800) { - utf_out[0] = 0xc0 | (tok->ucs_char >> 6); - utf_out[1] = 0x80 | (tok->ucs_char & 0x3f); - printbuf_memappend(tok->pb, (char*)utf_out, 2); - } else { - utf_out[0] = 0xe0 | (tok->ucs_char >> 12); - utf_out[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f); - utf_out[2] = 0x80 | (tok->ucs_char & 0x3f); - printbuf_memappend(tok->pb, (char*)utf_out, 3); - } - state = saved_state; - } - } else { - tok->err = json_tokener_error_parse_string; - goto out; - } - break; + case json_tokener_state_escape_unicode: + if (strchr(json_hex_chars, c)) { + tok->ucs_char += ((unsigned int) hexdigit(c) << ((3 - tok->st_pos++) * 4)); + if (tok->st_pos == 4) { + unsigned char utf_out[3]; + if (tok->ucs_char < 0x80) { + utf_out[0] = tok->ucs_char; + printbuf_memappend(tok->pb, (char *) utf_out, 1); + } else if (tok->ucs_char < 0x800) { + utf_out[0] = 0xc0 | (tok->ucs_char >> 6); + utf_out[1] = 0x80 | (tok->ucs_char & 0x3f); + printbuf_memappend(tok->pb, (char *) utf_out, 2); + } else { + utf_out[0] = 0xe0 | (tok->ucs_char >> 12); + utf_out[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f); + utf_out[2] = 0x80 | (tok->ucs_char & 0x3f); + printbuf_memappend(tok->pb, (char *) utf_out, 3); + } + state = saved_state; + } + } else { + tok->err = json_tokener_error_parse_string; + goto out; + } + break; - case json_tokener_state_boolean: - printbuf_memappend(tok->pb, &c, 1); - if(strncasecmp(json_true_str, tok->pb->buf, - min(tok->st_pos+1, strlen(json_true_str))) == 0) { - if(tok->st_pos == strlen(json_true_str)) { - current = json_object_new_boolean(1); - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - goto redo_char; - } - } else if(strncasecmp(json_false_str, tok->pb->buf, - min(tok->st_pos+1, strlen(json_false_str))) == 0) { - if(tok->st_pos == strlen(json_false_str)) { - current = json_object_new_boolean(0); - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - goto redo_char; - } - } else { - tok->err = json_tokener_error_parse_boolean; - goto out; - } - tok->st_pos++; - break; + case json_tokener_state_boolean: + printbuf_memappend(tok->pb, &c, 1); + if (strncasecmp(json_true_str, tok->pb->buf, min(tok->st_pos + 1, strlen(json_true_str))) == 0) { + if (tok->st_pos == strlen(json_true_str)) { + current = json_object_new_boolean(1); + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + goto redo_char; + } + } else if (strncasecmp(json_false_str, tok->pb->buf, min(tok->st_pos + 1, strlen(json_false_str))) == 0) { + if (tok->st_pos == strlen(json_false_str)) { + current = json_object_new_boolean(0); + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + goto redo_char; + } + } else { + tok->err = json_tokener_error_parse_boolean; + goto out; + } + tok->st_pos++; + break; - case json_tokener_state_number: - if(c && strchr(json_number_chars, c)) { - printbuf_memappend(tok->pb, &c, 1); - if(c == '.' || c == 'e') tok->is_double = 1; - } else { - int numi; - double numd; - if(!tok->is_double && sscanf(tok->pb->buf, "%d", &numi) == 1) { - current = json_object_new_int(numi); - } else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) { - current = json_object_new_double(numd); - } else { - tok->err = json_tokener_error_parse_number; - goto out; - } - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - goto redo_char; - } - break; + case json_tokener_state_number: + if (c && strchr(json_number_chars, c)) { + printbuf_memappend(tok->pb, &c, 1); + if (c == '.' || c == 'e') + tok->is_double = 1; + } else { + int numi; + double numd; + if (!tok->is_double && sscanf(tok->pb->buf, "%d", &numi) == 1) { + current = json_object_new_int(numi); + } else if (tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) { + current = json_object_new_double(numd); + } else { + tok->err = json_tokener_error_parse_number; + goto out; + } + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + goto redo_char; + } + break; - case json_tokener_state_array: - if(c == ']') { - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - } else { - if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) { - tok->err = json_tokener_error_depth; - goto out; - } - state = json_tokener_state_array_add; - tok->depth++; - json_tokener_reset_level(tok, tok->depth); - goto redo_char; - } - break; + case json_tokener_state_array: + if (c == ']') { + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + } else { + if (tok->depth >= JSON_TOKENER_MAX_DEPTH - 1) { + tok->err = json_tokener_error_depth; + goto out; + } + state = json_tokener_state_array_add; + tok->depth++; + json_tokener_reset_level(tok, tok->depth); + goto redo_char; + } + break; - case json_tokener_state_array_add: - json_object_array_add(current, obj); - saved_state = json_tokener_state_array_sep; - state = json_tokener_state_eatws; - goto redo_char; + case json_tokener_state_array_add: + json_object_array_add(current, obj); + saved_state = json_tokener_state_array_sep; + state = json_tokener_state_eatws; + goto redo_char; - case json_tokener_state_array_sep: - if(c == ']') { - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - } else if(c == ',') { - saved_state = json_tokener_state_array; - state = json_tokener_state_eatws; - } else { - tok->err = json_tokener_error_parse_array; - goto out; - } - break; + case json_tokener_state_array_sep: + if (c == ']') { + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + } else if (c == ',') { + saved_state = json_tokener_state_array; + state = json_tokener_state_eatws; + } else { + tok->err = json_tokener_error_parse_array; + goto out; + } + break; - case json_tokener_state_object_field_start: - if(c == '}') { - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - } else if (c == '"' || c == '\'') { - tok->quote_char = c; - printbuf_reset(tok->pb); - state = json_tokener_state_object_field; - } else { - tok->err = json_tokener_error_parse_object_key_name; - goto out; - } - break; + case json_tokener_state_object_field_start: + if (c == '}') { + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + } else if (c == '"' || c == '\'') { + tok->quote_char = c; + printbuf_reset(tok->pb); + state = json_tokener_state_object_field; + } else { + tok->err = json_tokener_error_parse_object_key_name; + goto out; + } + break; - case json_tokener_state_object_field: - if(c == tok->quote_char) { - obj_field_name = strdup(tok->pb->buf); - saved_state = json_tokener_state_object_field_end; - state = json_tokener_state_eatws; - } else if(c == '\\') { - saved_state = json_tokener_state_object_field; - state = json_tokener_state_string_escape; - } else { - printbuf_memappend(tok->pb, &c, 1); - } - break; + case json_tokener_state_object_field: + if (c == tok->quote_char) { + obj_field_name = strdup(tok->pb->buf); + saved_state = json_tokener_state_object_field_end; + state = json_tokener_state_eatws; + } else if (c == '\\') { + saved_state = json_tokener_state_object_field; + state = json_tokener_state_string_escape; + } else { + printbuf_memappend(tok->pb, &c, 1); + } + break; - case json_tokener_state_object_field_end: - if(c == ':') { - saved_state = json_tokener_state_object_value; - state = json_tokener_state_eatws; - } else { - tok->err = json_tokener_error_parse_object_key_sep; - goto out; - } - break; + case json_tokener_state_object_field_end: + if (c == ':') { + saved_state = json_tokener_state_object_value; + state = json_tokener_state_eatws; + } else { + tok->err = json_tokener_error_parse_object_key_sep; + goto out; + } + break; - case json_tokener_state_object_value: - if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) { - tok->err = json_tokener_error_depth; - goto out; - } - state = json_tokener_state_object_value_add; - tok->depth++; - json_tokener_reset_level(tok, tok->depth); - goto redo_char; + case json_tokener_state_object_value: + if (tok->depth >= JSON_TOKENER_MAX_DEPTH - 1) { + tok->err = json_tokener_error_depth; + goto out; + } + state = json_tokener_state_object_value_add; + tok->depth++; + json_tokener_reset_level(tok, tok->depth); + goto redo_char; - case json_tokener_state_object_value_add: - json_object_object_add(current, obj_field_name, obj); - free(obj_field_name); - obj_field_name = NULL; - saved_state = json_tokener_state_object_sep; - state = json_tokener_state_eatws; - goto redo_char; + case json_tokener_state_object_value_add: + json_object_object_add(current, obj_field_name, obj); + free(obj_field_name); + obj_field_name = NULL; + saved_state = json_tokener_state_object_sep; + state = json_tokener_state_eatws; + goto redo_char; - case json_tokener_state_object_sep: - if(c == '}') { - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - } else if(c == ',') { - saved_state = json_tokener_state_object_field_start; - state = json_tokener_state_eatws; - } else { - tok->err = json_tokener_error_parse_object_value_sep; - goto out; - } - break; + case json_tokener_state_object_sep: + if (c == '}') { + saved_state = json_tokener_state_finish; + state = json_tokener_state_eatws; + } else if (c == ',') { + saved_state = json_tokener_state_object_field_start; + state = json_tokener_state_eatws; + } else { + tok->err = json_tokener_error_parse_object_value_sep; + goto out; + } + break; - } - str++; - tok->char_offset++; - } while(c); + } + str++; + tok->char_offset++; + } while (c); - if(state != json_tokener_state_finish && - saved_state != json_tokener_state_finish) - tok->err = json_tokener_error_parse_eof; + if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish) + tok->err = json_tokener_error_parse_eof; - out: - if(tok->err == json_tokener_success) return json_object_get(current); - mc_debug("json_tokener_parse_ex: error %s at offset %d\n", - json_tokener_errors[tok->err], tok->char_offset); - return NULL; + out: + if (tok->err == json_tokener_success) + return json_object_get(current); + mc_debug("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err], tok->char_offset); + return NULL; } diff --git a/src/mod/applications/mod_http/json_tokener.h b/src/mod/applications/mod_http/json_tokener.h index d2c21270f4..5d79489a13 100644 --- a/src/mod/applications/mod_http/json_tokener.h +++ b/src/mod/applications/mod_http/json_tokener.h @@ -15,75 +15,72 @@ #include "json_object.h" enum json_tokener_error { - json_tokener_success, - json_tokener_continue, - json_tokener_error_depth, - json_tokener_error_parse_eof, - json_tokener_error_parse_unexpected, - json_tokener_error_parse_null, - json_tokener_error_parse_boolean, - json_tokener_error_parse_number, - json_tokener_error_parse_array, - json_tokener_error_parse_object_key_name, - json_tokener_error_parse_object_key_sep, - json_tokener_error_parse_object_value_sep, - json_tokener_error_parse_string, - json_tokener_error_parse_comment + json_tokener_success, + json_tokener_continue, + json_tokener_error_depth, + json_tokener_error_parse_eof, + json_tokener_error_parse_unexpected, + json_tokener_error_parse_null, + json_tokener_error_parse_boolean, + json_tokener_error_parse_number, + json_tokener_error_parse_array, + json_tokener_error_parse_object_key_name, + json_tokener_error_parse_object_key_sep, + json_tokener_error_parse_object_value_sep, + json_tokener_error_parse_string, + json_tokener_error_parse_comment }; enum json_tokener_state { - json_tokener_state_eatws, - json_tokener_state_start, - json_tokener_state_finish, - json_tokener_state_null, - json_tokener_state_comment_start, - json_tokener_state_comment, - json_tokener_state_comment_eol, - json_tokener_state_comment_end, - json_tokener_state_string, - json_tokener_state_string_escape, - json_tokener_state_escape_unicode, - json_tokener_state_boolean, - json_tokener_state_number, - json_tokener_state_array, - json_tokener_state_array_add, - json_tokener_state_array_sep, - json_tokener_state_object_field_start, - json_tokener_state_object_field, - json_tokener_state_object_field_end, - json_tokener_state_object_value, - json_tokener_state_object_value_add, - json_tokener_state_object_sep + json_tokener_state_eatws, + json_tokener_state_start, + json_tokener_state_finish, + json_tokener_state_null, + json_tokener_state_comment_start, + json_tokener_state_comment, + json_tokener_state_comment_eol, + json_tokener_state_comment_end, + json_tokener_state_string, + json_tokener_state_string_escape, + json_tokener_state_escape_unicode, + json_tokener_state_boolean, + json_tokener_state_number, + json_tokener_state_array, + json_tokener_state_array_add, + json_tokener_state_array_sep, + json_tokener_state_object_field_start, + json_tokener_state_object_field, + json_tokener_state_object_field_end, + json_tokener_state_object_value, + json_tokener_state_object_value_add, + json_tokener_state_object_sep }; -struct json_tokener_srec -{ - enum json_tokener_state state, saved_state; - struct json_object *obj; - struct json_object *current; - char *obj_field_name; +struct json_tokener_srec { + enum json_tokener_state state, saved_state; + struct json_object *obj; + struct json_object *current; + char *obj_field_name; }; #define JSON_TOKENER_MAX_DEPTH 32 -struct json_tokener -{ - char *str; - struct printbuf *pb; - int depth, is_double, st_pos, char_offset; - enum json_tokener_error err; - unsigned int ucs_char; - char quote_char; - struct json_tokener_srec stack[JSON_TOKENER_MAX_DEPTH]; +struct json_tokener { + char *str; + struct printbuf *pb; + int depth, is_double, st_pos, char_offset; + enum json_tokener_error err; + unsigned int ucs_char; + char quote_char; + struct json_tokener_srec stack[JSON_TOKENER_MAX_DEPTH]; }; -extern const char* json_tokener_errors[]; +extern const char *json_tokener_errors[]; -extern struct json_tokener* json_tokener_new(); +extern struct json_tokener *json_tokener_new(); extern void json_tokener_free(struct json_tokener *tok); extern void json_tokener_reset(struct json_tokener *tok); -extern struct json_object* json_tokener_parse(char *str); -extern struct json_object* json_tokener_parse_ex(struct json_tokener *tok, - char *str, int len); +extern struct json_object *json_tokener_parse(char *str); +extern struct json_object *json_tokener_parse_ex(struct json_tokener *tok, char *str, int len); #endif diff --git a/src/mod/applications/mod_http/json_util.c b/src/mod/applications/mod_http/json_util.c index e20be24038..f07e726827 100644 --- a/src/mod/applications/mod_http/json_util.c +++ b/src/mod/applications/mod_http/json_util.c @@ -51,71 +51,69 @@ #include "json_tokener.h" #include "json_util.h" -struct json_object* json_object_from_file(char *filename) +struct json_object *json_object_from_file(char *filename) { - struct printbuf *pb; - struct json_object *obj; - char buf[JSON_FILE_BUF_SIZE]; - int fd, ret; + struct printbuf *pb; + struct json_object *obj; + char buf[JSON_FILE_BUF_SIZE]; + int fd, ret; - if((fd = open(filename, O_RDONLY)) < 0) { - mc_error("json_object_from_file: error reading file %s: %s\n", - filename, strerror(errno)); - return error_ptr(-1); - } - if(!(pb = printbuf_new())) { - mc_error("json_object_from_file: printbuf_new failed\n"); - return error_ptr(-1); - } - while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) { - printbuf_memappend(pb, buf, ret); - } - close(fd); - if(ret < 0) { - mc_abort("json_object_from_file: error reading file %s: %s\n", - filename, strerror(errno)); - printbuf_free(pb); - return error_ptr(-1); - } - obj = json_tokener_parse(pb->buf); - printbuf_free(pb); - return obj; + if ((fd = open(filename, O_RDONLY)) < 0) { + mc_error("json_object_from_file: error reading file %s: %s\n", filename, strerror(errno)); + return error_ptr(-1); + } + if (!(pb = printbuf_new())) { + mc_error("json_object_from_file: printbuf_new failed\n"); + return error_ptr(-1); + } + while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) { + printbuf_memappend(pb, buf, ret); + } + close(fd); + if (ret < 0) { + mc_abort("json_object_from_file: error reading file %s: %s\n", filename, strerror(errno)); + printbuf_free(pb); + return error_ptr(-1); + } + obj = json_tokener_parse(pb->buf); + printbuf_free(pb); + return obj; } int json_object_to_file(char *filename, struct json_object *obj) { - char *json_str; - int fd, ret; - unsigned int wpos, wsize; + char *json_str; + int fd, ret; + unsigned int wpos, wsize; - if(!obj) { - mc_error("json_object_to_file: object is null\n"); - return -1; - } + if (!obj) { + mc_error("json_object_to_file: object is null\n"); + return -1; + } - if((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) { - mc_error("json_object_to_file: error opening file %s: %s\n", - filename, strerror(errno)); - return -1; - } + if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) { + mc_error("json_object_to_file: error opening file %s: %s\n", filename, strerror(errno)); + return -1; + } - if(!(json_str = json_object_to_json_string(obj))) { return -1; } + if (!(json_str = json_object_to_json_string(obj))) { + return -1; + } - wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */ - wpos = 0; - while(wpos < wsize) { - if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) { - close(fd); - mc_error("json_object_to_file: error writing file %s: %s\n", - filename, strerror(errno)); - return -1; - } + wsize = (unsigned int) (strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */ + wpos = 0; + while (wpos < wsize) { + if ((ret = write(fd, json_str + wpos, wsize - wpos)) < 0) { + close(fd); + mc_error("json_object_to_file: error writing file %s: %s\n", filename, strerror(errno)); + return -1; + } - /* because of the above check for ret < 0, we can safely cast and add */ - wpos += (unsigned int)ret; - } + /* because of the above check for ret < 0, we can safely cast and add */ + wpos += (unsigned int) ret; + } - close(fd); - return 0; + close(fd); + return 0; } diff --git a/src/mod/applications/mod_http/json_util.h b/src/mod/applications/mod_http/json_util.h index 30fe2ab2c4..2dc87ad1e8 100644 --- a/src/mod/applications/mod_http/json_util.h +++ b/src/mod/applications/mod_http/json_util.h @@ -17,7 +17,7 @@ #define JSON_FILE_BUF_SIZE 4096 /* utlitiy functions */ -extern struct json_object* json_object_from_file(char *filename); +extern struct json_object *json_object_from_file(char *filename); extern int json_object_to_file(char *filename, struct json_object *obj); #endif diff --git a/src/mod/applications/mod_http/linkhash.c b/src/mod/applications/mod_http/linkhash.c index 818d3dd7b5..adc704810f 100644 --- a/src/mod/applications/mod_http/linkhash.c +++ b/src/mod/applications/mod_http/linkhash.c @@ -31,7 +31,7 @@ void lh_abort(const char *msg, ...) uint32_t lh_ptr_hash(void *k) { /* CAW: refactored to be 64bit nice */ - return (uint32_t)((((ptrdiff_t)k * LH_PRIME) >> 4) & ULONG_MAX); + return (uint32_t) ((((ptrdiff_t) k * LH_PRIME) >> 4) & ULONG_MAX); } int lh_ptr_equal(void *k1, void *k2) @@ -42,48 +42,47 @@ int lh_ptr_equal(void *k1, void *k2) uint32_t lh_char_hash(void *k) { unsigned int h = 0; - const char* data = k; - - while( *data!=0 ) h = h*129 + (unsigned int)(*data++) + LH_PRIME; + const char *data = k; + + while (*data != 0) + h = h * 129 + (unsigned int) (*data++) + LH_PRIME; return h; } int lh_char_equal(void *k1, void *k2) { - return (strcmp((char*)k1, (char*)k2) == 0); + return (strcmp((char *) k1, (char *) k2) == 0); } -struct lh_table* lh_table_new(int size, char *name, - lh_entry_free_fn *free_fn, - lh_hash_fn *hash_fn, - lh_equal_fn *equal_fn) +struct lh_table *lh_table_new(int size, char *name, lh_entry_free_fn * free_fn, lh_hash_fn * hash_fn, lh_equal_fn * equal_fn) { int i; struct lh_table *t; t = calloc(1, sizeof(struct lh_table)); - if(!t) lh_abort("lh_table_new: calloc failed\n"); + if (!t) + lh_abort("lh_table_new: calloc failed\n"); t->count = 0; t->size = size; t->name = name; t->table = calloc(size, sizeof(struct lh_entry)); - if(!t->table) lh_abort("lh_table_new: calloc failed\n"); + if (!t->table) + lh_abort("lh_table_new: calloc failed\n"); t->free_fn = free_fn; t->hash_fn = hash_fn; t->equal_fn = equal_fn; - for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY; + for (i = 0; i < size; i++) + t->table[i].k = LH_EMPTY; return t; } -struct lh_table* lh_kchar_table_new(int size, char *name, - lh_entry_free_fn *free_fn) +struct lh_table *lh_kchar_table_new(int size, char *name, lh_entry_free_fn * free_fn) { return lh_table_new(size, name, free_fn, lh_char_hash, lh_char_equal); } -struct lh_table* lh_kptr_table_new(int size, char *name, - lh_entry_free_fn *free_fn) +struct lh_table *lh_kptr_table_new(int size, char *name, lh_entry_free_fn * free_fn) { return lh_table_new(size, name, free_fn, lh_ptr_hash, lh_ptr_equal); } @@ -95,7 +94,7 @@ void lh_table_resize(struct lh_table *t, int new_size) new_t = lh_table_new(new_size, t->name, NULL, t->hash_fn, t->equal_fn); ent = t->head; - while(ent) { + while (ent) { lh_table_insert(new_t, ent->k, ent->v); ent = ent->next; } @@ -111,8 +110,8 @@ void lh_table_resize(struct lh_table *t, int new_size) void lh_table_free(struct lh_table *t) { struct lh_entry *c; - for(c = t->head; c != NULL; c = c->next) { - if(t->free_fn) { + for (c = t->head; c != NULL; c = c->next) { + if (t->free_fn) { t->free_fn(c); } } @@ -126,22 +125,25 @@ int lh_table_insert(struct lh_table *t, void *k, void *v) uint32_t h, n; t->inserts++; - if(t->count > t->size * 0.66) lh_table_resize(t, t->size * 2); + if (t->count > t->size * 0.66) + lh_table_resize(t, t->size * 2); h = t->hash_fn(k); n = h % t->size; - while( 1 ) { - if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) break; + while (1) { + if (t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) + break; t->collisions++; - if(++n == t->size) n = 0; + if (++n == t->size) + n = 0; } t->table[n].k = k; t->table[n].v = v; t->count++; - if(t->head == NULL) { + if (t->head == NULL) { t->head = t->tail = &t->table[n]; t->table[n].next = t->table[n].prev = NULL; } else { @@ -155,43 +157,50 @@ int lh_table_insert(struct lh_table *t, void *k, void *v) } -struct lh_entry* lh_table_lookup_entry(struct lh_table *t, void *k) +struct lh_entry *lh_table_lookup_entry(struct lh_table *t, void *k) { uint32_t h = t->hash_fn(k); uint32_t n = h % t->size; t->lookups++; - while( 1 ) { - if(t->table[n].k == LH_EMPTY) return NULL; - if(t->table[n].k != LH_FREED && - t->equal_fn(t->table[n].k, k)) return &t->table[n]; - if(++n == t->size) n = 0; + while (1) { + if (t->table[n].k == LH_EMPTY) + return NULL; + if (t->table[n].k != LH_FREED && t->equal_fn(t->table[n].k, k)) + return &t->table[n]; + if (++n == t->size) + n = 0; } return NULL; } -void* lh_table_lookup(struct lh_table *t, void *k) +void *lh_table_lookup(struct lh_table *t, void *k) { struct lh_entry *e = lh_table_lookup_entry(t, k); - if(e) return e->v; + if (e) + return e->v; return NULL; } int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e) { - ptrdiff_t n = (ptrdiff_t)(e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */ + ptrdiff_t n = (ptrdiff_t) (e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */ /* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */ - if(n < 0) { return -2; } + if (n < 0) { + return -2; + } - if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) return -1; + if (t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) + return -1; t->count--; - if(t->free_fn) t->free_fn(e); + if (t->free_fn) + t->free_fn(e); t->table[n].v = NULL; t->table[n].k = LH_FREED; - if(t->tail == &t->table[n] && t->head == &t->table[n]) { + if (t->tail == &t->table[n] && t->head == &t->table[n]) { t->head = t->tail = NULL; } else if (t->head == &t->table[n]) { t->head->next->prev = NULL; @@ -211,7 +220,7 @@ int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e) int lh_table_delete(struct lh_table *t, void *k) { struct lh_entry *e = lh_table_lookup_entry(t, k); - if(!e) return -1; + if (!e) + return -1; return lh_table_delete_entry(t, e); } - diff --git a/src/mod/applications/mod_http/linkhash.h b/src/mod/applications/mod_http/linkhash.h index 21b62e3049..ea3fb54b15 100644 --- a/src/mod/applications/mod_http/linkhash.h +++ b/src/mod/applications/mod_http/linkhash.h @@ -8,7 +8,7 @@ * it under the terms of the MIT license. See COPYING for details. * */ - + #ifndef _linkhash_h_ #define _linkhash_h_ #include @@ -33,11 +33,11 @@ struct lh_entry; /** * callback function prototypes */ -typedef void (lh_entry_free_fn) (struct lh_entry *e); +typedef void (lh_entry_free_fn) (struct lh_entry * e); /** * callback function prototypes */ -typedef uint32_t (lh_hash_fn) (void *k); +typedef uint32_t(lh_hash_fn) (void *k); /** * callback function prototypes */ @@ -171,10 +171,7 @@ for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp) * and C strings respectively. * @return a pointer onto the linkhash table. */ -extern struct lh_table* lh_table_new(int size, char *name, - lh_entry_free_fn *free_fn, - lh_hash_fn *hash_fn, - lh_equal_fn *equal_fn); +extern struct lh_table *lh_table_new(int size, char *name, lh_entry_free_fn * free_fn, lh_hash_fn * hash_fn, lh_equal_fn * equal_fn); /** * Convenience function to create a new linkhash @@ -184,8 +181,7 @@ extern struct lh_table* lh_table_new(int size, char *name, * @param free_fn callback function used to free memory for entries. * @return a pointer onto the linkhash table. */ -extern struct lh_table* lh_kchar_table_new(int size, char *name, - lh_entry_free_fn *free_fn); +extern struct lh_table *lh_kchar_table_new(int size, char *name, lh_entry_free_fn * free_fn); /** @@ -196,8 +192,7 @@ extern struct lh_table* lh_kchar_table_new(int size, char *name, * @param free_fn callback function used to free memory for entries. * @return a pointer onto the linkhash table. */ -extern struct lh_table* lh_kptr_table_new(int size, char *name, - lh_entry_free_fn *free_fn); +extern struct lh_table *lh_kptr_table_new(int size, char *name, lh_entry_free_fn * free_fn); /** @@ -224,7 +219,7 @@ extern int lh_table_insert(struct lh_table *t, void *k, void *v); * @param k a pointer to the key to lookup * @return a pointer to the record structure of the value or NULL if it does not exist. */ -extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, void *k); +extern struct lh_entry *lh_table_lookup_entry(struct lh_table *t, void *k); /** * Lookup a record into the table @@ -232,7 +227,7 @@ extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, void *k); * @param k a pointer to the key to lookup * @return a pointer to the found value or NULL if it does not exist. */ -extern void* lh_table_lookup(struct lh_table *t, void *k); +extern void *lh_table_lookup(struct lh_table *t, void *k); /** diff --git a/src/mod/applications/mod_http/mod_http.c b/src/mod/applications/mod_http/mod_http.c index 2984d3802d..313d169a04 100644 --- a/src/mod/applications/mod_http/mod_http.c +++ b/src/mod/applications/mod_http/mod_http.c @@ -90,287 +90,279 @@ GARBAGE_TYPES_INIT(); SWITCH_STANDARD_API(http_api_main) { - char *ccmd; - int argc; - char *argv[HTTP_PARAMS]; - char *buf; - char *method; - char *url; - char *headers_dec; - char *headers_str; - char *value; - char *body; - char *body_dec; - char *t; - char *json_response; - struct json_object *json_http_headers; - char *key; - struct json_object *val; - enum json_type jsontype; - struct lh_entry *entry; - int i; - int j; - int f; - size_t l; - size_t m; - size_t a = 0; - int ret; + char *ccmd; + int argc; + char *argv[HTTP_PARAMS]; + char *buf; + char *method; + char *url; + char *headers_dec; + char *headers_str; + char *value; + char *body; + char *body_dec; + char *t; + char *json_response; + struct json_object *json_http_headers; + char *key; + struct json_object *val; + enum json_type jsontype; + struct lh_entry *entry; + int i; + int j; + int f; + size_t l; + size_t m; + size_t a = 0; + int ret; - http_header_t *headers; - http_request_t request; - http_response_t response; + http_header_t *headers; + http_request_t request; + http_response_t response; - GARBAGE_INIT(); - - (void)memset(&response, 0, sizeof(response)); + GARBAGE_INIT(); - if(cmd == NULL){ - stream->write_function(stream, "-USAGE: %s\n", HTTP_SYNTAX); - return SWITCH_STATUS_SUCCESS; - } + (void) memset(&response, 0, sizeof(response)); - ccmd = strdup(cmd); - argc = switch_separate_string(ccmd, ' ', argv, HTTP_PARAMS); - - if(argc != HTTP_PARAMS && argc != (HTTP_PARAMS - 1)){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - return SWITCH_STATUS_SUCCESS; - } - - method = argv[0]; - if(strcasecmp( "GET", method) == 0) request.method = GET; - else if(strcasecmp("POST", method) == 0) request.method = POST; - else if(strcasecmp("HEAD", method) == 0) request.method = HEAD; - else if(strcasecmp("DELETE", method) == 0) request.method = DELETE; - else if(strcasecmp("PUT", method) == 0) request.method = PUT; - - - - url = argv[1]; - headers_str = argv[2]; - if(argc == HTTP_PARAMS){ - body = argv[3]; - }else{ - body = (char *)malloc(1 * sizeof(char)); - if(body == NULL){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - return SWITCH_STATUS_SUCCESS; - } - body[0] = '\0'; - GARBAGE_ADD(body); - } - - buf = (char *)malloc(HTTP_BUFFER_SIZE * sizeof(char)); - if(buf == NULL){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - GARBAGE_CLEANUP(); - return SWITCH_STATUS_SUCCESS; - } - - GARBAGE_ADD(buf); - - request.version = DEFAULT_HTTP_VERSION; - l = strlen(url); - request.url = (char *)malloc((l + 1) * sizeof(char)); - if(request.url == NULL){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - GARBAGE_CLEANUP(); - return SWITCH_STATUS_SUCCESS; - } - - GARBAGE_ADD(request.url); - strcpy(request.url, url); - - - l = strlen(headers_str); - - headers_dec = url_decode(headers_str, l); - GARBAGE_ADD(headers_dec); - - json_http_headers = json_tokener_parse(headers_dec); - if(is_error(json_http_headers)){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - GARBAGE_CLEANUP(); - return SWITCH_STATUS_SUCCESS; - } - - jsontype = json_object_get_type(json_http_headers); - if(jsontype != json_type_object){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - GARBAGE_CLEANUP(); - return SWITCH_STATUS_SUCCESS; - } - - i = 0; - json_object_object_foreach(json_http_headers, key, val){ - i++; - } - - request.header_len = i; - headers = (http_header_t *)malloc(i * sizeof(http_header_t)); - request.headers = headers; - GARBAGE_ADD(headers); - - i = 0; - json_object_object_foreach(json_http_headers, key, val){ - l = strlen(key); - - request.headers[i].field_name = (char *)malloc((l + 1) * sizeof(char)); - if(request.headers[i].field_name == NULL){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - GARBAGE_CLEANUP(); - return SWITCH_STATUS_SUCCESS; - } - - GARBAGE_ADD(request.headers[i].field_name); - - strcpy(request.headers[i].field_name, key); - a += strlen(key); - - jsontype = json_object_get_type(val); - if(jsontype != json_type_string){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - GARBAGE_CLEANUP(); - return SWITCH_STATUS_SUCCESS; + if (cmd == NULL) { + stream->write_function(stream, "-USAGE: %s\n", HTTP_SYNTAX); + return SWITCH_STATUS_SUCCESS; } - value = json_object_get_string(val); - /* value = json_object_to_json_string(val); */ - l = strlen(value); - request.headers[i].value = (char *)malloc((l + 1) * sizeof(char)); - if(request.headers[i].value == NULL){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - GARBAGE_CLEANUP(); - return SWITCH_STATUS_SUCCESS; - } - GARBAGE_ADD(request.headers[i].value); - strcpy(request.headers[i].value, value); - a += strlen(value); - i++; - } + ccmd = strdup(cmd); + argc = switch_separate_string(ccmd, ' ', argv, HTTP_PARAMS); - if(argc == HTTP_PARAMS){ - l = strlen(body); - body_dec = url_decode(body, l); - GARBAGE_ADD(body_dec); - l = strlen(body_dec); - request.body_len = l; - request.body = body_dec; - }else request.body_len = 0; + if (argc != HTTP_PARAMS && argc != (HTTP_PARAMS - 1)) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + return SWITCH_STATUS_SUCCESS; + } - ret = http_req(&request, &response); - - if(response.version != NULL) GARBAGE_ADD(response.version); - if(response.phrase != NULL) GARBAGE_ADD(response.phrase); - if(response.headers != NULL) GARBAGE_ADD(response.headers); - if(response.body != NULL) GARBAGE_ADD(response.body); - for(i = 0; i < response.header_len; i++){ - GARBAGE_ADD(response.headers[i].field_name); - GARBAGE_ADD(response.headers[i].value); - } - - - if(ret == ERROR){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - GARBAGE_CLEANUP(); - return SWITCH_STATUS_SUCCESS; - } - - /* This is evil and should be changed in the future */ - l = 128 + (256 * response.header_len) + (a * 2) - + strlen("version") + strlen(response.version) - + strlen("status_code") + 3 - + strlen("phrase") + strlen(response.phrase) - + strlen("body") + (response.body_len * 3) + 1 - + strlen("headers") - + 1; - - /* to be safe */ - l <<= 2; - - json_response = (char *)malloc(l * sizeof(char)); - if(json_response == NULL){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - GARBAGE_CLEANUP(); - return SWITCH_STATUS_SUCCESS; - } - GARBAGE_ADD(json_response); - - if(response.body_len != 0){ - t = (char *)malloc((response.body_len + 1) * sizeof(char)); - if(t == NULL){ - switch_safe_free(ccmd); - stream->write_function(stream, "-ERR\n"); - GARBAGE_CLEANUP(); - return SWITCH_STATUS_SUCCESS; - } - GARBAGE_ADD(t); - (void)memcpy(t, response.body, response.body_len); - t[response.body_len] = '\0'; - response.body = url_encode(t, response.body_len); - GARBAGE_ADD(response.body); - } - - - m = snprintf(json_response, l, - "{" - "\"version\": \"%s\"," - "\"status_code\": \"%3d\"," - "\"phrase\": \"%s\"," - "\"body\": \"%s\"," - "\"headers\": [", - response.version, - response.status_code, - response.phrase, - ((response.body_len <= 0)? "":response.body) - ); + method = argv[0]; + if (strcasecmp("GET", method) == 0) + request.method = GET; + else if (strcasecmp("POST", method) == 0) + request.method = POST; + else if (strcasecmp("HEAD", method) == 0) + request.method = HEAD; + else if (strcasecmp("DELETE", method) == 0) + request.method = DELETE; + else if (strcasecmp("PUT", method) == 0) + request.method = PUT; - for(f = HTTP_FALSE, j = 0; j < response.header_len; j++){ - if(f != HTTP_FALSE){ - m += snprintf(json_response + m, l - m, - "," - ); - }else f = HTTP_TRUE; - m += snprintf(json_response + m, l - m, - "{\"key\": \"%s\",\"value\": \"%s\"}", - response.headers[j].field_name, - response.headers[j].value - ); - } + url = argv[1]; + headers_str = argv[2]; + if (argc == HTTP_PARAMS) { + body = argv[3]; + } else { + body = (char *) malloc(1 * sizeof(char)); + if (body == NULL) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + return SWITCH_STATUS_SUCCESS; + } + body[0] = '\0'; + GARBAGE_ADD(body); + } + + buf = (char *) malloc(HTTP_BUFFER_SIZE * sizeof(char)); + if (buf == NULL) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + GARBAGE_CLEANUP(); + return SWITCH_STATUS_SUCCESS; + } + + GARBAGE_ADD(buf); + + request.version = DEFAULT_HTTP_VERSION; + l = strlen(url); + request.url = (char *) malloc((l + 1) * sizeof(char)); + if (request.url == NULL) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + GARBAGE_CLEANUP(); + return SWITCH_STATUS_SUCCESS; + } + + GARBAGE_ADD(request.url); + strcpy(request.url, url); - m += snprintf(json_response + m, l - m, "]}"); - json_response[m] = '\0'; + l = strlen(headers_str); + + headers_dec = url_decode(headers_str, l); + GARBAGE_ADD(headers_dec); + + json_http_headers = json_tokener_parse(headers_dec); + if (is_error(json_http_headers)) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + GARBAGE_CLEANUP(); + return SWITCH_STATUS_SUCCESS; + } + + jsontype = json_object_get_type(json_http_headers); + if (jsontype != json_type_object) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + GARBAGE_CLEANUP(); + return SWITCH_STATUS_SUCCESS; + } + + i = 0; + json_object_object_foreach(json_http_headers, key, val) { + i++; + } + + request.header_len = i; + headers = (http_header_t *) malloc(i * sizeof(http_header_t)); + request.headers = headers; + GARBAGE_ADD(headers); + + i = 0; + json_object_object_foreach(json_http_headers, key, val) { + l = strlen(key); + + request.headers[i].field_name = (char *) malloc((l + 1) * sizeof(char)); + if (request.headers[i].field_name == NULL) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + GARBAGE_CLEANUP(); + return SWITCH_STATUS_SUCCESS; + } + + GARBAGE_ADD(request.headers[i].field_name); + + strcpy(request.headers[i].field_name, key); + a += strlen(key); + + jsontype = json_object_get_type(val); + if (jsontype != json_type_string) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + GARBAGE_CLEANUP(); + return SWITCH_STATUS_SUCCESS; + } + + value = json_object_get_string(val); + /* value = json_object_to_json_string(val); */ + l = strlen(value); + request.headers[i].value = (char *) malloc((l + 1) * sizeof(char)); + if (request.headers[i].value == NULL) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + GARBAGE_CLEANUP(); + return SWITCH_STATUS_SUCCESS; + } + GARBAGE_ADD(request.headers[i].value); + strcpy(request.headers[i].value, value); + a += strlen(value); + i++; + } + + if (argc == HTTP_PARAMS) { + l = strlen(body); + body_dec = url_decode(body, l); + GARBAGE_ADD(body_dec); + l = strlen(body_dec); + request.body_len = l; + request.body = body_dec; + } else + request.body_len = 0; + + ret = http_req(&request, &response); + + if (response.version != NULL) + GARBAGE_ADD(response.version); + if (response.phrase != NULL) + GARBAGE_ADD(response.phrase); + if (response.headers != NULL) + GARBAGE_ADD(response.headers); + if (response.body != NULL) + GARBAGE_ADD(response.body); + for (i = 0; i < response.header_len; i++) { + GARBAGE_ADD(response.headers[i].field_name); + GARBAGE_ADD(response.headers[i].value); + } - switch_log_printf( - SWITCH_CHANNEL_LOG, - SWITCH_LOG_NOTICE, - "RESERVED %ld BYTES, USED %ld BYTES, HTTP Response as JSON: %s\n", - l, - m, - json_response - ); + if (ret == ERROR) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + GARBAGE_CLEANUP(); + return SWITCH_STATUS_SUCCESS; + } + + /* This is evil and should be changed in the future */ + l = 128 + (256 * response.header_len) + (a * 2) + + strlen("version") + strlen(response.version) + + strlen("status_code") + 3 + strlen("phrase") + strlen(response.phrase) + + strlen("body") + (response.body_len * 3) + 1 + strlen("headers") + + 1; + + /* to be safe */ + l <<= 2; + + json_response = (char *) malloc(l * sizeof(char)); + if (json_response == NULL) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + GARBAGE_CLEANUP(); + return SWITCH_STATUS_SUCCESS; + } + GARBAGE_ADD(json_response); + + if (response.body_len != 0) { + t = (char *) malloc((response.body_len + 1) * sizeof(char)); + if (t == NULL) { + switch_safe_free(ccmd); + stream->write_function(stream, "-ERR\n"); + GARBAGE_CLEANUP(); + return SWITCH_STATUS_SUCCESS; + } + GARBAGE_ADD(t); + (void) memcpy(t, response.body, response.body_len); + t[response.body_len] = '\0'; + response.body = url_encode(t, response.body_len); + GARBAGE_ADD(response.body); + } - stream->write_function(stream, "%s\n", json_response); + m = snprintf(json_response, l, + "{" + "\"version\": \"%s\"," + "\"status_code\": \"%3d\"," + "\"phrase\": \"%s\"," + "\"body\": \"%s\"," + "\"headers\": [", response.version, response.status_code, response.phrase, ((response.body_len <= 0) ? "" : response.body) + ); - switch_safe_free(ccmd); - GARBAGE_CLEANUP(); - return SWITCH_STATUS_SUCCESS; + + for (f = HTTP_FALSE, j = 0; j < response.header_len; j++) { + if (f != HTTP_FALSE) { + m += snprintf(json_response + m, l - m, ","); + } else + f = HTTP_TRUE; + + m += snprintf(json_response + m, l - m, "{\"key\": \"%s\",\"value\": \"%s\"}", response.headers[j].field_name, response.headers[j].value); + } + + + m += snprintf(json_response + m, l - m, "]}"); + json_response[m] = '\0'; + + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "RESERVED %ld BYTES, USED %ld BYTES, HTTP Response as JSON: %s\n", l, m, json_response); + + + stream->write_function(stream, "%s\n", json_response); + + switch_safe_free(ccmd); + GARBAGE_CLEANUP(); + return SWITCH_STATUS_SUCCESS; } SWITCH_MODULE_LOAD_FUNCTION(mod_http_load); @@ -378,25 +370,13 @@ SWITCH_MODULE_DEFINITION(mod_http, mod_http_load, NULL, NULL); SWITCH_MODULE_LOAD_FUNCTION(mod_http_load) { - switch_api_interface_t *api_interface; + switch_api_interface_t *api_interface; - *module_interface = - switch_loadable_module_create_module_interface(pool, modname); + *module_interface = switch_loadable_module_create_module_interface(pool, modname); - switch_log_printf( - SWITCH_CHANNEL_LOG, - SWITCH_LOG_NOTICE, - "HTTP request mod enabled\n" - ); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "HTTP request mod enabled\n"); - SWITCH_ADD_API( - api_interface, - "http", - "Make HTTP requests", - http_api_main, - HTTP_SYNTAX - ); + SWITCH_ADD_API(api_interface, "http", "Make HTTP requests", http_api_main, HTTP_SYNTAX); - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS; } - diff --git a/src/mod/applications/mod_http/printbuf.c b/src/mod/applications/mod_http/printbuf.c index 79bdaf554a..5d6fcef81f 100644 --- a/src/mod/applications/mod_http/printbuf.c +++ b/src/mod/applications/mod_http/printbuf.c @@ -25,44 +25,44 @@ #include "debug.h" #include "printbuf.h" -struct printbuf* printbuf_new() +struct printbuf *printbuf_new() { - struct printbuf *p; + struct printbuf *p; - if(!(p = calloc(1, sizeof(struct printbuf)))) return NULL; - p->size = 32; - p->bpos = 0; - if(!(p->buf = malloc(p->size))) { - free(p); - return NULL; - } - return p; + if (!(p = calloc(1, sizeof(struct printbuf)))) + return NULL; + p->size = 32; + p->bpos = 0; + if (!(p->buf = malloc(p->size))) { + free(p); + return NULL; + } + return p; } int printbuf_memappend(struct printbuf *p, char *buf, int size) { - char *t; - if(p->size - p->bpos <= size) { - int new_size = max(p->size * 2, p->bpos + size + 8); + char *t; + if (p->size - p->bpos <= size) { + int new_size = max(p->size * 2, p->bpos + size + 8); #ifdef PRINTBUF_DEBUG - mc_debug("printbuf_memappend: realloc " - "bpos=%d wrsize=%d old_size=%d new_size=%d\n", - p->bpos, size, p->size, new_size); + mc_debug("printbuf_memappend: realloc " "bpos=%d wrsize=%d old_size=%d new_size=%d\n", p->bpos, size, p->size, new_size); #endif /* PRINTBUF_DEBUG */ - if(!(t = realloc(p->buf, new_size))) return -1; - p->size = new_size; - p->buf = t; - } - memcpy(p->buf + p->bpos, buf, size); - p->bpos += size; - p->buf[p->bpos]= '\0'; - return size; + if (!(t = realloc(p->buf, new_size))) + return -1; + p->size = new_size; + p->buf = t; + } + memcpy(p->buf + p->bpos, buf, size); + p->bpos += size; + p->buf[p->bpos] = '\0'; + return size; } #if !HAVE_VSNPRINTF && defined(WIN32) # define vsnprintf _vsnprintf -#elif !HAVE_VSNPRINTF /* !HAVE_VSNPRINTF */ +#elif !HAVE_VSNPRINTF /* !HAVE_VSNPRINTF */ # error Need vsnprintf! #endif /* !HAVE_VSNPRINTF && defined(WIN32) */ @@ -76,22 +76,26 @@ static int vasprintf(char **buf, const char *fmt, va_list ap) int chars; char *b; - if(!buf) { return -1; } - + if (!buf) { + return -1; + } #ifdef WIN32 - chars = _vscprintf(fmt, ap)+1; + chars = _vscprintf(fmt, ap) + 1; #else /* !defined(WIN32) */ /* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite our buffer like on some 64bit sun systems.... but hey, its time to move on */ - chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1; - if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */ + chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap) + 1; + if (chars < 0) { + chars *= -1; + } /* CAW: old glibc versions have this problem */ #endif /* defined(WIN32) */ - b = (char*)malloc(sizeof(char)*chars); - if(!b) { return -1; } + b = (char *) malloc(sizeof(char) * chars); + if (!b) { + return -1; + } - if((chars = vsprintf(b, fmt, ap)) < 0) - { + if ((chars = vsprintf(b, fmt, ap)) < 0) { free(b); } else { *buf = b; @@ -103,42 +107,43 @@ static int vasprintf(char **buf, const char *fmt, va_list ap) int sprintbuf(struct printbuf *p, const char *msg, ...) { - va_list ap; - char *t; - int size; - char buf[128]; + va_list ap; + char *t; + int size; + char buf[128]; - /* user stack buffer first */ - va_start(ap, msg); - size = vsnprintf(buf, 128, msg, ap); - va_end(ap); - /* if string is greater than stack buffer, then use dynamic string - with vasprintf. Note: some implementation of vsnprintf return -1 - if output is truncated whereas some return the number of bytes that - would have been writen - this code handles both cases. */ - if(size == -1 || size > 127) { - int ret; - va_start(ap, msg); - if((size = vasprintf(&t, msg, ap)) == -1) return -1; - va_end(ap); - ret = printbuf_memappend(p, t, size); - free(t); - return ret; - } else { - return printbuf_memappend(p, buf, size); - } + /* user stack buffer first */ + va_start(ap, msg); + size = vsnprintf(buf, 128, msg, ap); + va_end(ap); + /* if string is greater than stack buffer, then use dynamic string + with vasprintf. Note: some implementation of vsnprintf return -1 + if output is truncated whereas some return the number of bytes that + would have been writen - this code handles both cases. */ + if (size == -1 || size > 127) { + int ret; + va_start(ap, msg); + if ((size = vasprintf(&t, msg, ap)) == -1) + return -1; + va_end(ap); + ret = printbuf_memappend(p, t, size); + free(t); + return ret; + } else { + return printbuf_memappend(p, buf, size); + } } void printbuf_reset(struct printbuf *p) { - p->buf[0] = '\0'; - p->bpos = 0; + p->buf[0] = '\0'; + p->bpos = 0; } void printbuf_free(struct printbuf *p) { - if(p) { - free(p->buf); - free(p); - } + if (p) { + free(p->buf); + free(p); + } } diff --git a/src/mod/applications/mod_http/printbuf.h b/src/mod/applications/mod_http/printbuf.h index bc1669bd19..a3b80eab81 100644 --- a/src/mod/applications/mod_http/printbuf.h +++ b/src/mod/applications/mod_http/printbuf.h @@ -15,24 +15,19 @@ #undef PRINTBUF_DEBUG struct printbuf { - char *buf; - int bpos; - int size; + char *buf; + int bpos; + int size; }; -extern struct printbuf* -printbuf_new(); +extern struct printbuf *printbuf_new(); -extern int -printbuf_memappend(struct printbuf *p, char *buf, int size); +extern int printbuf_memappend(struct printbuf *p, char *buf, int size); -extern int -sprintbuf(struct printbuf *p, const char *msg, ...); +extern int sprintbuf(struct printbuf *p, const char *msg, ...); -extern void -printbuf_reset(struct printbuf *p); +extern void printbuf_reset(struct printbuf *p); -extern void -printbuf_free(struct printbuf *p); +extern void printbuf_free(struct printbuf *p); #endif diff --git a/src/mod/applications/mod_http/url_encoding.c b/src/mod/applications/mod_http/url_encoding.c index 3529f5e424..4e81573436 100644 --- a/src/mod/applications/mod_http/url_encoding.c +++ b/src/mod/applications/mod_http/url_encoding.c @@ -30,96 +30,97 @@ #ifdef DEBUG int main(int argc, char *argv[]) { - char *buf1; - char *buf2; - + char *buf1; + char *buf2; - buf1 = url_encode("This is a test #$ "); - buf2 = url_decode(buf1); - printf("%s\n", buf2); - - free(buf1); - free(buf2); - return EXIT_FAILURE; + buf1 = url_encode("This is a test #$ "); + buf2 = url_decode(buf1); + + printf("%s\n", buf2); + + free(buf1); + free(buf2); + return EXIT_FAILURE; } #endif char *url_encode(char *url, size_t l) { - int i; - int j; - char *buf; - unsigned char c; + int i; + int j; + char *buf; + unsigned char c; - buf = (char *)malloc((l * 3) + 1); - if(buf == NULL){ - perror("Could not allocate memory url encoding"); - return NULL; - } + buf = (char *) malloc((l * 3) + 1); + if (buf == NULL) { + perror("Could not allocate memory url encoding"); + return NULL; + } - for(i = 0, j = 0; i < l; i++){ - c = (unsigned char)url[i]; - if(c <= 31 || c >= 127 - || c == '$' || c == '&' || c == '+' || c == ',' || c == '/' - || c == ':' || c == ';' || c == '=' || c == '?' || c == '@' - || c == ' ' || c == '"' || c == '<' || c == '>' || c == '#' - || c == '%' || c == '{' || c == '}' || c == '|' || c == '\\' - || c == '^' || c == '~' || c == '[' || c == ']' || c == '`'){ - - (void)sprintf(buf + j, "%%%X%X", c >> 4, c & 0x0F); - j += 3; - }else{ - buf[j] = url[i]; - j++; - } - } - - buf[j] = '\0'; + for (i = 0, j = 0; i < l; i++) { + c = (unsigned char) url[i]; + if (c <= 31 || c >= 127 + || c == '$' || c == '&' || c == '+' || c == ',' || c == '/' + || c == ':' || c == ';' || c == '=' || c == '?' || c == '@' + || c == ' ' || c == '"' || c == '<' || c == '>' || c == '#' + || c == '%' || c == '{' || c == '}' || c == '|' || c == '\\' || c == '^' || c == '~' || c == '[' || c == ']' || c == '`') { - return buf; + (void) sprintf(buf + j, "%%%X%X", c >> 4, c & 0x0F); + j += 3; + } else { + buf[j] = url[i]; + j++; + } + } + + buf[j] = '\0'; + + return buf; } char *url_decode(char *url, size_t l) { - int i; - int j; - char *buf; - char c; - char d0; - char d1; + int i; + int j; + char *buf; + char c; + char d0; + char d1; - buf = (char *)malloc((l + 1) * sizeof(char)); - if(buf == NULL){ - perror("Could not allocate memory for decoding"); - return NULL; - } + buf = (char *) malloc((l + 1) * sizeof(char)); + if (buf == NULL) { + perror("Could not allocate memory for decoding"); + return NULL; + } - for(i = 0, j = 0; i < l; j++){ - c = url[i]; - if(c == '%'){ - d0 = url[i + 2]; - d1 = url[i + 1]; - d0 = toupper(d0); - d1 = toupper(d1); + for (i = 0, j = 0; i < l; j++) { + c = url[i]; + if (c == '%') { + d0 = url[i + 2]; + d1 = url[i + 1]; + d0 = toupper(d0); + d1 = toupper(d1); - if(d0 >= 'A' && d0 <= 'F') d0 = d0 - 'A' + 10; - else if(d0 >= '0' && d0 <= '9') d0 = d0 - '0'; - if(d1 >= 'A' && d1 <= 'F') d1 = d1 - 'A' + 10; - else if(d1 >= '0' && d1 <= '9') d1 = d1 - '0'; + if (d0 >= 'A' && d0 <= 'F') + d0 = d0 - 'A' + 10; + else if (d0 >= '0' && d0 <= '9') + d0 = d0 - '0'; + if (d1 >= 'A' && d1 <= 'F') + d1 = d1 - 'A' + 10; + else if (d1 >= '0' && d1 <= '9') + d1 = d1 - '0'; - buf[j] = (d1 << 4) + d0; - i += 3; - }else{ - buf[j] = url[i]; - i++; - } - } + buf[j] = (d1 << 4) + d0; + i += 3; + } else { + buf[j] = url[i]; + i++; + } + } - buf[j] = '\0'; + buf[j] = '\0'; - return buf; + return buf; } - - diff --git a/src/mod/applications/mod_http/url_encoding.h b/src/mod/applications/mod_http/url_encoding.h index 49723c3a7a..39d8a6f4d0 100644 --- a/src/mod/applications/mod_http/url_encoding.h +++ b/src/mod/applications/mod_http/url_encoding.h @@ -39,4 +39,3 @@ char *url_encode(char *url, size_t l); char *url_decode(char *url, size_t l); #endif -