Added Content-Disposition.

master
Nicolas Favre-Felix 14 years ago
parent 48b26587c1
commit 683cd7759f

@ -72,6 +72,20 @@ http_client_on_header_name(struct http_parser *p, const char *at, size_t sz) {
return 0;
}
static char *
wrap_filename(const char *val, size_t val_len) {
char format[] = "attachment; filename=\"";
size_t sz = sizeof(format) - 1 + val_len + 1;
char *p = calloc(sz + 1, 1);
memcpy(p, format, sizeof(format)-1); /* copy format */
memcpy(p + sizeof(format)-1, val, val_len); /* copy filename */
p[sz-1] = '"';
return p;
}
/*
* Split query string into key/value pairs, process some of them.
*/
@ -109,6 +123,8 @@ http_client_on_query_string(struct http_parser *parser, const char *at, size_t s
|| (key_len == 8 && strncmp(key, "callback", 8) == 0)) {
c->jsonp = calloc(1 + val_len, 1);
memcpy(c->jsonp, val, val_len);
} else if(key_len == 8 && strncmp(key, "filename", 8) == 0) {
c->filename = wrap_filename(val, val_len);
}
if(!amp) {
@ -222,6 +238,7 @@ http_client_reset(struct http_client *c) {
c->path_sz = 0;
free(c->type); c->type = NULL;
free(c->jsonp); c->jsonp = NULL;
free(c->filename); c->filename = NULL;
/* no last known header callback */
c->last_cb = LAST_CB_NONE;

@ -50,6 +50,7 @@ struct http_client {
char *type; /* forced output content-type */
char *jsonp; /* jsonp wrapper */
char *filename; /* content-disposition */
struct cmd *pub_sub;
};

@ -109,6 +109,11 @@ cmd_setup(struct cmd *cmd, struct http_client *client) {
client->jsonp = NULL;
}
if(client->filename) { /* transfer pointer ownership */
cmd->filename = client->filename;
client->filename = NULL;
}
cmd->fd = client->fd;
cmd->http_version = client->http_version;
}

@ -28,10 +28,13 @@ struct cmd {
/* HTTP data */
char *mime; /* forced output content-type */
int mime_free; /* need to free mime buffer */
char *filename; /* content-disposition attachment */
char *if_none_match; /* used with ETags */
char *jsonp; /* jsonp wrapper */
int keep_alive;
int mime_free; /* need to free mime buffer */
/* various flags */
int started_responding;

@ -56,6 +56,7 @@ format_send_reply(struct cmd *cmd, const char *p, size_t sz, const char *content
int free_cmd = 1;
struct http_response resp;
const char *ct = cmd->mime?cmd->mime:content_type;
if(cmd->is_websocket) {
ws_reply(cmd, p, sz);
@ -68,10 +69,12 @@ format_send_reply(struct cmd *cmd, const char *p, size_t sz, const char *content
/* start streaming */
if(cmd->started_responding == 0) {
const char *ct = cmd->mime?cmd->mime:content_type;
cmd->started_responding = 1;
http_response_init(&resp, 200, "OK");
resp.http_version = cmd->http_version;
if(cmd->filename) {
http_response_set_header(&resp, "Content-Disposition", cmd->filename);
}
http_response_set_header(&resp, "Content-Type", ct);
http_response_set_keep_alive(&resp, 1);
http_response_set_header(&resp, "Transfer-Encoding", "chunked");
@ -88,8 +91,10 @@ format_send_reply(struct cmd *cmd, const char *p, size_t sz, const char *content
/* SAME! send 304. */
http_response_init(&resp, 304, "Not Modified");
} else {
const char *ct = cmd->mime?cmd->mime:content_type;
http_response_init(&resp, 200, "OK");
if(cmd->filename) {
http_response_set_header(&resp, "Content-Disposition", cmd->filename);
}
http_response_set_header(&resp, "Content-Type", ct);
http_response_set_header(&resp, "ETag", etag);
http_response_set_body(&resp, p, sz);

Loading…
Cancel
Save