Skip to content

Commit

Permalink
Make evhttp_uri non-public, and give it accessor functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
nmathewson committed Oct 21, 2010
1 parent 2075fbc commit 45f6869
Show file tree
Hide file tree
Showing 3 changed files with 360 additions and 172 deletions.
140 changes: 138 additions & 2 deletions http.c
Original file line number Diff line number Diff line change
Expand Up @@ -2465,7 +2465,7 @@ evhttp_parse_query__checked_20(const char *str, struct evkeyvalq *headers,
uri = evhttp_uri_parse(str);
if (!uri)
goto error;
query_part = uri->query;
query_part = evhttp_uri_get_query(uri);
} else {
query_part = str;
}
Expand Down Expand Up @@ -3347,6 +3347,25 @@ bind_socket(const char *address, ev_uint16_t port, int reuse)
return (fd);
}

struct evhttp_uri {
char *scheme; /* scheme; e.g http, ftp etc */
char *userinfo; /* userinfo (typically username:pass), or NULL */
char *host; /* hostname, IP address, or NULL */
int port; /* port, or zero */
char *path; /* path, or "". */
char *query; /* query, or NULL */
char *fragment; /* fragment or NULL */
};

struct evhttp_uri *
evhttp_uri_new(void)
{
struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
if (uri)
uri->port = -1;
return uri;
}

/* Return true of the string starting at s and ending immediately before eos
* is a valid URI scheme according to RFC3986
*/
Expand Down Expand Up @@ -3689,7 +3708,6 @@ evhttp_uri_free(struct evhttp_uri *uri)
_URI_FREE_STR(fragment);

mm_free(uri);

#undef _URI_FREE_STR
}

Expand Down Expand Up @@ -3756,3 +3774,121 @@ evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
return output;
#undef _URI_ADD
}

const char *
evhttp_uri_get_scheme(const struct evhttp_uri *uri)
{
return uri->scheme;
}
const char *
evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
{
return uri->userinfo;
}
const char *
evhttp_uri_get_host(const struct evhttp_uri *uri)
{
return uri->host;
}
int
evhttp_uri_get_port(const struct evhttp_uri *uri)
{
return uri->port;
}
const char *
evhttp_uri_get_path(const struct evhttp_uri *uri)
{
return uri->path;
}
const char *
evhttp_uri_get_query(const struct evhttp_uri *uri)
{
return uri->query;
}
const char *
evhttp_uri_get_fragment(const struct evhttp_uri *uri)
{
return uri->fragment;
}

#define _URI_SET_STR(f) do { \
if (uri->f) \
mm_free(uri->f); \
if (f) { \
if ((uri->f = mm_strdup(f)) == NULL) { \
event_warn("%s: strdup()", __func__); \
return -1; \
} \
} else { \
uri->f = NULL; \
} \
} while(0)

int
evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
{
if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
return -1;

_URI_SET_STR(scheme);
return 0;
}
int
evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
{
if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
return -1;
_URI_SET_STR(userinfo);
return 0;
}
int
evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
{
if (host) {
if (host[0] == '[') {
if (! bracket_addr_ok(host, host+strlen(host)))
return -1;
} else {
if (! regname_ok(host, host+strlen(host)))
return -1;
}
}

_URI_SET_STR(host);
return 0;
}
int
evhttp_uri_set_port(struct evhttp_uri *uri, int port)
{
if (port < -1)
return -1;
uri->port = port;
return 0;
}
#define end_of_cpath(cp,aq) ((const char*)(end_of_path(((char*)(cp)), (aq))))

int
evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
{
if (path && end_of_cpath(path, 0) != path+strlen(path))
return -1;

_URI_SET_STR(path);
return 0;
}
int
evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
{
if (query && end_of_cpath(query, 1) != query+strlen(query))
return -1;
_URI_SET_STR(query);
return 0;
}
int
evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
{
if (fragment && end_of_cpath(fragment, 1) != fragment+strlen(fragment))
return -1;
_URI_SET_STR(fragment);
return 0;
}
75 changes: 64 additions & 11 deletions include/event2/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -632,17 +632,70 @@ int evhttp_parse_query__checked_20(const char *uri, struct evkeyvalq *headers,
char *evhttp_htmlescape(const char *html);

/**
* A structure to hold a parsed URI.
*/
struct evhttp_uri {
char *scheme; /* scheme; e.g http, ftp etc */
char *host; /* hostname, IP address, or NULL */
char *userinfo; /* userinfo (typically username:pass), or NULL */
int port; /* port, or zero */
char *path; /* path, or "". */
char *query; /* query, or NULL */
char *fragment; /* fragment or NULL */
};
* A structure to hold a parsed URI or Relative-Ref conforming to RFC3986.
*/
struct evhttp_uri;

/**
* Return a new empty evhttp_uri with no fields set.
*/
struct evhttp_uri *evhttp_uri_new(void);

/** Return the scheme of an evhttp_uri, or NULL if there is no scheme has
* been set and the evhttp_uri contains a Relative-Ref. */
const char *evhttp_uri_get_scheme(const struct evhttp_uri *uri);
/**
* Return the userinfo part of an evhttp_uri, or NULL if it has no userinfo
* set.
*/
const char *evhttp_uri_get_userinfo(const struct evhttp_uri *uri);
/**
* Return the host part of an evhttp_uri, or NULL if it has no host set.
* The host may either be a regular hostname (conforming to the RFC 3986
* "regname" production), or an IPv4 address, or the empty string, or a
* bracketed IPv6 address, or a bracketed 'IP-Future' address.
*
* Note that having a NULL host means that the URI has no authority
* section, but having an empty-string host means that the URI has an
* authority section with no host part. For example,
* "mailto:[email protected]" has a host of NULL, but "file:///etc/motd"
* has a host of "".
*/
const char *evhttp_uri_get_host(const struct evhttp_uri *uri);
/** Return the port part of an evhttp_uri, or -1 if there is no port set. */
int evhttp_uri_get_port(const struct evhttp_uri *uri);
/** Return the path part of an evhttp_uri, or NULL if it has no path set */
const char *evhttp_uri_get_path(const struct evhttp_uri *uri);
/** Return the query part of an evhttp_uri (excluding the leading "?"), or
* NULL if it has no query set */
const char *evhttp_uri_get_query(const struct evhttp_uri *uri);
/** Return the fragment part of an evhttp_uri (excluding the leading "#"),
* or NULL if it has no fragment set */
const char *evhttp_uri_get_fragment(const struct evhttp_uri *uri);

/** Set the scheme of an evhttp_uri, or clear the scheme if scheme==NULL.
* Returns 0 on success, -1 if scheme is not well-formed. */
int evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme);
/** Set the userinfo of an evhttp_uri, or clear the userinfo if userinfo==NULL.
* Returns 0 on success, -1 if userinfo is not well-formed. */
int evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo);
/** Set the host of an evhttp_uri, or clear the host if host==NULL.
* Returns 0 on success, -1 if host is not well-formed. */
int evhttp_uri_set_host(struct evhttp_uri *uri, const char *host);
/** Set the port of an evhttp_uri, or clear the port if port==-1.
* Returns 0 on success, -1 if port is not well-formed. */
int evhttp_uri_set_port(struct evhttp_uri *uri, int port);
/** Set the path of an evhttp_uri, or clear the path if path==NULL.
* Returns 0 on success, -1 if path is not well-formed. */
int evhttp_uri_set_path(struct evhttp_uri *uri, const char *path);
/** Set the query of an evhttp_uri, or clear the query if query==NULL.
* The query should not include a leading "?".
* Returns 0 on success, -1 if query is not well-formed. */
int evhttp_uri_set_query(struct evhttp_uri *uri, const char *query);
/** Set the fragment of an evhttp_uri, or clear the fragment if fragment==NULL.
* The fragment should not include a leading "#".
* Returns 0 on success, -1 if fragment is not well-formed. */
int evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment);

/**
* Helper function to parse a URI-Reference as specified by RFC3986.
Expand Down
Loading

0 comments on commit 45f6869

Please sign in to comment.