uri
struct evhttp_uri {
unsigned flags;
char *scheme;
char *userinfo;
char *host;
int port;
char *path;
char *query;
char *fragment;
};
libevent evhttp_uri_parse_with_flags
struct evhttp_uri *
evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
{
char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
char *path = NULL, *fragment = NULL;
int got_authority = 0;
struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
if (uri == NULL) {
event_warn("%s: calloc", __func__);
goto err;
}
uri->port = -1;
uri->flags = flags;
readbuf = mm_strdup(source_uri);
if (readbuf == NULL) {
event_warn("%s: strdup", __func__);
goto err;
}
readp = readbuf;
token = NULL;
/* We try to follow RFC3986 here as much as we can, and match
the productions
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
relative-ref = relative-part [ "?" query ] [ "#" fragment ]
*/
/* 1. scheme: */
token = strchr(readp,
if (token && scheme_ok(readp,token)) {
*token =
uri->scheme = mm_strdup(readp);
if (uri->scheme == NULL) {
event_warn("%s: strdup", __func__);
goto err;
}
readp = token+1; /* eat : */
}
/* 2. Optionally, "//" then an
if (readp[0]==
char *authority;
readp += 2;
authority = readp;
path = end_of_authority(readp);
if (parse_authority(uri, authority, path) < 0)
goto err;
readp = path;
got_authority = 1;
}
/* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
*/
path = readp;
readp = end_of_path(path, PART_PATH, flags);
/* Query */
if (*readp ==
*readp =
++readp;
query = readp;
readp = end_of_path(readp, PART_QUERY, flags);
}
/* fragment */
if (*readp ==
*readp =
++readp;
fragment = readp;
readp = end_of_path(readp, PART_FRAGMENT, flags);
}
if (*readp !=
goto err;
}
/* These next two cases may be unreachable; I
* in to be defensive. */
/* If you didn
if (!got_authority && path[0]==
goto err;
/* If you did get an authority, the path must begin with "/" or be
* empty. */
if (got_authority && path[0] !=
goto err;
/* (End of maybe-unreachable cases) */
/* If there was no scheme, the first part of the path (if any) must
* have no colon in it. */
if (! uri->scheme && !path_matches_noscheme(path))
goto err;
EVUTIL_ASSERT(path);
uri->path = mm_strdup(path);
if (uri->path == NULL) {
event_warn("%s: strdup", __func__);
goto err;
}
if (query) {
uri->query = mm_strdup(query);
if (uri->query == NULL) {
event_warn("%s: strdup", __func__);
goto err;
}
}
if (fragment) {
uri->fragment = mm_strdup(fragment);
if (uri->fragment == NULL) {
event_warn("%s: strdup", __func__);
goto err;
}
}
mm_free(readbuf);
return uri;
err:
if (uri)
evhttp_uri_free(uri);
if (readbuf)
mm_free(readbuf);
return NULL;
}