AST_RWLIST_TRAVERSE_SAFE_END
}
+/*
+ * Decode special characters in http uri.
+ * We have ast_uri_decode to handle %XX sequences, but spaces
+ * are encoded as a '+' so we need to replace them beforehand.
+ */
+static void http_decode(char *s)
+{
+ for (;*s; s++) {
+ if (*s == '+')
+ *s = ' ';
+ }
+ ast_uri_decode(s);
+}
+
static struct ast_str *handle_uri(struct ast_tcptls_session_instance *ser, char *uri, enum ast_http_method method,
int *status, char **title, int *contentlength, struct ast_variable **cookies, struct ast_variable *headers,
unsigned int *static_content)
if (method == AST_HTTP_GET) {
strsep(¶ms, "?");
- /* Extract arguments from the request and store them in variables. */
+ /* Extract arguments from the request and store them in variables.
+ * Note that a request can have multiple arguments with the same
+ * name, and we store them all in the list of variables.
+ * It is up to the application to handle multiple values.
+ */
if (params) {
char *var, *val;
while ((val = strsep(¶ms, "&"))) {
var = strsep(&val, "=");
if (val) {
- ast_uri_decode(val);
+ http_decode(val);
} else {
val = "";
}
- ast_uri_decode(var);
+ http_decode(var);
if ((v = ast_variable_new(var, val, ""))) {
if (vars) {
prev->next = v;
}
/*
- * Append the cookies to the variables (the only reason to have them
- * at the end is to avoid another pass of the cookies list to find
- * the tail).
+ * Append the cookies to the list of variables.
+ * This saves a pass in the cookies list, but has the side effect
+ * that a variable might mask a cookie with the same name if the
+ * application stops at the first match.
+ * Note that this is the same behaviour as $_REQUEST variables in PHP.
*/
if (prev) {
prev->next = *cookies;
}
*cookies = NULL;
- ast_uri_decode(uri);
+ http_decode(uri);
AST_RWLIST_RDLOCK(&uri_redirects);
AST_RWLIST_TRAVERSE(&uri_redirects, redirect, entry) {