Created
August 19, 2011 15:02
-
-
Save mythosil/1156995 to your computer and use it in GitHub Desktop.
evhttp returns static files (bug fixed ver.)
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 *filepath) | |
{ | |
const char *filetype = strrchr(filepath, '.'); | |
if (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 const char *get_content_from_file(const char *req_path, char **content, int *content_length) | |
{ | |
struct stat sb; | |
static char filepath[1024]; | |
FILE *fp; | |
int rsize; | |
*content = NULL; | |
sprintf(filepath, "%s%s", DOCUMENT_ROOT, req_path); | |
if (stat(filepath, &sb) < 0) | |
return filepath; | |
if (S_ISDIR(sb.st_mode)) { | |
if (strcmp(req_path, "/") == 0) | |
sprintf(filepath, "%s%sindex.html", DOCUMENT_ROOT, req_path); | |
else | |
sprintf(filepath, "%s%s/index.html", DOCUMENT_ROOT, req_path); | |
if (stat(filepath, &sb) < 0) | |
return filepath; | |
} | |
*content_length = (int)sb.st_size; | |
fp = fopen(filepath, "rb"); | |
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 filepath; | |
} | |
void req_handler(struct evhttp_request *r, void *arg) | |
{ | |
struct evbuffer *evbuf; | |
const char *req_path, *res_path; | |
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); | |
res_path = get_content_from_file(req_path, &content, &content_length); | |
if (content == NULL) { | |
evhttp_send_error(r, HTTP_NOTFOUND, "Not Found"); | |
return; | |
} | |
sprintf(content_length_str, "%d", content_length); | |
evhttp_add_header(r->output_headers, "Content-Type", get_mime_type(res_path)); | |
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); | |
} | |
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