コード例 #1
0
ファイル: http.c プロジェクト: snip/aprsc
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);
}
コード例 #2
0
ファイル: z_rss.c プロジェクト: oripka/bagunceiro
void rss_http_header()
{
	http_content_type("application/rss+xml");
}