* Parse a database URL of form * scheme[:group]://[username[:password]@]hostname[:port]/database[?options] * * \param id filled id struct * \param url parsed URL * \return 0 if parsing was successful and -1 otherwise */
| 69 | * \return 0 if parsing was successful and -1 otherwise |
| 70 | */ |
| 71 | static int parse_cachedb_url(struct cachedb_id* id, const str* url) |
| 72 | { |
| 73 | #define SHORTEST_DB_URL "s://" |
| 74 | #define SHORTEST_DB_URL_LEN (sizeof(SHORTEST_DB_URL) - 1) |
| 75 | |
| 76 | enum state { |
| 77 | ST_SCHEME, /* Scheme part */ |
| 78 | ST_SLASH1, /* First slash */ |
| 79 | ST_SLASH1_GRP, /* Group Name or first / */ |
| 80 | ST_SLASH2, /* Second slash */ |
| 81 | ST_USER_HOST, /* Username or hostname */ |
| 82 | ST_PASS_PORT, /* Password or port part */ |
| 83 | ST_HOST, /* Hostname part */ |
| 84 | ST_HOST6, /* Hostname part IPv6 */ |
| 85 | ST_PORT, /* Port part */ |
| 86 | ST_DB, /* Database part */ |
| 87 | ST_OPTIONS /* Options part */ |
| 88 | }; |
| 89 | |
| 90 | enum state st; |
| 91 | unsigned int len, i, ipv6_flag=0, multi_hosts=0; |
| 92 | char* begin, *last_at, *last_slash, *last_qm; |
| 93 | char* prev_token,*start_host=NULL,*start_prev=NULL,*ptr; |
| 94 | |
| 95 | prev_token = 0; |
| 96 | |
| 97 | if (!id || !url || !url->s) { |
| 98 | goto err; |
| 99 | } |
| 100 | |
| 101 | len = url->len; |
| 102 | if (len < SHORTEST_DB_URL_LEN) { |
| 103 | goto err; |
| 104 | } |
| 105 | |
| 106 | LM_DBG("parsing [%.*s]\n",url->len,url->s); |
| 107 | /* Initialize all attributes to 0 */ |
| 108 | memset(id, 0, sizeof(struct cachedb_id)); |
| 109 | st = ST_SCHEME; |
| 110 | begin = url->s; |
| 111 | |
| 112 | if (dupl_string(&id->initial_url,url->s,url->s+url->len) < 0) |
| 113 | goto err; |
| 114 | |
| 115 | last_slash = q_memrchr(url->s, '/', url->len); |
| 116 | last_qm = q_memrchr(url->s, '?', url->len); |
| 117 | |
| 118 | /* ignore any '@' characters inside the "params" part */ |
| 119 | if (last_qm || last_slash) |
| 120 | last_at = q_memrchr(url->s, '@', |
| 121 | last_slash ? (last_slash-url->s) : (last_qm-url->s)); |
| 122 | else |
| 123 | last_at = q_memrchr(url->s, '@', url->len); |
| 124 | |
| 125 | for(i = 0; i < len; i++) { |
| 126 | switch(st) { |
| 127 | case ST_SCHEME: |
| 128 | switch(url->s[i]) { |
no test coverage detected