//404 void resp_error_page( header_out_t* header_out, int status_code ) { if ( status_code >= 400 && status_code <= 507 ) { int ret = resp_defined_error_page( header_out , status_code ); if ( ret == 1 ) { return; } } //get header info header_status_t error_page = get_http_status( status_code ); int datalen = strlen( error_page.data ); //header append //resp_append_header( header_out , HEADER_STATUS , error_page.status ); //resp_append_header( header_out , HEADER_SERVER ); create_common_header( header_out , status_code ); header_append_length( header_out , datalen ); resp_append_header( header_out , HEADER_END_LINE ); //send http_response_write( header_out->req->connfd, header_out->data , header_out->length ); http_response_write( header_out->req->connfd, error_page.data , datalen ); http_close( header_out->req , 0 ); }
/* Simple error response */ void http_send_error(struct http_client *c, short code, const char *msg) { struct http_response resp; http_response_init(&resp, code, msg); resp.http_version = c->http_version; http_response_set_connection_header(c, &resp); http_response_set_body(&resp, NULL, 0); http_response_write(&resp, c->fd); http_client_reset(c); }
/* Response to HTTP OPTIONS */ void http_send_options(struct http_client *c) { struct http_response resp; http_response_init(&resp, 200, "OK"); resp.http_version = c->http_version; http_response_set_connection_header(c, &resp); http_response_set_header(&resp, "Content-Type", "text/html"); http_response_set_header(&resp, "Content-Length", "0"); http_response_write(&resp, c->fd); http_client_reset(c); }
void http_redirect( httpHeader* reqHeader , char* uri ) { header_out_t header_out; memset( &header_out , 0 , sizeof( header_out )); header_out.req = reqHeader; header_status_t error_page = get_http_status( 301 ); //header append create_common_header( &header_out , 301 ); resp_append_header( &header_out , HEADER_LOCATION , uri ); resp_append_header( &header_out , HEADER_CONTENT_LENGTH , 0 ); resp_append_header( &header_out , HEADER_END_LINE ); http_response_write( reqHeader->connfd , header_out.data , header_out.length ); http_close( reqHeader , 0 ); }
void custom_type_reply(redisAsyncContext *c, void *r, void *privdata) { redisReply *reply = r; struct cmd *cmd = privdata; (void)c; char int_buffer[50]; int int_len; struct http_response resp; if (reply == NULL) { /* broken Redis link */ format_send_error(cmd, 503, "Service Unavailable"); return; } if(cmd->mime) { /* use the given content-type, but only for strings */ switch(reply->type) { case REDIS_REPLY_NIL: /* or nil values */ format_send_reply(cmd, "", 0, cmd->mime); return; case REDIS_REPLY_STRING: format_send_reply(cmd, reply->str, reply->len, cmd->mime); return; case REDIS_REPLY_INTEGER: int_len = sprintf(int_buffer, "%lld", reply->integer); format_send_reply(cmd, int_buffer, int_len, cmd->mime); return; case REDIS_REPLY_ARRAY: # TODO: Avoid assuming the command is BLPOP. format_send_reply(cmd, reply->element[1]->str, reply->element[1]->len, cmd->mime); return; } } /* couldn't make sense of what the client wanted. */ http_response_init(&resp, 401, "Bad Request"); http_response_set_header(&resp, "Content-Length", "0"); http_response_set_keep_alive(&resp, cmd->keep_alive); http_response_write(&resp, cmd->fd); cmd_free(cmd); }
void format_send_error(struct cmd *cmd, short code, const char *msg) { struct http_response *resp; if(!cmd->is_websocket && !cmd->pub_sub_client) { resp = http_response_init(cmd->w, code, msg); resp->http_version = cmd->http_version; http_response_set_keep_alive(resp, cmd->keep_alive); http_response_write(resp, cmd->fd); } /* for pub/sub, remove command from client */ if(cmd->pub_sub_client) { cmd->pub_sub_client->pub_sub = NULL; } else { cmd_free(cmd); } }
/* Adobe flash cross-domain request */ void http_crossdomain(struct http_client *c) { struct http_response resp; char out[] = "<?xml version=\"1.0\"?>\n" "<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n" "<cross-domain-policy>\n" "<allow-access-from domain=\"*\" />\n" "</cross-domain-policy>\n"; http_response_init(&resp, 200, "OK"); resp.http_version = c->http_version; http_response_set_connection_header(c, &resp); http_response_set_header(&resp, "Content-Type", "application/xml"); http_response_set_body(&resp, out, sizeof(out)-1); http_response_write(&resp, c->fd); http_client_reset(c); }
void format_send_reply(struct cmd *cmd, const char *p, size_t sz, const char *content_type) { int free_cmd = 1; const char *ct = cmd->mime?cmd->mime:content_type; struct http_response *resp; if(cmd->is_websocket) { ws_reply(cmd, p, sz); /* If it's a subscribe command, there'll be more responses */ if(!cmd_is_subscribe(cmd)) cmd_free(cmd); return; } if(cmd_is_subscribe(cmd)) { free_cmd = 0; /* start streaming */ if(cmd->started_responding == 0) { cmd->started_responding = 1; resp = http_response_init(cmd->w, 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"); http_response_set_body(resp, p, sz); http_response_write(resp, cmd->fd); } else { /* Asynchronous chunk write. */ http_response_write_chunk(cmd->fd, cmd->w, p, sz); } } else { /* compute ETag */ char *etag = etag_new(p, sz); if(etag) { /* check If-None-Match */ if(cmd->if_none_match && strcmp(cmd->if_none_match, etag) == 0) { /* SAME! send 304. */ resp = http_response_init(cmd->w, 304, "Not Modified"); } else { resp = http_response_init(cmd->w, 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); } resp->http_version = cmd->http_version; http_response_set_keep_alive(resp, cmd->keep_alive); http_response_write(resp, cmd->fd); free(etag); } else { format_send_error(cmd, 503, "Service Unavailable"); } } /* cleanup */ if(free_cmd) { cmd_free(cmd); } }