*(p++) = 0;
else if (*p == '#')
*p = 0;
- len = url_decode(key);
+ len = url_decode(key, 1);
if (len == -1)
goto error;
*(p++) = 0;
else if (*p == '#')
*p = 0;
- len = url_decode(value);
+ len = url_decode(value, 1);
if (len == -1)
goto error;
}
sample fetch function or after a transformation keyword returning a string
type. The result is of type string.
-url_dec
- Takes an url-encoded string provided as input and returns the decoded
- version as output. The input and the output are of type string.
+url_dec([<in_form>])
+ Takes an url-encoded string provided as input and returns the decoded version
+ as output. The input and the output are of type string. If the <in_form>
+ argument is set to a non-zero integer value, the input string is assumed to
+ be part of a form or query string and the '+' character will be turned into a
+ space (' '). Otherwise this will only happen after a question mark indicating
+ a query string ('?').
ungrpc(<field_number>,[<field_type>])
This extracts the protocol buffers message field in raw mode of an input binary
* be shorter. If some forbidden characters are found, the conversion is
* aborted, the string is truncated before the issue and non-zero is returned,
* otherwise the operation returns non-zero indicating success.
+ * If the 'in_form' argument is non-nul the string is assumed to be part of
+ * an "application/x-www-form-urlencoded" encoded string, and the '+' will be
+ * turned to a space. If it's zero, this will only be done after a question
+ * mark ('?').
*/
-int url_decode(char *string);
+int url_decode(char *string, int in_form);
/* This one is 6 times faster than strtoul() on athlon, but does
* no check at all.
/* This fetch url-decode any input string. */
static int sample_conv_url_dec(const struct arg *args, struct sample *smp, void *private)
{
+ int in_form = 0;
int len;
/* If the constant flag is set or if not size is available at
/* Add final \0 required by url_decode(), and convert the input string. */
smp->data.u.str.area[smp->data.u.str.data] = '\0';
- len = url_decode(smp->data.u.str.area);
+
+ if (args && (args[0].type == ARGT_SINT))
+ in_form = !!args[0].data.sint;
+
+ len = url_decode(smp->data.u.str.area, in_form);
if (len < 0)
return 0;
smp->data.u.str.data = len;
{ "language", sample_conv_q_preferred, ARG2(1,STR,STR), NULL, SMP_T_STR, SMP_T_STR},
{ "capture-req", smp_conv_req_capture, ARG1(1,SINT), NULL, SMP_T_STR, SMP_T_STR},
{ "capture-res", smp_conv_res_capture, ARG1(1,SINT), NULL, SMP_T_STR, SMP_T_STR},
- { "url_dec", sample_conv_url_dec, 0, NULL, SMP_T_STR, SMP_T_STR},
+ { "url_dec", sample_conv_url_dec, ARG1(0,SINT), NULL, SMP_T_STR, SMP_T_STR},
{ NULL, NULL, 0, 0, 0 },
}};
chunk_memcat(params->p, path.ptr, path.len);
path.ptr = b_tail(params->p) - path.len;
path.ptr[path.len] = '\0';
- len = url_decode(path.ptr);
+ len = url_decode(path.ptr, 0);
if (len < 0)
goto error;
path.len = len;
* be shorter. If some forbidden characters are found, the conversion is
* aborted, the string is truncated before the issue and a negative value is
* returned, otherwise the operation returns the length of the decoded string.
+ * If the 'in_form' argument is non-nul the string is assumed to be part of
+ * an "application/x-www-form-urlencoded" encoded string, and the '+' will be
+ * turned to a space. If it's zero, this will only be done after a question
+ * mark ('?').
*/
-int url_decode(char *string)
+int url_decode(char *string, int in_form)
{
char *in, *out;
int ret = -1;
while (*in) {
switch (*in) {
case '+' :
- *out++ = ' ';
+ *out++ = in_form ? ' ' : *in;
break;
case '%' :
if (!ishex(in[1]) || !ishex(in[2]))
*out++ = (hex2i(in[1]) << 4) + hex2i(in[2]);
in += 2;
break;
+ case '?':
+ in_form = 1;
+ /* fall through */
default:
*out++ = *in;
break;
/* Ok, a value is found, we can mark the end of the key */
*value++ = '\0';
}
- if (url_decode(key) < 0 || url_decode(value) < 0)
+ if (url_decode(key, 1) < 0 || url_decode(value, 1) < 0)
break;
/* Now we can check the key to see what to do */