23 #include "asterisk/uri.h"
26 #include <uriparser/Uri.h>
54 static struct ast_uri *ast_uri_create_(
55 const char *
scheme,
unsigned int scheme_size,
56 const char *
user_info,
unsigned int user_info_size,
57 const char *
host,
unsigned int host_size,
58 const char *
port,
unsigned int port_size,
59 const char *
path,
unsigned int path_size,
60 const char *
query,
unsigned int query_size)
62 #define SET_VALUE(param, field, size) \
64 ast_copy_string(p, param, size); \
66 p += size; } } while (0)
69 struct ast_uri *res = ao2_alloc(
70 sizeof(*res) + scheme_size + user_info_size + host_size +
71 port_size + path_size + query_size, NULL);
74 ast_log(LOG_ERROR,
"Unable to create URI object\n");
79 SET_VALUE(scheme, res->
scheme, scheme_size);
80 SET_VALUE(user_info, res->
user_info, user_info_size);
81 SET_VALUE(host, res->
host, host_size);
82 SET_VALUE(port, res->
port, port_size);
83 SET_VALUE(path, res->
path, path_size);
84 SET_VALUE(query, res->
query, query_size);
92 return ast_uri_create_(
93 scheme, scheme ? strlen(scheme) + 1 : 0,
94 user_info, user_info ? strlen(user_info) + 1 : 0,
95 host, host ? strlen(host) + 1 : 0,
96 port, port ? strlen(port) + 1 : 0,
97 path, path ? strlen(path) + 1 : 0,
98 query, query ? strlen(query) + 1 : 0);
101 struct ast_uri *ast_uri_copy_replace(
const struct ast_uri *
uri,
const char *scheme,
102 const char *user_info,
const char *host,
103 const char *port,
const char *path,
106 return ast_uri_create(
107 scheme ? scheme : uri->
scheme,
109 host ? host : uri->
host,
110 port ? port : uri->
port,
111 path ? path : uri->
path,
112 query ? query : uri->
query);
115 const char *ast_uri_scheme(
const struct ast_uri *
uri)
120 const char *ast_uri_user_info(
const struct ast_uri *
uri)
125 const char *ast_uri_host(
const struct ast_uri *
uri)
130 const char *ast_uri_port(
const struct ast_uri *
uri)
135 const char *ast_uri_path(
const struct ast_uri *
uri)
140 const char *ast_uri_query(
const struct ast_uri *
uri)
145 int ast_uri_is_secure(
const struct ast_uri *
uri)
147 return ast_strlen_zero(uri->
scheme) ? 0 :
151 #ifdef HAVE_URIPARSER
152 struct ast_uri *ast_uri_parse(
const char *
uri)
154 UriParserStateA
state;
157 unsigned int scheme_size, user_info_size, host_size;
158 unsigned int port_size, path_size, query_size;
159 const char *path_start, *path_end;
162 if (uriParseUriA(&state, uri) != URI_SUCCESS) {
163 ast_log(LOG_ERROR,
"Unable to parse URI %s\n", uri);
164 uriFreeUriMembersA(&uria);
168 scheme_size = uria.scheme.first ?
169 uria.scheme.afterLast - uria.scheme.first + 1 : 0;
170 user_info_size = uria.userInfo.first ?
171 uria.userInfo.afterLast - uria.userInfo.first + 1 : 0;
172 host_size = uria.hostText.first ?
173 uria.hostText.afterLast - uria.hostText.first + 1 : 0;
174 port_size = uria.portText.first ?
175 uria.portText.afterLast - uria.portText.first + 1 : 0;
177 path_start = uria.pathHead && uria.pathHead->text.first ?
178 uria.pathHead->text.first : NULL;
179 path_end = path_start ? uria.pathTail->text.afterLast : NULL;
180 path_size = path_end ? path_end - path_start + 1 : 0;
182 query_size = uria.query.first ?
183 uria.query.afterLast - uria.query.first + 1 : 0;
185 res = ast_uri_create_(uria.scheme.first, scheme_size,
186 uria.userInfo.first, user_info_size,
187 uria.hostText.first, host_size,
188 uria.portText.first, port_size,
189 path_start, path_size,
190 uria.query.first, query_size);
191 uriFreeUriMembersA(&uria);
195 struct ast_uri *ast_uri_parse(
const char *uri)
197 #define SET_VALUES(value) \
199 size_##value = p - uri + 1; \
202 const char *p, *scheme = NULL, *user_info = NULL, *host = NULL;
203 const char *port = NULL, *path = NULL, *query = NULL;
204 unsigned int size_scheme = 0, size_user_info = 0, size_host = 0;
205 unsigned int size_port = 0, size_path = 0, size_query = 0;
207 if ((p = strstr(uri,
"://"))) {
209 size_scheme = p - uri + 1;
213 if ((p = strchr(uri,
'@'))) {
214 SET_VALUES(user_info);
217 if ((p = strchr(uri,
':'))) {
221 if ((p = strchr(uri,
'/'))) {
229 if ((p = strchr(uri,
'?'))) {
231 size_query = strlen(query) + 1;
233 p = uri + strlen(uri);
238 }
else if (*(uri - 1) ==
':') {
240 }
else if (*(uri - 1) ==
'/') {
244 return ast_uri_create_(scheme, size_scheme,
245 user_info, size_user_info,
253 static struct ast_uri *uri_parse_and_default(
const char *uri,
const char *scheme,
254 const char *port,
const char *secure_port)
257 int len = strlen(scheme);
259 if (!strncmp(uri, scheme, len)) {
260 res = ast_uri_parse(uri);
263 char *with_scheme =
ast_malloc(len + strlen(uri) + 4);
265 ast_log(LOG_ERROR,
"Unable to allocate uri '%s' with "
266 "scheme '%s'", uri, scheme);
273 sprintf(with_scheme,
"%s://%s", scheme, uri);
274 res = ast_uri_parse(with_scheme);
275 ast_free(with_scheme);
278 if (res && ast_strlen_zero(ast_uri_port(res))) {
280 struct ast_uri *tmp = ast_uri_copy_replace(
281 res, NULL, NULL, NULL,
282 ast_uri_is_secure(res) ? secure_port : port,
290 struct ast_uri *ast_uri_parse_http(
const char *uri)
292 return uri_parse_and_default(uri,
"http",
"80",
"443");
295 struct ast_uri *ast_uri_parse_websocket(
const char *uri)
297 return uri_parse_and_default(uri,
"ws",
"80",
"443");
300 char *ast_uri_make_host_with_port(
const struct ast_uri *uri)
305 ast_uri_host(uri) ?:
"",
306 ast_uri_port(uri) ?
":" :
"",
307 ast_uri_port(uri) ?:
"") == -1) {
Asterisk main include file. File version handling, generic pbx functions.
String manipulation functions.
Stores parsed uri information.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ast_malloc(len)
A wrapper for malloc()