Ejemplo n.º 1
0
int HTTPConnectionSendFile(HTTPConnectionRef const conn, strarg_t const path, strarg_t const type, int64_t size) {
	int rc = async_fs_open(path, O_RDONLY, 0000);
	if(UV_ENOENT == rc) return HTTPConnectionSendStatus(conn, 404);
	if(rc < 0) return HTTPConnectionSendStatus(conn, 400); // TODO: Error conversion.

	uv_file file = rc; rc = 0;
	if(size < 0) {
		uv_fs_t req[1];
		rc = async_fs_fstat(file, req);
		if(rc < 0) {
			rc = HTTPConnectionSendStatus(conn, 400);
			goto cleanup;
		}
		if(S_ISDIR(req->statbuf.st_mode)) {
			rc = UV_EISDIR;
			goto cleanup;
		}
		if(!S_ISREG(req->statbuf.st_mode)) {
			rc = HTTPConnectionSendStatus(conn, 403);
			goto cleanup;
		}
		size = req->statbuf.st_size;
	}
	rc = rc < 0 ? rc : HTTPConnectionWriteResponse(conn, 200, "OK");
	rc = rc < 0 ? rc : HTTPConnectionWriteContentLength(conn, size);
	// TODO: Caching and other headers.
	if(type) rc = rc < 0 ? rc : HTTPConnectionWriteHeader(conn, "Content-Type", type);
	rc = rc < 0 ? rc : HTTPConnectionBeginBody(conn);
	rc = rc < 0 ? rc : HTTPConnectionWriteFile(conn, file);
	rc = rc < 0 ? rc : HTTPConnectionEnd(conn);

cleanup:
	async_fs_close(file); file = -1;
	return rc;
}
Ejemplo n.º 2
0
static void listener(void *ctx, HTTPServerRef const server, HTTPConnectionRef const conn) {
    assert(server);
    assert(conn);
    int rc = listener0(ctx, server, conn);
    if(rc < 0) rc = 404;
    if(rc > 0) HTTPConnectionSendStatus(conn, rc);
}
Ejemplo n.º 3
0
int HTTPConnectionSendFile(HTTPConnectionRef const conn, strarg_t const path, strarg_t const type, int64_t size) {
	uv_file const file = async_fs_open(path, O_RDONLY, 0000);
	if(UV_ENOENT == file) return HTTPConnectionSendStatus(conn, 404);
	if(file < 0) return HTTPConnectionSendStatus(conn, 400); // TODO: Error conversion.
	int rc = 0;
	if(size < 0) {
		uv_fs_t req[1];
		rc = async_fs_fstat(file, req);
		if(rc < 0) return HTTPConnectionSendStatus(conn, 400);
		size = req->statbuf.st_size;
	}
	rc = rc < 0 ? rc : HTTPConnectionWriteResponse(conn, 200, "OK");
	rc = rc < 0 ? rc : HTTPConnectionWriteContentLength(conn, size);
	// TODO: Caching and other headers.
	if(type) rc = rc < 0 ? rc : HTTPConnectionWriteHeader(conn, "Content-Type", type);
	rc = rc < 0 ? rc : HTTPConnectionBeginBody(conn);
	rc = rc < 0 ? rc : HTTPConnectionWriteFile(conn, file);
	rc = rc < 0 ? rc : HTTPConnectionEnd(conn);
	async_fs_close(file);
	return rc;
}
Ejemplo n.º 4
0
static void listener(void *ctx, HTTPServerRef const server, HTTPConnectionRef const conn) {
	assert(server);
	assert(conn);
	str_t URI[URI_MAX]; URI[0] = '\0';
	HTTPHeadersRef headers = NULL;
	SLNSessionRef session = NULL;
	int rc = listener0(server, conn, URI, sizeof(URI), &headers, &session);
	if(rc < 0) rc = 404;
	if(rc > 0) HTTPConnectionSendStatus(conn, rc);
	strarg_t const username = SLNSessionGetUsername(session);
	HTTPConnectionLog(conn, URI, username, headers, SERVER_LOG_FILE);
	SLNSessionRelease(&session);
	HTTPHeadersFree(&headers);
}
static bool_t getPage(EFSRepoRef const repo, HTTPConnectionRef const conn, HTTPMethod const method, strarg_t const URI) {
	if(HTTP_GET != method) return false;
	size_t pathlen = prefix("/", URI);
	if(!pathlen) return false;
	if(!pathterm(URI, (size_t)pathlen)) return false;
	EFSSessionRef const session = auth(repo, conn, method, URI+pathlen);
	if(!session) {
		HTTPConnectionSendStatus(conn, 403);
		return true;
	}

	// TODO: Parse querystring `q` parameter
	EFSFilterRef const filter = EFSFilterCreate(EFSTypeFilter);
	EFSFilterAddStringArg(filter, "text/html; charset=utf-8");

	EFSFileInfo *const files = EFSSessionCreateFileInfoList(session, filter, RESULTS_MAX);

	HTTPConnectionWriteResponse(conn, 200, "OK");
	HTTPConnectionWriteHeader(conn, "Content-Type", "text/html; charset=utf-8");
	HTTPConnectionWriteHeader(conn, "Transfer-Encoding", "chunked");
	HTTPConnectionBeginBody(conn);

	// TODO: Page header

	uv_fs_t req = { .data = co_active(); }
	for(index_t i = 0; i < files->count; ++i) {
		uv_fs_open(loop, &req, path, O_RDONLY, 0400, async_fs_cb);
		co_switch(yield);
		uv_fs_req_cleanup(&req);
		uv_file const file = req.result;
		if(file < 0) continue;
		HTTPConnectionWriteChunkLength(conn, files->items[i].size);
		HTTPConnectionWriteFile(conn, file);
		uv_fs_close(loop, &req, file, async_fs_cb);
		co_switch(yield);
		uv_fs_req_cleanup(&req);
		HTTPConnectionWrite(conn, "\r\n", 2);
	}

	// TODO: Page trailer

	HTTPConnectionWriteChunkLength(conn, 0);
	HTTPConnectionWrite(conn, "\r\n", 2);
	HTTPConnectionEnd(conn);

	EFSFileInfoListFree(files);
	return true;
}