Exemplo n.º 1
0
void uh_chunk_vprintf(struct client *cl, const char *format, va_list arg)
{
	char buf[256];
	va_list arg2;
	int len;

	if (cl->state == CLIENT_STATE_CLEANUP)
		return;

	uloop_timeout_set(&cl->timeout, conf.network_timeout * 1000);
	if (!uh_use_chunked(cl)) {
		ustream_vprintf(cl->us, format, arg);
		return;
	}

	va_copy(arg2, arg);
	len = vsnprintf(buf, sizeof(buf), format, arg2);
	va_end(arg2);

	ustream_printf(cl->us, "%X\r\n", len);
	if (len < sizeof(buf))
		ustream_write(cl->us, buf, len, true);
	else
		ustream_vprintf(cl->us, format, arg);
	ustream_printf(cl->us, "\r\n", len);
}
Exemplo n.º 2
0
static void uh_file_response_ok_hdrs(struct client *cl, struct stat *s)
{
	char buf[128];

	if (s) {
		ustream_printf(cl->us, "ETag: %s\r\n", make_file_etag(s, buf, sizeof(buf)));
		ustream_printf(cl->us, "Last-Modified: %s\r\n",
			       uh_file_unix2date(s->st_mtime, buf, sizeof(buf)));
	}
	ustream_printf(cl->us, "Date: %s\r\n",
		       uh_file_unix2date(time(NULL), buf, sizeof(buf)));
}
Exemplo n.º 3
0
void uh_chunk_write(struct client *cl, const void *data, int len)
{
	bool chunked = uh_use_chunked(cl);

	if (cl->state == CLIENT_STATE_CLEANUP)
		return;

	uloop_timeout_set(&cl->timeout, conf.network_timeout * 1000);
	if (chunked)
		ustream_printf(cl->us, "%X\r\n", len);
	ustream_write(cl->us, data, len, true);
	if (chunked)
		ustream_printf(cl->us, "\r\n", len);
}
Exemplo n.º 4
0
static void proc_handle_header_end(struct relay *r)
{
	struct client *cl = r->cl;
	struct dispatch_proc *p = &cl->dispatch.proc;
	struct blob_attr *cur;
	int rem;

	uloop_timeout_cancel(&p->timeout);
	uh_http_header(cl, cl->dispatch.proc.status_code, cl->dispatch.proc.status_msg);
	blob_for_each_attr(cur, cl->dispatch.proc.hdr.head, rem)
		ustream_printf(cl->us, "%s: %s\r\n", blobmsg_name(cur), blobmsg_data(cur));

	ustream_printf(cl->us, "\r\n");

	if (cl->request.method == UH_HTTP_MSG_HEAD)
		r->skip_data = true;
}
Exemplo n.º 5
0
void uh_chunk_eof(struct client *cl)
{
	if (!uh_use_chunked(cl))
		return;

	if (cl->state == CLIENT_STATE_CLEANUP)
		return;

	ustream_printf(cl->us, "0\r\n\r\n");
}
Exemplo n.º 6
0
static void uh_file_data(struct client *cl, struct path_info *pi, int fd)
{
	/* test preconditions */
	if (!uh_file_if_modified_since(cl, &pi->stat) ||
		!uh_file_if_match(cl, &pi->stat) ||
		!uh_file_if_range(cl, &pi->stat) ||
		!uh_file_if_unmodified_since(cl, &pi->stat) ||
		!uh_file_if_none_match(cl, &pi->stat)) {
		ustream_printf(cl->us, "Content-Length: 0\r\n");
		ustream_printf(cl->us, "\r\n");
		request_done(cl);
		close(fd);
		return;
	}

	/* write status */
	uh_file_response_200(cl, &pi->stat);

	ustream_printf(cl->us, "Content-Type: %s\r\n",
			file_mime_lookup(pi->name));

	ustream_printf(cl->us, "Content-Length: %i\r\n\r\n",
			   pi->stat.st_size);


	/* Stop if this is a header only request */
	if (cl->request.method == UH_HTTP_MSG_HEAD) {
		request_done(cl);
		close(fd);
		return;
	}

	cl->dispatch.file.fd = fd;
	cl->dispatch.write_cb = file_write_cb;
	cl->dispatch.free = uh_file_free;
	cl->dispatch.close_fds = uh_file_free;
	file_write_cb(cl);
}
Exemplo n.º 7
0
static void uh_file_dirlist(struct client *cl, struct path_info *pi)
{
	struct dirent **files = NULL;
	int count = 0;

	uh_file_response_200(cl, NULL);
	ustream_printf(cl->us, "Content-Type: text/html\r\n\r\n");

	uh_chunk_printf(cl,
		"<html><head><title>Index of %s</title></head>"
		"<body><h1>Index of %s</h1><hr /><ol>",
		pi->name, pi->name);

	count = scandir(pi->phys, &files, NULL, dirent_cmp);
	if (count > 0) {
		strcpy(uh_buf, pi->phys);
		list_entries(cl, files, count, pi->name, uh_buf);
	}
	free(files);

	uh_chunk_printf(cl, "</ol><hr /></body></html>");
	request_done(cl);
}
Exemplo n.º 8
0
/**
 * Given a url this functions tries to find the physical path on the server.
 * @cl the client that made the request
 * @url the requested URL
 * @return NULL on error
 */
static struct path_info *path_lookup(struct client *cl, const char *url)
{
	static char path_phys[PATH_MAX];
	static char path_info[PATH_MAX];
	static struct path_info p;

	int docroot_len = strlen(DOCUMENT_ROOT);
	char *pathptr = NULL;
	bool slash;

	int i = 0;
	int len;
	struct stat s;

	/* Return NULL when the URL is undefined */
	if (url == NULL)
		return NULL;

	memset(&p, 0, sizeof(p));
	path_phys[0] = 0;
	path_info[0] = 0;

	/* Start the canonical path with the document root */
	strcpy(uh_buf, DOCUMENT_ROOT);

	/* Separate query string from url */
	if ((pathptr = strchr(url, '?')) != NULL) {
		p.query = pathptr[1] ? pathptr + 1 : NULL;

		/* URL decode component without query */
		if (pathptr > url) {
			if (uh_urldecode(&uh_buf[docroot_len],
					 sizeof(uh_buf) - docroot_len - 1,
					 url, pathptr - url ) < 0)
				return NULL;

		}
	}

	/* Decode the full url when  there is no querystring */
	else if (uh_urldecode(&uh_buf[docroot_len],
			      sizeof(uh_buf) - docroot_len - 1,
			      url, strlen(url) ) < 0)
		return NULL;

	/* Create canonical path */
	len = strlen(uh_buf);
	slash = len && uh_buf[len - 1] == '/';
	len = min(len, sizeof(path_phys) - 1);

	for (i = len; i >= 0; i--) {
		char ch = uh_buf[i];
		bool exists;

		if (ch != 0 && ch != '/')
			continue;

		uh_buf[i] = 0;
		exists = !!canonpath(uh_buf, path_phys);
		uh_buf[i] = ch;

		if (!exists)
			continue;

		/* Test the current path */
		if (stat(path_phys, &p.stat))
			continue;

		snprintf(path_info, sizeof(path_info), "%s", uh_buf + i);
		break;
	}

	/* Check whether found path is within docroot */
	if (strncmp(path_phys, DOCUMENT_ROOT, docroot_len) != 0 ||
	    (path_phys[docroot_len] != 0 &&
	     path_phys[docroot_len] != '/')){
		return NULL;
	}

	/* Check if the found file is a regular file */
	if (p.stat.st_mode & S_IFREG) {
		p.root = DOCUMENT_ROOT;
		p.phys = path_phys;
		p.name = &path_phys[docroot_len];
		p.info = path_info[0] ? path_info : NULL;
		return &p;
	}

	/* Make sure it is not a directory */
	if (!(p.stat.st_mode & S_IFDIR)){
		return NULL;
	}

	if (path_info[0]){
	    return NULL;
	}

	pathptr = path_phys + strlen(path_phys);

	/* ensure trailing slash */
	if (pathptr[-1] != '/') {
		pathptr[0] = '/';
		pathptr[1] = 0;
		pathptr++;
	}

	/* if requested url resolves to a directory and a trailing slash
	   is missing in the request url, redirect the client to the same
	   url with trailing slash appended */
	if (!slash) {
		write_http_header(cl, 302, "Found");
		ustream_printf(cl->us, "Content-Length: 0\r\n");
		ustream_printf(cl->us, "Location: %s%s%s\r\n\r\n",
				&path_phys[docroot_len],
				p.query ? "?" : "",
				p.query ? p.query : "");
		request_done(cl);
		p.redirected = 1;
		return &p;
	}

	/* Check if the folder contains an index file */
	len = path_phys + sizeof(path_phys) - pathptr - 1;
	if(strlen(INDEX_FILE) <= len){

		strcpy(pathptr, INDEX_FILE);
		if (!stat(path_phys, &s) && (s.st_mode & S_IFREG)) {
			memcpy(&p.stat, &s, sizeof(p.stat));
		} else {
			/* Stop when strcpy is not needed */
			*pathptr = 0;
		}
	}

	p.root = DOCUMENT_ROOT;
	p.phys = path_phys;
	p.name = &path_phys[docroot_len];

	return p.phys ? &p : NULL;
}