mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
Support RFC 2231.
This commit is contained in:
parent
d92049ef66
commit
d5361eca21
@ -1,3 +1,8 @@
|
|||||||
|
2009-09-22 Arvind Jamuna Dixit <ardsrk@gmail.com>
|
||||||
|
|
||||||
|
* http.c (extract_param, parse_content_disposition): Support
|
||||||
|
RFC 2231 while parsing Content-Disposition header
|
||||||
|
|
||||||
2009-10-24 Petr Pisar <petr.pisar@atlas.cz>
|
2009-10-24 Petr Pisar <petr.pisar@atlas.cz>
|
||||||
|
|
||||||
* openssl.c: Implement support for (multiple) subjectAltNames in
|
* openssl.c: Implement support for (multiple) subjectAltNames in
|
||||||
|
114
src/http.c
114
src/http.c
@ -942,6 +942,66 @@ skip_short_body (int fd, wgint contlen)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define NOT_RFC2231 0
|
||||||
|
#define RFC2231_NOENCODING 1
|
||||||
|
#define RFC2231_ENCODING 2
|
||||||
|
|
||||||
|
/* extract_param extracts the parameter name into NAME.
|
||||||
|
However, if the parameter name is in RFC2231 format then
|
||||||
|
this function adjusts NAME by stripping of the trailing
|
||||||
|
characters that are not part of the name but are present to
|
||||||
|
indicate the presence of encoding information in the value
|
||||||
|
or a fragment of a long parameter value
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
modify_param_name(param_token *name)
|
||||||
|
{
|
||||||
|
const char *delim1 = memchr (name->b, '*', name->e - name->b);
|
||||||
|
const char *delim2 = memrchr (name->b, '*', name->e - name->b);
|
||||||
|
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if(delim1 == NULL)
|
||||||
|
{
|
||||||
|
result = NOT_RFC2231;
|
||||||
|
}
|
||||||
|
else if(delim1 == delim2)
|
||||||
|
{
|
||||||
|
if ((name->e - 1) == delim1)
|
||||||
|
{
|
||||||
|
result = RFC2231_ENCODING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = RFC2231_NOENCODING;
|
||||||
|
}
|
||||||
|
name->e = delim1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name->e = delim1;
|
||||||
|
result = RFC2231_ENCODING;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* extract_param extract the paramater value into VALUE.
|
||||||
|
Like modify_param_name this function modifies VALUE by
|
||||||
|
stripping off the encoding information from the actual value
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
modify_param_value (param_token *value, int encoding_type )
|
||||||
|
{
|
||||||
|
if (RFC2231_ENCODING == encoding_type)
|
||||||
|
{
|
||||||
|
const char *delim = memrchr (value->b, '\'', value->e - value->b);
|
||||||
|
if ( delim != NULL )
|
||||||
|
{
|
||||||
|
value->b = (delim+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Extract a parameter from the string (typically an HTTP header) at
|
/* Extract a parameter from the string (typically an HTTP header) at
|
||||||
**SOURCE and advance SOURCE to the next parameter. Return false
|
**SOURCE and advance SOURCE to the next parameter. Return false
|
||||||
when there are no more parameters to extract. The name of the
|
when there are no more parameters to extract. The name of the
|
||||||
@ -1013,9 +1073,31 @@ extract_param (const char **source, param_token *name, param_token *value,
|
|||||||
if (*p == separator) ++p;
|
if (*p == separator) ++p;
|
||||||
}
|
}
|
||||||
*source = p;
|
*source = p;
|
||||||
|
|
||||||
|
int param_type = modify_param_name(name);
|
||||||
|
if (NOT_RFC2231 != param_type)
|
||||||
|
{
|
||||||
|
modify_param_value(value, param_type);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef NOT_RFC2231
|
||||||
|
#undef RFC2231_NOENCODING
|
||||||
|
#undef RFC2231_ENCODING
|
||||||
|
|
||||||
|
/* Appends the string represented by VALUE to FILENAME */
|
||||||
|
|
||||||
|
static void
|
||||||
|
append_value_to_filename (char **filename, param_token const * const value)
|
||||||
|
{
|
||||||
|
int original_length = strlen(*filename);
|
||||||
|
int new_length = strlen(*filename) + (value->e - value->b);
|
||||||
|
*filename = xrealloc (*filename, new_length+1);
|
||||||
|
memcpy (*filename + original_length, value->b, (value->e - value->b));
|
||||||
|
(*filename)[new_length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
#undef MAX
|
#undef MAX
|
||||||
#define MAX(p, q) ((p) > (q) ? (p) : (q))
|
#define MAX(p, q) ((p) > (q) ? (p) : (q))
|
||||||
|
|
||||||
@ -1035,13 +1117,15 @@ extract_param (const char **source, param_token *name, param_token *value,
|
|||||||
|
|
||||||
The file name is stripped of directory components and must not be
|
The file name is stripped of directory components and must not be
|
||||||
empty. */
|
empty. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
parse_content_disposition (const char *hdr, char **filename)
|
parse_content_disposition (const char *hdr, char **filename)
|
||||||
{
|
{
|
||||||
|
*filename = NULL;
|
||||||
param_token name, value;
|
param_token name, value;
|
||||||
while (extract_param (&hdr, &name, &value, ';'))
|
while (extract_param (&hdr, &name, &value, ';'))
|
||||||
if (BOUNDED_EQUAL_NO_CASE (name.b, name.e, "filename") && value.b != NULL)
|
{
|
||||||
|
int isFilename = BOUNDED_EQUAL_NO_CASE ( name.b, name.e, "filename" );
|
||||||
|
if ( isFilename && value.b != NULL)
|
||||||
{
|
{
|
||||||
/* Make the file name begin at the last slash or backslash. */
|
/* Make the file name begin at the last slash or backslash. */
|
||||||
const char *last_slash = memrchr (value.b, '/', value.e - value.b);
|
const char *last_slash = memrchr (value.b, '/', value.e - value.b);
|
||||||
@ -1054,6 +1138,8 @@ parse_content_disposition (const char *hdr, char **filename)
|
|||||||
continue;
|
continue;
|
||||||
/* Start with the directory prefix, if specified. */
|
/* Start with the directory prefix, if specified. */
|
||||||
if (opt.dir_prefix)
|
if (opt.dir_prefix)
|
||||||
|
{
|
||||||
|
if (!(*filename))
|
||||||
{
|
{
|
||||||
int prefix_length = strlen (opt.dir_prefix);
|
int prefix_length = strlen (opt.dir_prefix);
|
||||||
bool add_slash = (opt.dir_prefix[prefix_length - 1] != '/');
|
bool add_slash = (opt.dir_prefix[prefix_length - 1] != '/');
|
||||||
@ -1070,11 +1156,33 @@ parse_content_disposition (const char *hdr, char **filename)
|
|||||||
(*filename)[total_length] = '\0';
|
(*filename)[total_length] = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
append_value_to_filename (filename, &value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (*filename)
|
||||||
|
{
|
||||||
|
append_value_to_filename (filename, &value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
*filename = strdupdelim (value.b, value.e);
|
*filename = strdupdelim (value.b, value.e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*filename)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Persistent connections. Currently, we cache the most recently used
|
/* Persistent connections. Currently, we cache the most recently used
|
||||||
connection as persistent, provided that the HTTP server agrees to
|
connection as persistent, provided that the HTTP server agrees to
|
||||||
@ -3368,6 +3476,8 @@ test_parse_content_disposition()
|
|||||||
{ "attachment; filename=\"file.ext\"; dummy", "somedir", "somedir/file.ext", true },
|
{ "attachment; filename=\"file.ext\"; dummy", "somedir", "somedir/file.ext", true },
|
||||||
{ "attachment", NULL, NULL, false },
|
{ "attachment", NULL, NULL, false },
|
||||||
{ "attachment", "somedir", NULL, false },
|
{ "attachment", "somedir", NULL, false },
|
||||||
|
{ "attachement; filename*=UTF-8'en-US'hello.txt", NULL, "hello.txt", true },
|
||||||
|
{ "attachement; filename*0=\"hello\"; filename*1=\"world.txt\"", NULL, "helloworld.txt", true },
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i)
|
for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user