Permalink
Browse files

Added Content-Disposition.

  • Loading branch information...
1 parent 48b2658 commit 683cd7759f9bb4de957eecf3f159339b0c43f457 @nicolasff committed May 31, 2011
Showing with 34 additions and 3 deletions.
  1. +17 −0 client.c
  2. +1 −0 client.h
  3. +5 −0 cmd.c
  4. +4 −1 cmd.h
  5. +7 −2 formats/common.c
View
17 client.c
@@ -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;
View
1 client.h
@@ -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;
};
View
5 cmd.c
@@ -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;
}
View
5 cmd.h
@@ -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;
View
9 formats/common.c
@@ -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);

0 comments on commit 683cd77

Please sign in to comment.