From f5c0c1393105fafc510e926c46e36849013bf149 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 6 Sep 2014 15:35:10 +0800 Subject: [PATCH] add http query string parsing and improve http header parsing --- src/include/switch_utils.h | 13 ++++++++ src/switch_utils.c | 62 +++++++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 2c0bac8183..67fee60c3c 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -24,6 +24,7 @@ * Contributor(s): * * Anthony Minessale II + * Seven Du * * * switch_utils.h -- Compatability and Helper Code @@ -1113,6 +1114,8 @@ typedef struct switch_http_request_s { const char *referer; const char *user; switch_bool_t keepalive; + const char *content_type; + switch_size_t content_length; switch_event_t *headers; void *user_data; /* private user data */ @@ -1134,6 +1137,16 @@ typedef struct switch_http_request_s { SWITCH_DECLARE(switch_status_t) switch_http_parse_header(char *buffer, uint32_t datalen, switch_http_request_t *request); SWITCH_DECLARE(void) switch_http_free_request(switch_http_request_t *request); SWITCH_DECLARE(void) switch_http_dump_request(switch_http_request_t *request); +/** + * parse http query string + * \param[in] request the http request object + * \param[in] qs the query string buffer + * + * qs buffer will be modified, so be sure to dup the qs before passing into this function if you want to keep the original string untouched + * if qs is NULL, the it will parse request->qs, request->qs will be duplicated before parse to avoid being modified + */ + +SWITCH_DECLARE(void) switch_http_parse_qs(switch_http_request_t *request, char *qs); SWITCH_END_EXTERN_C #endif diff --git a/src/switch_utils.c b/src/switch_utils.c index 81fe8a192f..c08b5ff27d 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -25,6 +25,7 @@ * * Anthony Minessale II * Juan Jose Comellas + * Seven Du * * * switch_utils.c -- Compatibility and Helper Code @@ -3603,6 +3604,47 @@ SWITCH_DECLARE(char *) switch_strerror_r(int errnum, char *buf, switch_size_t bu #endif } +SWITCH_DECLARE(void) switch_http_parse_qs(switch_http_request_t *request, char *qs) +{ + char *q; + char *next; + char *name, *val; + + if (qs) { + q = qs; + } else { /*parse our own qs, dup to avoid modify the original string */ + q = strdup(request->qs); + } + + switch_assert(q); + next = q; + + do { + char *p; + + if ((next = strchr(next, '&'))) { + *next++ = '\0'; + } + + for (p = q; p && *p; p++) { + if (*p == '+') *p = ' '; + } + + switch_url_decode(q); + + name = q; + if ((val = strchr(name, '='))) { + *val++ = '\0'; + switch_event_add_header_string(request->headers, SWITCH_STACK_BOTTOM, name, val); + } + q = next; + } while (q); + + if (!qs) { + switch_safe_free(q); + } +} + SWITCH_DECLARE(switch_status_t) switch_http_parse_header(char *buffer, uint32_t datalen, switch_http_request_t *request) { switch_status_t status = SWITCH_STATUS_FALSE; @@ -3646,9 +3688,17 @@ SWITCH_DECLARE(switch_status_t) switch_http_parse_header(char *buffer, uint32_t p = strchr(request->uri, ' '); if (!p) goto err; - *p++ = '\0'; + *p++ = '\0'; http = p; + + p = strchr(request->uri, '?'); + + if (p) { + *p++ = '\0'; + request->qs = p; + } + p = strchr(http, '\n'); if (!p) goto err; @@ -3702,9 +3752,19 @@ SWITCH_DECLARE(switch_status_t) switch_http_parse_header(char *buffer, uint32_t if (*p) request->port = (switch_port_t)atoi(p); } + } else if (!strncasecmp(header, "Content-Type", 12)) { + request->content_type = value; + } else if (!strncasecmp(header, "Content-Length", 14)) { + request->content_length = atoi(value); + } else if (!strncasecmp(header, "Referer", 7)) { + request->referer = value; } } + if (request->qs) { + switch_http_parse_qs(request, NULL); + } + return SWITCH_STATUS_SUCCESS; err: