Пример #1
0
static unsigned int html_reply(struct http_request *request, void *data)
{
	int ret, fd=-1;
	char *path = NULL;
	char *buffer = NULL;
	struct stat sbuf;
	struct agent_core_t *core = data;
	struct http_response *resp;
	struct html_priv_t *html;
	GET_PRIV(data, html);
	const char *url_stub = (strlen(request->url) > strlen("/html/")) ? request->url + strlen("/html/") : "index.html";
	if (url_stub[0] == '/' || strstr(url_stub,"/../") || !strncmp(url_stub,"../",strlen("../"))) {
		send_response_fail(request->connection, "Invalid URL");
		return 0;
	}
	ret = asprintf(&path, "%s/%s", core->config->H_arg, url_stub);
	assert(ret>0);
	ret = stat(path, &sbuf);
	if (ret < 0) {
		warnlog(html->logger, "Stat failed for %s. Errnno %d: %s.", path,errno,strerror(errno));
		send_response_fail(request->connection, "stat() was not happy");
		goto out;
	}
	fd = open(path, O_RDONLY);
	if (fd < 0) {
		warnlog(html->logger, "open() failed for %s: %s", path, strerror(errno));
		send_response_fail(request->connection, "open() was not happy");
		goto out;
	}
	if (!S_ISREG(sbuf.st_mode)) {
		warnlog(html->logger, "%s isn't a regular file.", path);
		send_response_fail(request->connection, "not a file");
		goto out;
	}
	buffer = malloc(sbuf.st_size);
	assert(buffer);
	ret = read(fd, buffer, sbuf.st_size);
	assert(ret>0);
	assert(ret==sbuf.st_size);
	resp = http_mkresp(request->connection, 200, NULL);
	resp->data = buffer;
	resp->ndata = ret;
	send_response2(resp);
	http_free_resp(resp);
	out:
	if (fd >= 0)
		close(fd);
	if (buffer)
		free(buffer);
	if (path)
		free(path);
	return 0;
}
Пример #2
0
static unsigned int vban_reply(struct http_request *request, void *data)
{
	struct vban_priv_t *vban;
	struct agent_plugin_t *plug;
	char *body;
	plug = plugin_find(data,"vban");
	vban = plug->data;

	if (request->method == M_GET) {
		run_and_respond(vban->vadmin, request->connection, "ban.list");
		return 0;
	} else {
		char *mark;
		assert(((char *)request->data)[request->ndata] == '\0');
		body = strdup(request->data);
		mark = index(body,'\n');
		if (mark)
			*mark = '\0';
		if (strlen(request->url) == strlen("/ban"))
			run_and_respond(vban->vadmin, request->connection, "ban %s",body);
		else {
			const char *path = request->url + strlen("/ban");
			if (request->ndata != 0) {
				send_response_fail(request->connection, "Banning with both a url and request body? Pick one or the other please.");
			} else {
				assert(request->ndata == 0);
				run_and_respond(vban->vadmin, request->connection, "ban " BAN_SHORTHAND "%s",path);
			}
		}
		free(body);
		return 0;
	}

	return 0;
}
Пример #3
0
/*
 * Run a varnishadm-command and send the result of that command back to the
 * http connection. If varnishd returns 200, then so do we. Otherwise: 500.
 */
void run_and_respond(int vadmin, struct MHD_Connection *conn, const char *fmt, ...)
{
	struct ipc_ret_t vret;
	va_list ap;
	char *buffer;
	int iret;

	va_start(ap, fmt);
	iret = vasprintf(&buffer, fmt, ap);
	assert(iret>0);
	va_end(ap);
	ipc_run(vadmin, &vret, "%s", buffer);
	free(buffer);

	if (vret.status == 200)
		send_response_ok(conn, vret.answer);
	else
		send_response_fail(conn, vret.answer);
	free(vret.answer);
}
Пример #4
0
static int answer_to_connection (void *cls, struct MHD_Connection *connection,
                      const char *url, const char *method,
                      const char *version, const char *upload_data,
                      size_t *upload_data_size, void **con_cls)
{
	struct agent_core_t *core = (struct agent_core_t *)cls;
	struct http_priv_t *http;
	struct agent_plugin_t *plug;
	struct http_request request;
	struct connection_info_struct *con_info = NULL;
	int ret;

	(void)version;
	plug = plugin_find(core,"http");
	http = (struct http_priv_t *) plug->data;
	assert(plug);
	assert(http);


	if (NULL == *con_cls) {
		con_info = malloc (sizeof (struct connection_info_struct));
		assert(con_info);
		con_info->answerstring[0] = '\0';
		con_info->progress = 0;
		con_info->authed = 0;
		*con_cls = con_info;
		return MHD_YES;
	}
	con_info = *con_cls;
	assert(core->config->userpass);

	log_request(connection, http, method, url);

	if (0 == strcmp (method, "GET") || !strcmp(method, "HEAD") || !strcmp(method,"DELETE")) {
		ret = check_auth(connection, core, con_info);
		if (ret == 1)
			return MHD_YES;
		if (!strcmp(method,"DELETE")) {
			request.method = M_DELETE;
		} else {
			request.method = M_GET;
		}
		request.connection = connection;
		request.url = url;
		request.ndata = 0;
		if (find_listener(&request, http))
			return MHD_YES;
	}


	if (!strcmp(method, "POST") || !strcmp(method, "PUT")) {

		if (*upload_data_size != 0) {
			if (*upload_data_size + con_info->progress >= RCV_BUFFER) {
				warnlog(http->logger, "Client input exceeded buffer size of %u bytes. Dropping client.", RCV_BUFFER);

				 return MHD_NO;
			}
			memcpy(con_info->answerstring + con_info->progress,
				upload_data, *upload_data_size);
			con_info->progress += *upload_data_size;
			*upload_data_size = 0;

			return MHD_YES;
		} else if (NULL != con_info->answerstring){
			ret = check_auth(connection, core, con_info);
			if (ret == 1)
				return MHD_YES;
			if (!strcmp(method,"POST")) {
				request.method = M_POST;
			} else {
				request.method = M_PUT;
			}
			request.connection = connection;
			request.url = url;
			request.ndata = con_info->progress;
			request.data = con_info->answerstring;
			/*
			 * FIXME
			 */
			((char *)request.data)[con_info->progress] = '\0';
			if (find_listener(&request, http))
				return MHD_YES;
		}
	}
	if (request.method == M_GET && !strcmp(url, "/")) {
		if (http->help_page == NULL)
			http->help_page = make_help(http);
		assert (http->help_page);
		return send_response_ok(connection, http->help_page);
	}


	return send_response_fail (connection, "Failed\n");
}
Пример #5
0
static unsigned int vlog_reply(struct httpd_request *request, void *data)
{
	struct vlog_priv_t *vlog;
	int ret;
	char *limit = NULL;
	char *p;
	char *tag = NULL;
	char *itag = NULL;
	struct agent_core_t *core = data;
	GET_PRIV(data,vlog);
	p = next_slash(request->url + 1);

	assert(vlog->tag==NULL);
	assert(vlog->answer == NULL);

	if (p) {
		limit = strdup(p);
		assert(limit);
		char *tmp2 = index(limit,'/');
		if (tmp2 && *tmp2) *tmp2 = '\0';

		if(!(atoi(limit) > 0)) {
			free(limit);
			send_response_fail(request->connection,"Not a number");
			return 0;
		}
		p = next_slash(p);
	}
	if (p) {
		tag = strdup(p);
		char *tmp2 = index(tag,'/');
		if (tmp2 && *tmp2) *tmp2 = '\0';
		p = next_slash(p);
	}
	if (p) {
		itag = strdup(p);
		char *tmp2 = index(itag,'/');
		if (tmp2 && *tmp2) *tmp2 = '\0';
		p = next_slash(p);
	}
	vlog->answer = VSB_new_auto();
	assert(vlog->answer != NULL);
	vlog->vd = VSM_New();
	assert(VSL_Arg(vlog->vd, 'n', core->config->n_arg));
	VSL_Setup(vlog->vd);
	VSL_Arg(vlog->vd, 'd', "");
	if (tag) {
		VSL_Arg(vlog->vd, 'i', tag);
		if (itag)
			VSL_Arg(vlog->vd,'I',itag);
	} else {
		VSL_Arg(vlog->vd, 'k', limit ? limit : "10");
	}

	if (limit)
		free(limit);
	VSB_printf(vlog->answer, "{ \"log\": [");
	ret = VSL_Open(vlog->vd, 1);
	assert(!ret);

	if (tag == NULL) {
		do_order(vlog);
	} else {
		do_unorder(vlog);
	}
	if (tag)
		free(tag);
	if (itag)
		free(itag);

	VSB_printf(vlog->answer, "\n] }\n");
	assert(VSB_finish(vlog->answer) == 0);
	if (VSB_len(vlog->answer) > 1) {
		send_response(request->connection, 200, VSB_data(vlog->answer), VSB_len(vlog->answer));
	} else {
		send_response_fail(request->connection, "FAIL");
	}
	VSB_clear(vlog->answer);
	VSM_Close(vlog->vd);
	vlog->answer = NULL;
	vlog->entries = 0;
	return 0;
}