summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--render/form.c67
-rw-r--r--render/form.h2
-rw-r--r--utils/url.c382
-rw-r--r--utils/url.h5
4 files changed, 231 insertions, 225 deletions
diff --git a/render/form.c b/render/form.c
index 776ebdc7a..f60a2bad3 100644
--- a/render/form.c
+++ b/render/form.c
@@ -674,26 +674,41 @@ char *form_textarea_value(struct form_control *textarea)
*
* \param form form to which successful controls relate
* \param control linked list of fetch_multipart_data
+ * \param query_string iff true add '?' to the start of returned data
* \return URL-encoded form, or 0 on memory exhaustion
*/
-char *form_url_encode(struct form *form,
- struct fetch_multipart_data *control)
+static char *form_url_encode(struct form *form,
+ struct fetch_multipart_data *control,
+ bool query_string)
{
char *name, *value;
- char *s = malloc(1), *s2;
- unsigned int len = 0, len1;
+ char *s, *s2;
+ unsigned int len, len1;
url_func_result url_err;
- if (!s)
- return 0;
- s[0] = 0;
+ if (query_string)
+ s = malloc(2);
+ else
+ s = malloc(1);
+
+ if (s == NULL)
+ return NULL;
+
+ if (query_string) {
+ s[0] = '?';
+ s[1] = '\0';
+ len = 1;
+ } else {
+ s[0] = '\0';
+ len = 0;
+ }
for (; control; control = control->next) {
url_err = url_escape(control->name, 0, true, NULL, &name);
if (url_err == URL_FUNC_NOMEM) {
free(s);
- return 0;
+ return NULL;
}
assert(url_err == URL_FUNC_OK);
@@ -702,7 +717,7 @@ char *form_url_encode(struct form *form,
if (url_err == URL_FUNC_NOMEM) {
free(name);
free(s);
- return 0;
+ return NULL;
}
assert(url_err == URL_FUNC_OK);
@@ -713,7 +728,7 @@ char *form_url_encode(struct form *form,
free(value);
free(name);
free(s);
- return 0;
+ return NULL;
}
s = s2;
sprintf(s + len, "%s=%s&", name, value);
@@ -723,7 +738,7 @@ char *form_url_encode(struct form *form,
}
if (len)
- s[len - 1] = 0;
+ s[len - 1] = '\0';
return s;
}
@@ -1460,10 +1475,10 @@ void form_radio_set(html_content *html,
void form_submit(nsurl *page_url, struct browser_window *target,
struct form *form, struct form_control *submit_button)
{
- char *data = NULL, *url = NULL;
+ char *data = NULL;
struct fetch_multipart_data *success;
- struct url_components components;
- url_func_result res;
+ nsurl *action;
+ nsurl *action_query;
assert(form != NULL);
@@ -1474,7 +1489,7 @@ void form_submit(nsurl *page_url, struct browser_window *target,
switch (form->method) {
case method_GET:
- data = form_url_encode(form, success);
+ data = form_url_encode(form, success, true);
if (data == NULL) {
fetch_multipart_data_destroy(success);
warn_user("NoMemory", 0);
@@ -1482,8 +1497,7 @@ void form_submit(nsurl *page_url, struct browser_window *target,
}
/* Decompose action */
- res = url_get_components(form->action, &components);
- if (res != URL_FUNC_OK) {
+ if (nsurl_create(form->action, &action) != NSERROR_OK) {
free(data);
fetch_multipart_data_destroy(success);
warn_user("NoMemory", 0);
@@ -1491,24 +1505,24 @@ void form_submit(nsurl *page_url, struct browser_window *target,
}
/* Replace query segment */
- components.query = data;
-
- /* Construct submit url */
- url = url_reform_components(&components);
- if (url == NULL) {
+ if (nsurl_replace_query(action, data, &action_query) !=
+ NSERROR_OK) {
+ nsurl_unref(action);
free(data);
fetch_multipart_data_destroy(success);
warn_user("NoMemory", 0);
return;
}
- url_destroy_components(&components);
-
- browser_window_go(target, url, nsurl_access(page_url), true);
+ /* Construct submit url */
+ browser_window_go(target, nsurl_access(action_query),
+ nsurl_access(page_url), true);
+ nsurl_unref(action);
+ nsurl_unref(action_query);
break;
case method_POST_URLENC:
- data = form_url_encode(form, success);
+ data = form_url_encode(form, success, false);
if (data == NULL) {
fetch_multipart_data_destroy(success);
warn_user("NoMemory", 0);
@@ -1527,5 +1541,4 @@ void form_submit(nsurl *page_url, struct browser_window *target,
fetch_multipart_data_destroy(success);
free(data);
- free(url);
}
diff --git a/render/form.h b/render/form.h
index c769dc960..67372d5d5 100644
--- a/render/form.h
+++ b/render/form.h
@@ -151,8 +151,6 @@ bool form_add_option(struct form_control *control, char *value, char *text,
bool form_successful_controls(struct form *form,
struct form_control *submit_button,
struct fetch_multipart_data **successful_controls);
-char *form_url_encode(struct form *form,
- struct fetch_multipart_data *control);
bool form_open_select_menu(void *client_data,
struct form_control *control,
diff --git a/utils/url.c b/utils/url.c
index f7a7cd634..447f85c5a 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -167,6 +167,197 @@ out_true:
return true;
}
+/**
+ * Split a URL into separate components
+ *
+ * URLs passed to this function are assumed to be valid and no error checking
+ * or recovery is attempted.
+ *
+ * See RFC 3986 for reference.
+ *
+ * \param url a valid absolute or relative URL
+ * \param result pointer to buffer to hold components
+ * \return URL_FUNC_OK on success
+ */
+
+static url_func_result url_get_components(const char *url,
+ struct url_components *result)
+{
+ int storage_length;
+ char *storage_end;
+ const char *scheme;
+ const char *authority;
+ const char *path;
+ const char *query;
+ const char *fragment;
+ struct url_components_internal *internal;
+
+ assert(url);
+
+ /* clear our return value */
+ internal = (struct url_components_internal *)result;
+ memset(result, 0x00, sizeof(struct url_components));
+
+ /* get enough storage space for a URL with termination at each node */
+ storage_length = strlen(url) + 8;
+ internal->buffer = malloc(storage_length);
+ if (!internal->buffer)
+ return URL_FUNC_NOMEM;
+ storage_end = internal->buffer;
+
+ /* look for a valid scheme */
+ scheme = url;
+ if (isalpha(*scheme)) {
+ for (scheme = url + 1;
+ ((*scheme != ':') && (*scheme != '\0'));
+ scheme++) {
+ if (!isalnum(*scheme) && (*scheme != '+') &&
+ (*scheme != '-') && (*scheme != '.'))
+ break;
+ }
+
+ if (*scheme == ':') {
+ memcpy(storage_end, url, scheme - url);
+ storage_end[scheme - url] = '\0';
+ result->scheme = storage_end;
+ storage_end += scheme - url + 1;
+ scheme++;
+ } else {
+ scheme = url;
+ }
+ }
+
+
+ /* look for an authority */
+ authority = scheme;
+ if ((authority[0] == '/') && (authority[1] == '/')) {
+ authority = strpbrk(scheme + 2, "/?#");
+ if (!authority)
+ authority = scheme + strlen(scheme);
+ memcpy(storage_end, scheme + 2, authority - scheme - 2);
+ storage_end[authority - scheme - 2] = '\0';
+ result->authority = storage_end;
+ storage_end += authority - scheme - 1;
+ }
+
+
+ /* look for a path */
+ path = authority;
+ if ((*path != '?') && (*path != '#') && (*path != '\0')) {
+ path = strpbrk(path, "?#");
+ if (!path)
+ path = authority + strlen(authority);
+ memcpy(storage_end, authority, path - authority);
+ storage_end[path - authority] = '\0';
+ result->path = storage_end;
+ storage_end += path - authority + 1;
+ }
+
+
+ /* look for a query */
+ query = path;
+ if (*query == '?') {
+ query = strchr(query, '#');
+ if (!query)
+ query = path + strlen(path);
+ memcpy(storage_end, path + 1, query - path - 1);
+ storage_end[query - path - 1] = '\0';
+ result->query = storage_end;
+ storage_end += query - path;
+ }
+
+
+ /* look for a fragment */
+ fragment = query;
+ if (*fragment == '#') {
+ fragment = query + strlen(query);
+
+ /* make a copy of the result for the caller */
+ memcpy(storage_end, query + 1, fragment - query - 1);
+ storage_end[fragment - query - 1] = '\0';
+ result->fragment = storage_end;
+ storage_end += fragment - query;
+ }
+
+ assert((result->buffer + storage_length) >= storage_end);
+ return URL_FUNC_OK;
+}
+
+
+/**
+ * Reform a URL from separate components
+ *
+ * See RFC 3986 for reference.
+ *
+ * \param components the components to reform into a URL
+ * \return a new URL allocated on the heap, or NULL on failure
+ */
+
+static char *url_reform_components(const struct url_components *components)
+{
+ int scheme_len = 0, authority_len = 0, path_len = 0, query_len = 0,
+ fragment_len = 0;
+ char *result, *url;
+
+ /* 5.3 */
+ if (components->scheme)
+ scheme_len = strlen(components->scheme) + 1;
+ if (components->authority)
+ authority_len = strlen(components->authority) + 2;
+ if (components->path)
+ path_len = strlen(components->path);
+ if (components->query)
+ query_len = strlen(components->query) + 1;
+ if (components->fragment)
+ fragment_len = strlen(components->fragment) + 1;
+
+ /* claim memory */
+ url = result = malloc(scheme_len + authority_len + path_len +
+ query_len + fragment_len + 1);
+ if (!url) {
+ LOG(("malloc failed"));
+ return NULL;
+ }
+
+ /* rebuild URL */
+ if (components->scheme) {
+ sprintf(url, "%s:", components->scheme);
+ url += scheme_len;
+ }
+ if (components->authority) {
+ sprintf(url, "//%s", components->authority);
+ url += authority_len;
+ }
+ if (components->path) {
+ sprintf(url, "%s", components->path);
+ url += path_len;
+ }
+ if (components->query) {
+ sprintf(url, "?%s", components->query);
+ url += query_len;
+ }
+ if (components->fragment)
+ sprintf(url, "#%s", components->fragment);
+ return result;
+}
+
+
+/**
+ * Release some url components from memory
+ *
+ * \param result pointer to buffer containing components
+ */
+static void url_destroy_components(const struct url_components *components)
+{
+ const struct url_components_internal *internal;
+
+ assert(components);
+
+ internal = (const struct url_components_internal *)components;
+ if (internal->buffer)
+ free(internal->buffer);
+}
+
/**
* Resolve a relative URL to absolute form.
@@ -685,197 +876,6 @@ url_func_result url_escape(const char *unescaped, size_t toskip,
return URL_FUNC_OK;
}
-/**
- * Split a URL into separate components
- *
- * URLs passed to this function are assumed to be valid and no error checking
- * or recovery is attempted.
- *
- * See RFC 3986 for reference.
- *
- * \param url a valid absolute or relative URL
- * \param result pointer to buffer to hold components
- * \return URL_FUNC_OK on success
- */
-
-url_func_result url_get_components(const char *url,
- struct url_components *result)
-{
- int storage_length;
- char *storage_end;
- const char *scheme;
- const char *authority;
- const char *path;
- const char *query;
- const char *fragment;
- struct url_components_internal *internal;
-
- assert(url);
-
- /* clear our return value */
- internal = (struct url_components_internal *)result;
- memset(result, 0x00, sizeof(struct url_components));
-
- /* get enough storage space for a URL with termination at each node */
- storage_length = strlen(url) + 8;
- internal->buffer = malloc(storage_length);
- if (!internal->buffer)
- return URL_FUNC_NOMEM;
- storage_end = internal->buffer;
-
- /* look for a valid scheme */
- scheme = url;
- if (isalpha(*scheme)) {
- for (scheme = url + 1;
- ((*scheme != ':') && (*scheme != '\0'));
- scheme++) {
- if (!isalnum(*scheme) && (*scheme != '+') &&
- (*scheme != '-') && (*scheme != '.'))
- break;
- }
-
- if (*scheme == ':') {
- memcpy(storage_end, url, scheme - url);
- storage_end[scheme - url] = '\0';
- result->scheme = storage_end;
- storage_end += scheme - url + 1;
- scheme++;
- } else {
- scheme = url;
- }
- }
-
-
- /* look for an authority */
- authority = scheme;
- if ((authority[0] == '/') && (authority[1] == '/')) {
- authority = strpbrk(scheme + 2, "/?#");
- if (!authority)
- authority = scheme + strlen(scheme);
- memcpy(storage_end, scheme + 2, authority - scheme - 2);
- storage_end[authority - scheme - 2] = '\0';
- result->authority = storage_end;
- storage_end += authority - scheme - 1;
- }
-
-
- /* look for a path */
- path = authority;
- if ((*path != '?') && (*path != '#') && (*path != '\0')) {
- path = strpbrk(path, "?#");
- if (!path)
- path = authority + strlen(authority);
- memcpy(storage_end, authority, path - authority);
- storage_end[path - authority] = '\0';
- result->path = storage_end;
- storage_end += path - authority + 1;
- }
-
-
- /* look for a query */
- query = path;
- if (*query == '?') {
- query = strchr(query, '#');
- if (!query)
- query = path + strlen(path);
- memcpy(storage_end, path + 1, query - path - 1);
- storage_end[query - path - 1] = '\0';
- result->query = storage_end;
- storage_end += query - path;
- }
-
-
- /* look for a fragment */
- fragment = query;
- if (*fragment == '#') {
- fragment = query + strlen(query);
-
- /* make a copy of the result for the caller */
- memcpy(storage_end, query + 1, fragment - query - 1);
- storage_end[fragment - query - 1] = '\0';
- result->fragment = storage_end;
- storage_end += fragment - query;
- }
-
- assert((result->buffer + storage_length) >= storage_end);
- return URL_FUNC_OK;
-}
-
-
-/**
- * Reform a URL from separate components
- *
- * See RFC 3986 for reference.
- *
- * \param components the components to reform into a URL
- * \return a new URL allocated on the heap, or NULL on failure
- */
-
-char *url_reform_components(const struct url_components *components)
-{
- int scheme_len = 0, authority_len = 0, path_len = 0, query_len = 0,
- fragment_len = 0;
- char *result, *url;
-
- /* 5.3 */
- if (components->scheme)
- scheme_len = strlen(components->scheme) + 1;
- if (components->authority)
- authority_len = strlen(components->authority) + 2;
- if (components->path)
- path_len = strlen(components->path);
- if (components->query)
- query_len = strlen(components->query) + 1;
- if (components->fragment)
- fragment_len = strlen(components->fragment) + 1;
-
- /* claim memory */
- url = result = malloc(scheme_len + authority_len + path_len +
- query_len + fragment_len + 1);
- if (!url) {
- LOG(("malloc failed"));
- return NULL;
- }
-
- /* rebuild URL */
- if (components->scheme) {
- sprintf(url, "%s:", components->scheme);
- url += scheme_len;
- }
- if (components->authority) {
- sprintf(url, "//%s", components->authority);
- url += authority_len;
- }
- if (components->path) {
- sprintf(url, "%s", components->path);
- url += path_len;
- }
- if (components->query) {
- sprintf(url, "?%s", components->query);
- url += query_len;
- }
- if (components->fragment)
- sprintf(url, "#%s", components->fragment);
- return result;
-}
-
-
-/**
- * Release some url components from memory
- *
- * \param result pointer to buffer containing components
- */
-void url_destroy_components(const struct url_components *components)
-{
- const struct url_components_internal *internal;
-
- assert(components);
-
- internal = (const struct url_components_internal *)components;
- if (internal->buffer)
- free(internal->buffer);
-}
-
#ifdef TEST
diff --git a/utils/url.h b/utils/url.h
index fa27a4874..7c716d723 100644
--- a/utils/url.h
+++ b/utils/url.h
@@ -58,11 +58,6 @@ url_func_result url_escape(const char *unescaped, size_t toskip,
url_func_result url_unescape(const char *str, char **result);
url_func_result url_path(const char *url, char **result);
-url_func_result url_get_components(const char *url,
- struct url_components *result);
-char *url_reform_components(const struct url_components *components);
-void url_destroy_components(const struct url_components *components);
-
char *path_to_url(const char *path);
char *url_to_path(const char *url);