Created
August 18, 2011 17:11
-
-
Save mythosil/1154552 to your computer and use it in GitHub Desktop.
evhttp returns static files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <errno.h> | |
#include <sys/stat.h> | |
#include <event.h> | |
#include <evhttp.h> | |
#define HTTPD_ADDR "0.0.0.0" | |
#define HTTPD_PORT 8080 | |
#define DOCUMENT_ROOT "./" | |
static const char *get_mime_type(const char *filetype) | |
{ | |
if (filetype == NULL || | |
strcasecmp(filetype, "html") == 0 || | |
strcasecmp(filetype, "htm") == 0) | |
return "text/html"; | |
else if (strcasecmp(filetype, "js") == 0) | |
return "text/javascript"; | |
else if (strcasecmp(filetype, "css") == 0) | |
return "text/css"; | |
else if (strcasecmp(filetype, "txt") == 0) | |
return "text/plain"; | |
else if (strcasecmp(filetype, "ico") == 0) | |
return "image/x-icon"; | |
else if (strcasecmp(filetype, "png") == 0) | |
return "image/png"; | |
else if (strcasecmp(filetype, "gif") == 0) | |
return "image/gif"; | |
else if (strcasecmp(filetype, "jpeg") == 0 || | |
strcasecmp(filetype, "jpg") == 0) | |
return "image/jpeg"; | |
return "application/ocet-stream"; | |
} | |
static char *get_file_content(const char *req_path, int *content_length) | |
{ | |
struct stat sb; | |
static char filepath[1024]; | |
char *content; | |
FILE *fp; | |
int rsize; | |
sprintf(filepath, "%s%s", DOCUMENT_ROOT, req_path); | |
if (stat(filepath, &sb) < 0) /* not found */ | |
return NULL; | |
if (S_ISDIR(sb.st_mode)) { | |
sprintf(filepath, "%s%s/index.html", DOCUMENT_ROOT, req_path); | |
if (stat(filepath, &sb) < 0) /* not found */ | |
return NULL; | |
} | |
*content_length = (int)sb.st_size; | |
fp = fopen(filepath, "rb"); | |
content = NULL; | |
if (fp) { | |
content = (char *)malloc(*content_length); | |
rsize = fread(content, 1, *content_length, fp); | |
fclose(fp); | |
if (rsize != *content_length) { | |
free(content); | |
content = NULL; | |
} | |
} | |
return content; | |
} | |
void req_handler(struct evhttp_request *r, void *arg) | |
{ | |
struct evbuffer *evbuf; | |
const char *req_path, *filetype, *mime_type; | |
char *content; | |
int content_length; | |
char content_length_str[12]; | |
if (r->type != EVHTTP_REQ_GET) { | |
evhttp_send_error(r, HTTP_BADREQUEST, "available GET only"); | |
return; | |
} | |
req_path = evhttp_request_uri(r); | |
content = get_file_content(req_path, &content_length); | |
if (content == NULL) { | |
evhttp_send_error(r, HTTP_NOTFOUND, "Not Found"); | |
return; | |
} | |
filetype = strrchr(req_path, '.'); | |
if (filetype == NULL) | |
mime_type = get_mime_type(NULL); | |
else | |
mime_type = get_mime_type(filetype + 1); | |
sprintf(content_length_str, "%d", content_length); | |
evhttp_add_header(r->output_headers, "Content-Type", mime_type); | |
evhttp_add_header(r->output_headers, "Content-Length", content_length_str); | |
evbuf = evbuffer_new(); | |
if (evbuf == NULL) { | |
evhttp_send_error(r, HTTP_SERVUNAVAIL, "failed to create buffer"); | |
free(content); | |
return; | |
} | |
evbuffer_add(evbuf, content, content_length); | |
evhttp_send_reply(r, HTTP_OK, "", evbuf); | |
evbuffer_free(evbuf); | |
free(content); | |
} | |
int main(int argc, const char* argv[]) | |
{ | |
struct event_base *ev_base; | |
struct evhttp *httpd; | |
ev_base = event_base_new(); | |
httpd = evhttp_new(ev_base); | |
if (evhttp_bind_socket(httpd, HTTPD_ADDR, HTTPD_PORT) < 0) { | |
perror("evhttp_bind_socket()"); | |
exit(EXIT_FAILURE); | |
} | |
evhttp_set_gencb(httpd, req_handler, NULL); | |
event_base_dispatch(ev_base); | |
evhttp_free(httpd); | |
event_base_free(ev_base); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
oops, there're terrible bugs.
should not return text/html for filetype == NULL (in get_mime_type).
also, not considering security.