summaryrefslogtreecommitdiff
path: root/pjlib-util
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2010-10-01 06:43:17 +0000
committerBenny Prijono <bennylp@teluu.com>2010-10-01 06:43:17 +0000
commit2d607c9fcd1a5ca1c6920d7ce7748cae497ad77f (patch)
tree0fdeb643344d95f40bb8b6109838fc30a7116c30 /pjlib-util
parent8222a3a22a61dfbd1c443d662f0ec6d7c159b0fd (diff)
Re #1136 (Basic and digest authentication in the HTTP client): fixed error in parsing URL if the path contains at ("@") character
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3332 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib-util')
-rw-r--r--pjlib-util/src/pjlib-util-test/http_client.c12
-rw-r--r--pjlib-util/src/pjlib-util/http_client.c32
2 files changed, 42 insertions, 2 deletions
diff --git a/pjlib-util/src/pjlib-util-test/http_client.c b/pjlib-util/src/pjlib-util-test/http_client.c
index d8445092..9194f2bb 100644
--- a/pjlib-util/src/pjlib-util-test/http_client.c
+++ b/pjlib-util/src/pjlib-util-test/http_client.c
@@ -303,6 +303,15 @@ static int parse_url_test()
/* empty username and passwd*/
{"http://:@pjsip.org", PJ_SUCCESS, "", "", "pjsip.org", 80, "/"},
+ /* '@' character in username and path */
+ {"http://user@pjsip.org/@", PJ_SUCCESS, "user", "", "pjsip.org", 80, "/@"},
+
+ /* '@' character in path */
+ {"http://pjsip.org/@", PJ_SUCCESS, "", "", "pjsip.org", 80, "/@"},
+
+ /* '@' character in path */
+ {"http://pjsip.org/one@", PJ_SUCCESS, "", "", "pjsip.org", 80, "/one@"},
+
/* Invalid URL */
{"http://:", PJ_EINVAL, "", "", "", 0, ""},
@@ -325,6 +334,9 @@ static int parse_url_test()
{"http://@/", PJ_EINVAL, "", "", "", 0, ""},
/* Invalid URL */
+ {"http:///@", PJ_EINVAL, "", "", "", 0, ""},
+
+ /* Invalid URL */
{"http://:::", PJ_EINVAL, "", "", "", 0, ""},
};
unsigned i;
diff --git a/pjlib-util/src/pjlib-util/http_client.c b/pjlib-util/src/pjlib-util/http_client.c
index 31c46b45..2e966387 100644
--- a/pjlib-util/src/pjlib-util/http_client.c
+++ b/pjlib-util/src/pjlib-util/http_client.c
@@ -766,6 +766,34 @@ PJ_DEF(void) pj_http_req_param_default(pj_http_req_param *param)
pj_time_val_normalize(&param->timeout);
}
+/* Get the location of '@' character to indicate the end of
+ * user:passwd part of an URI. If user:passwd part is not
+ * present, NULL will be returned.
+ */
+static char *get_url_at_pos(const char *str, long len)
+{
+ const char *end = str + len;
+ const char *p = str;
+
+ /* skip scheme: */
+ while (p!=end && *p!='/') ++p;
+ if (p!=end && *p=='/') ++p;
+ if (p!=end && *p=='/') ++p;
+ if (p==end) return NULL;
+
+ for (; p!=end; ++p) {
+ switch (*p) {
+ case '/':
+ return NULL;
+ case '@':
+ return (char*)p;
+ }
+ }
+
+ return NULL;
+}
+
+
PJ_DEF(pj_status_t) pj_http_req_parse_url(const pj_str_t *url,
pj_http_url *hurl)
{
@@ -801,7 +829,7 @@ PJ_DEF(pj_status_t) pj_http_req_parse_url(const pj_str_t *url,
}
pj_scan_advance_n(&scanner, 3, PJ_FALSE);
- if (pj_memchr(url->ptr, '@', url->slen)) {
+ if (get_url_at_pos(url->ptr, url->slen)) {
/* Parse username and password */
pj_scan_get_until_chr(&scanner, ":@", &hurl->username);
if (*scanner.curptr == ':') {
@@ -924,7 +952,7 @@ PJ_DEF(pj_status_t) pj_http_req_create(pj_pool_t *pool,
/* If URL contains username/password, move them to credential and
* remove them from the URL.
*/
- if ((at_pos=pj_strchr(&hreq->url, '@')) != NULL) {
+ if ((at_pos=get_url_at_pos(hreq->url.ptr, hreq->url.slen)) != NULL) {
pj_str_t tmp;
char *user_pos = pj_strchr(&hreq->url, '/');
int removed_len;