Example #1
0
static unsigned int
vstat_reply(struct http_request *request, const char *arg, void *data)
{
	struct vstat_priv_t *vstat;
	struct agent_core_t *core = data;
	struct http_response *resp;

	(void)arg;
	GET_PRIV(core, vstat);

	if (check_reopen(&vstat->http)) {
		http_reply(request->connection, 500, "Couldn't open shmlog");
		return 0;
	}

	do_json(vstat->http.vd, vstat->http.vsb);

	resp = http_mkresp(request->connection, 200, NULL);
	resp->data = VSB_data(vstat->http.vsb);
	resp->ndata = VSB_len(vstat->http.vsb);
	http_add_header(resp,"Content-Type","application/json");
	send_response(resp);
	http_free_resp(resp);
	VSB_clear(vstat->http.vsb);
	return 0;
}
Example #2
0
File: http.c Project: Dridi/vagent2
static int send_response(struct MHD_Connection *connection, int status, const char *data, unsigned int ndata)
{
	struct http_response *resp = http_mkresp(connection, status, NULL);
	int ret;
	resp->data = data;
	resp->ndata = ndata;
	ret = send_response2(resp);
	http_free_resp(resp);
	return ret;
}
Example #3
0
File: http.c Project: Dridi/vagent2
static int send_auth_response(struct MHD_Connection *connection)
{
	struct http_response *resp = http_mkresp(connection, 401, "Authorize, please.\n\n" \
	    "If Varnish Agent was installed from packages, the /etc/varnish/agent_secret " \
	    "file contains generated credentials.");
	http_add_header(resp, "WWW-Authenticate", "Basic realm=varnish-agent");
	send_response2(resp);
	http_free_resp(resp);
	return 1;
}
Example #4
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;
}
Example #5
0
File: echo.c Project: Dridi/vagent2
static unsigned int echo_reply(struct http_request *request, void *data)
{
	struct echo_priv_t *echo = data;
	struct http_response *resp = http_mkresp(request->connection, 200, NULL);
	resp->data = request->data;
	resp->ndata = request->ndata;
	if (request->method == M_PUT || request->method == M_POST) {
		if (((char *)request->data)[request->ndata] == '\0' && strlen((char *)request->data) == request->ndata)
			debuglog(echo->logger, "Data being printed: \n%s", (char *)request->data);
	}
	logger(echo->logger, "Responding to request");
	send_response2(resp);
	http_free_resp(resp);
	return 0;
}
Example #6
0
static void param_json(struct http_request *request, struct vparams_priv_t *vparams)
{
	struct ipc_ret_t vret;
	char *tmp;
	ipc_run(vparams->vadmin, &vret, "param.show -l");
	if (vret.status == 200) {
		tmp = vparams_show_json(vret.answer);
		struct http_response *resp = http_mkresp(request->connection, 200, tmp);
		http_add_header(resp,"Content-Type","application/json");
		send_response(resp);
		free(tmp);
		http_free_resp(resp);
	} else {
		http_reply(request->connection, 500, vret.answer);
	}
	free(vret.answer);
}
Example #7
0
static void backends_json(struct http_request *request,
    struct vbackends_priv_t *vbackends)
{
	struct vsb *json;
	struct ipc_ret_t vret;
	ipc_run(vbackends->vadmin, &vret, "backend.list");
	if (vret.status == 200) {
		json = VSB_new_auto();
		assert(json);
		vbackends_show_json(json, vret.answer);
		AZ(VSB_finish(json));
		struct http_response *resp = http_mkresp(request->connection,
		    200, VSB_data(json));
		http_add_header(resp,"Content-Type","application/json");
		send_response(resp);
		VSB_delete(json);
		http_free_resp(resp);
	} else
		http_reply(request->connection, 500, vret.answer);
	free(vret.answer);
}
Example #8
0
static unsigned int
vcl_json(struct http_request *request, const char *arg, void *data)
{
	struct agent_core_t *core = data;
	struct vcl_priv_t *vcl;
	struct ipc_ret_t vret;
	struct vsb *json;
	struct http_response *resp;

	GET_PRIV(core, vcl);

	assert(STARTS_WITH(request->url, "/vcljson"));
	assert(request->method == M_GET);

	if (arg) {
		http_reply(request->connection, 404,
		    "/vcljson takes no argument");
		return (0);
	}

	ipc_run(vcl->vadmin, &vret, "vcl.list");
	if (vret.status == 400)
		http_reply(request->connection, 500, vret.answer);
	else {
		json = vcl_list_json(vret.answer);
		assert(VSB_finish(json) == 0);
		resp = http_mkresp(request->connection, 200, NULL);
		resp->data = VSB_data(json);
		resp->ndata = VSB_len(json);
		http_add_header(resp, "Content-Type", "application/json");
		send_response(resp);
		http_free_resp(resp);
		VSB_clear(json);
		VSB_delete(json);
	}
	free(vret.answer);
	return (0);
}
Example #9
0
static unsigned int vlog_reply(struct http_request *request, void *data)
{
	struct vlog_req_priv vrp = { .limit = 10 };
	int disp_status;
	char *p;
	char *tag = NULL;
	char *tag_re = NULL;
	struct VSL_data *vsl = NULL;
	struct VSLQ *vslq = NULL;
	struct VSL_cursor *c = NULL;
	enum VSL_grouping_e grouping = VSL_g_request;
	struct agent_core_t *core = data;

	p = next_slash(request->url + 1);
	if (p) {
		char *lim = strdup(p);
		assert(lim);
		char *tmp2 = strchr(lim, '/');
		if (tmp2 && *tmp2) *tmp2 = '\0';

		int j = sscanf(lim, "%u", &vrp.limit);
		if(j != 1) {
			free(lim);
			http_reply(request->connection, 500, "Not a number");
			return 0;
		}

		free(lim);
		p = next_slash(p);
	}

	if (p) {
		tag = strdup(p);
		char *tmp2 = strchr(tag,'/');
		if (tmp2 && *tmp2) *tmp2 = '\0';
		p = next_slash(p);
	}

	if (p) {
		tag_re = strdup(p);
		char *tmp2 = strchr(tag_re, '/');
		if (tmp2 && *tmp2) *tmp2 = '\0';
		p = next_slash(p);
	}
	
	vrp.answer = VSB_new_auto();
	assert(vrp.answer != NULL);

	vrp.vsm = VSM_New();
	assert(vrp.vsm);
	if (!VSM_n_Arg(vrp.vsm, core->config->n_arg)) {
		VSB_printf(vrp.answer, "Error in creating shmlog: %s",
		    VSM_Error(vrp.vsm));
		VSB_finish(vrp.answer);
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}

	if (VSM_Open(vrp.vsm) != 0) {
		VSB_printf(vrp.answer, "Error in opening shmlog: %s",
		    VSM_Error(vrp.vsm));
		VSB_finish(vrp.answer);
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}
	
	vsl = VSL_New();
	assert(vsl);

	if (tag) {
		grouping = VSL_g_raw;
		
		if (VSL_Arg(vsl, 'i', tag) < 0) {
			VSB_printf(vrp.answer, "Unable to specify tag '%s': %s",
			    tag, VSL_Error(vsl));
			VSB_finish(vrp.answer);
			http_reply(request->connection, 500, VSB_data(vrp.answer));
			goto cleanup;
		}
		if (tag_re) {
			VSL_Arg(vsl,'I', tag_re);
		}
	}

	c = VSL_CursorVSM(vsl, vrp.vsm,
	    VSL_COPT_BATCH | VSL_COPT_TAILSTOP);
	if (c == NULL) {
		VSB_printf(vrp.answer, "Can't open log (%s)",
		    VSL_Error(vsl));
		VSB_finish(vrp.answer);
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}

	
	vslq = VSLQ_New(vsl, &c, grouping, NULL);
	if (vslq == NULL) {
		VSB_clear(vrp.answer);
		VSB_printf(vrp.answer, "Error in creating query: %s",
		    VSL_Error(vsl));
		http_reply(request->connection, 500, VSB_data(vrp.answer));
		goto cleanup;
	}

	VSB_printf(vrp.answer, "{ \"log\": [");

	do {
		disp_status = VSLQ_Dispatch(vslq, vlog_cb_func, &vrp);
	} while (disp_status == 1 && vrp.entries < vrp.limit);

	VSB_printf(vrp.answer, "\n] }\n");

	assert(VSB_finish(vrp.answer) == 0);
	if (VSB_len(vrp.answer) > 1) {
		struct http_response *resp = http_mkresp(request->connection, 200, NULL);
		resp->data = VSB_data(vrp.answer);
		resp->ndata = VSB_len(vrp.answer);
		http_add_header(resp,"Content-Type","application/json");
		send_response(resp);
		http_free_resp(resp);
	} else {
		http_reply(request->connection, 500, "FAIL");
	}

 cleanup:
	free(tag);
	free(tag_re);
	VSB_delete(vrp.answer);
	if (vslq)
		VSLQ_Delete(&vslq);
	if (vsl)
		VSL_Delete(vsl);
	if (vrp.vsm)
		VSM_Delete(vrp.vsm);
	vrp.answer = NULL;
	return 0;
}

void vlog_init(struct agent_core_t *core)
{
	struct agent_plugin_t *plug;
	struct vlog_priv_t *priv;

	ALLOC_OBJ(priv);
	plug = plugin_find(core,"vlog");
	plug->data = priv;

	http_register_url(core, "/log", M_GET, vlog_reply, core);
}
Example #10
0
File: vcl.c Project: aondio/vagent2
static unsigned int
vcl_reply(struct http_request *request, void *data)
{
	struct agent_core_t *core = data;
	struct vcl_priv_t *vcl;
	struct http_response *resp;
	struct ipc_ret_t vret;
	char id[ID_LEN + 1];
	int ret;
	int status;

	GET_PRIV(core, vcl);

	if (request->method == M_GET) {
		if (!strcmp(request->url, "/vclactive") || !strcmp(request->url,"/vclactive/")) {
			/*
			 * vcl.list output:
			 *
			 * V3/4 : (active|available|discarded) (refcnt) (name)
			 * V4.1 : (active|available|discarded) (state) \
			 *            (busycnt|) (name)
			 */
			ipc_run(vcl->vadmin,&vret,"vcl.list");
			if (vret.status == 400) {
				http_reply(request->connection, 500, vret.answer);
			} else {
				char **tp, *tok[5];
				char *p, *last;
				char *line;

				memset(tok, '\0', sizeof(tok));
				for (p = vret.answer, last = NULL;
				    (line = strtok_r(p, "\n", &last));
				    p = NULL) {
					if (strncmp("active", line, 6))
						continue;
					last = NULL;
					for (p = line, tp = tok;
					    tp < &tok[4] &&
					    (*tp = strtok_r(p, " ", &last));
					    p = NULL) {
						if (**tp != '\0')
							tp++;
                                        }
				}
				if (!tok[2] || !tok[3]) {
					http_reply(request->connection,
					    500, "No active VCL");
				} else {
					strcpy(vret.answer,
					    tok[3] ? tok[3] : tok[2]);
					http_reply(request->connection,
					    200, vret.answer);
				}
			}
			free(vret.answer);
			return 0;
		} else if (!strcmp(request->url, "/vcl") || !strcmp(request->url,"/vcl/")) {
			ipc_run(vcl->vadmin, &vret, "vcl.list");
			if (vret.status == 400) {
				http_reply(request->connection, 500, vret.answer);
			} else {
				http_reply(request->connection, 200, vret.answer);
			}
			free(vret.answer);
			return 0;
		} else if (!strncmp(request->url,"/vcl/",strlen("/vcl/"))) {
			ipc_run(vcl->vadmin, &vret, "vcl.show %s", request->url + strlen("/vcl/"));
			if (vret.status == 400) {
				http_reply(request->connection, 500, vret.answer);
			} else {
				http_reply(request->connection, 200, vret.answer);
			}
			free(vret.answer);
			return 0;
		} else if(!strcmp(request->url, "/vcljson/")) {
			struct vsb *json;
			ipc_run(vcl->vadmin, &vret, "vcl.list");
			if (vret.status == 400) {
				http_reply(request->connection, 500, vret.answer);
			} else {
				json = vcl_list_json(vret.answer);
				assert(VSB_finish(json) == 0);
				resp = http_mkresp(request->connection, 200, NULL);
				resp->data = VSB_data(json);
				resp->ndata = VSB_len(json);
				http_add_header(resp, "Content-Type", "application/json");
				send_response(resp);
				http_free_resp(resp);
				VSB_clear(json);
				VSB_delete(json);
			}
			free(vret.answer);
			return 0;
		} else {
			http_reply(request->connection, 500, "Invalid VCL-url.");
			return 0;
		}
	} else if (request->method == M_POST) {
		snprintf(id, sizeof(id), "%ju", (uintmax_t) time(NULL));
		status = vcl_store(request, vcl, &vret, core, id);
		http_reply(request->connection, status, vret.answer);
		free(vret.answer);
		return 0;
	} else if (request->method == M_PUT) {
		if (!strncmp(request->url,"/vcl/",strlen("/vcl/"))) {
			if (strlen(request->url) >= 6) {
				status = vcl_store(request, vcl, &vret, core,
				                   request->url + strlen("/vcl/"));
				http_reply(request->connection, status, vret.answer);
				free(vret.answer);
				return 0;
			} else {
				http_reply(request->connection, 400, "Bad URL?");
				return 0;
			}
		} else if (!strncmp(request->url, "/vcldeploy/",strlen("/vcldeploy/"))) {
			ipc_run(vcl->vadmin, &vret, "vcl.use %s",
				request->url + strlen("/vcldeploy/"));
			if (vret.status == 200) {
				ret = vcl_persist_active(vcl->logger, request->url + strlen("/vcldeploy/"), core);
			}
			if (vret.status == 200 && ret)
				http_reply(request->connection, 500, "Deployed ok, but NOT PERSISTED.");
			else if (vret.status == 200 && ret == 0)
				http_reply(request->connection, 200, vret.answer);
			else
				http_reply(request->connection, 500, vret.answer);
			free(vret.answer);
			return 0;
		}
	} else if (request->method == M_DELETE) {
		if (!strncmp(request->url, "/vcl/", strlen("/vcl/"))) {
			ipc_run(vcl->vadmin, &vret, "vcl.discard %s",
				request->url + strlen("/vcl/"));
			if (vret.status == 400 || vret.status == 106) {
				http_reply(request->connection, 500, vret.answer);
			} else {
				http_reply(request->connection, 200, vret.answer);
			}
			free(vret.answer);
			return 0;
		}
	} else {
		return http_reply(request->connection, 500, "Unknown request?");
	}
	assert("Shouldn't get here" == NULL);
	return 0;
}
Example #11
0
File: vlog.c Project: agiza/vagent2
static unsigned int vlog_reply(struct http_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);
	if (ret) {
		send_response_fail(request->connection, "Error in opening shmlog");
		goto cleanup;
	}

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

	VSB_printf(vlog->answer, "\n] }\n");
	assert(VSB_finish(vlog->answer) == 0);
	if (VSB_len(vlog->answer) > 1) {
		struct http_response *resp = http_mkresp(request->connection, 200, NULL);
		resp->data = VSB_data(vlog->answer);
		resp->ndata = VSB_len(vlog->answer);
		http_add_header(resp,"Content-Type","application/json");
		send_response2(resp);
		http_free_resp(resp);
	} else {
		send_response_fail(request->connection, "FAIL");
	}

 cleanup:
	free(tag);
	free(itag);
	VSB_clear(vlog->answer);
	VSB_delete(vlog->answer);
	VSM_Delete(vlog->vd);
	vlog->answer = NULL;
	vlog->entries = 0;
	return 0;
}