static void http_route_static(struct evhttp_request *r, const char *uri) { struct http_static_t *cmdp; struct stat st; char fname[HTTP_FNAME_LEN]; char last_modified[128]; char *contenttype; int fd; int file_size; char *buf; struct evkeyvalq *req_headers; const char *ims; for (cmdp = http_static_files; cmdp->name != NULL; cmdp++) if (strcmp(cmdp->name, uri) == 0) break; if (cmdp->name == NULL) { hlog(LOG_DEBUG, "HTTP: 404"); evhttp_send_error(r, HTTP_NOTFOUND, "Not found"); return; } snprintf(fname, HTTP_FNAME_LEN, "%s/%s", webdir, cmdp->filename); //hlog(LOG_DEBUG, "static file request %s", uri); fd = open(fname, 0, O_RDONLY); if (fd < 0) { if (errno == ENOENT) { /* don't complain about missing motd.html - it's optional. */ int level = LOG_ERR; if (strcmp(cmdp->filename, "motd.html") == 0) level = LOG_DEBUG; hlog(level, "http static file '%s' not found", fname); evhttp_send_error(r, HTTP_NOTFOUND, "Not found"); return; } hlog(LOG_ERR, "http static file '%s' could not be opened for reading: %s", fname, strerror(errno)); evhttp_send_error(r, HTTP_INTERNAL, "Could not access file"); return; } if (fstat(fd, &st) == -1) { hlog(LOG_ERR, "http static file '%s' could not fstat() after opening: %s", fname, strerror(errno)); evhttp_send_error(r, HTTP_INTERNAL, "Could not access file"); if (close(fd) < 0) hlog(LOG_ERR, "http static file '%s' could not be closed after failed stat: %s", fname, strerror(errno)); return; } http_date(last_modified, sizeof(last_modified), st.st_mtime); contenttype = http_content_type(cmdp->filename); //hlog(LOG_DEBUG, "found content-type %s", contenttype); struct evkeyvalq *headers = evhttp_request_get_output_headers(r); http_header_base(headers, st.st_mtime); evhttp_add_header(headers, "Content-Type", contenttype); /* Consider an IMS hit */ req_headers = evhttp_request_get_input_headers(r); ims = evhttp_find_header(req_headers, "If-Modified-Since"); if ((ims) && strcasecmp(ims, last_modified) == 0) { hlog(LOG_DEBUG, "http static file '%s' IMS hit", fname); evhttp_send_reply(r, HTTP_NOTMODIFIED, "Not modified", NULL); if (close(fd) < 0) hlog(LOG_ERR, "http static file '%s' could not be closed after failed stat: %s", fname, strerror(errno)); return; } file_size = st.st_size; /* yes, we are not going to serve large files. */ buf = hmalloc(file_size); int n = read(fd, buf, file_size); if (close(fd) < 0) { hlog(LOG_ERR, "http static file '%s' could not be closed after reading: %s", fname, strerror(errno)); evhttp_send_error(r, HTTP_INTERNAL, "Could not access file"); hfree(buf); return; } if (n != file_size) { hlog(LOG_ERR, "http static file '%s' could only read %d of %d bytes", fname, n, file_size); evhttp_send_error(r, HTTP_INTERNAL, "Could not access file"); hfree(buf); return; } int allow_compress; if (strncmp(contenttype, "image/", 6) == 0) allow_compress = 0; else allow_compress = 1; http_send_reply_ok(r, headers, buf, n, allow_compress); hfree(buf); }
void rss_http_header() { http_content_type("application/rss+xml"); }