fetch extension - use local filename from content-disposition header

Panagiotis Astithas past at ebs.gr
Fri Dec 30 02:29:54 PST 2005


Martin Cracauer wrote:
> I'm a bit rusty, so please point me to style mistakes in the appended
> diff. 
> 
> The following diff implements a "-O" option to fetch(1), which, when
> set, will make fetch use a local filename supplied by the server in a
> Content-Disposition header.
> 
> The most common case for this is when things are stored on a web
> server by users and there handled as "attachments".  The URL filename
> will say "http://foo.bar.com/attachment.php?attid=42" which is useless
> as a local filename.
> 
> However, popular web software like the vBulletion forum system and
> Bugzilla internally store the original filename (e.g. "mysystem.jpg"
> which it was when the uploader submitted it) and provide it to the
> client in a Content-Disposition header.
> 
> If you visit such an attachment in Mozilla, you will see that using
> the "save" function will default to the original filename.
> 
> This extension to fetch implements the same thing.
> 
> You can test it here:
> http://www.cons.org/tmp/content-disposition.cgi
> 
> Open in browser, say "save to disk", it will default to "foo.txt"
> instead of "content-disposition.cgi".  Same if you use the new fetch
> with -O.  Or test on any attachment on a modern version of vBulletin.
> 
> If you use Bugzilla somewhere, use this fetch to get an attachment
> with "-O" and you'll be thankful that it got the original filename,
> e.g. "reproduce-bug.query".
> 
> Martin
> 
> 

[...]

> Index: lib/libfetch/http.c
> ===================================================================
> RCS file: /home/CVS-FreeBSD/src/lib/libfetch/http.c,v
> retrieving revision 1.77
> diff -u -r1.77 http.c
> --- lib/libfetch/http.c	24 Aug 2005 12:28:05 -0000	1.77
> +++ lib/libfetch/http.c	30 Dec 2005 00:11:38 -0000
> @@ -334,6 +334,7 @@
>  	hdr_error = -1,
>  	hdr_end = 0,
>  	hdr_unknown = 1,
> +	hdr_content_disposition,
>  	hdr_content_length,
>  	hdr_content_range,
>  	hdr_last_modified,
> @@ -347,6 +348,7 @@
>  	hdr_t		 num;
>  	const char	*name;
>  } hdr_names[] = {
> +	{ hdr_content_disposition,	"Content-Disposition" },
>  	{ hdr_content_length,		"Content-Length" },
>  	{ hdr_content_range,		"Content-Range" },
>  	{ hdr_last_modified,		"Last-Modified" },
> @@ -549,6 +551,30 @@
>  	return (0);
>  }
>  
> +/*
> + * Parse a content-composition header

You probably meant content-disposition here.

> + */
> +static char *
> +_http_parse_content_disposition(const char *p)
> +{
> +	char *s, *s2;
> +	const char *looking_for = "filename=\"";
> +
> +	if ((s = strstr(p, looking_for))) {
> +		s = strdup(s + strlen(looking_for));
> +		if ((s2 = strchr(s, '"'))) {
> +			*s2 = '\0';
> +			return s;
> +		} else {
> +			free(s);
> +			return NULL;
> +		}
> +			
> +	} else {
> +		return NULL;
> +	}
> +}
> +
>  
>  /*****************************************************************************
>   * Helper functions for authorization
> @@ -991,6 +1017,10 @@
>  			case hdr_error:
>  				_http_seterr(HTTP_PROTOCOL_ERROR);
>  				goto ouch;
> +			case hdr_content_disposition:
> +				us->content_disposition = 
> +					_http_parse_content_disposition(p);
> +				break;
>  			case hdr_content_length:
>  				_http_parse_length(p, &clength);
>  				break;
> 
> 


FWIW, I find this very useful.

Cheers,

Panagiotis


More information about the freebsd-current mailing list