예제 #1
0
파일: vcl.c 프로젝트: varnish/vagent2
static unsigned int
vcl_push(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;
	char id[ID_LEN];
	int status;

	GET_PRIV(core, vcl);

	assert(STARTS_WITH(request->url, "/vcl"));
	assert(request->method == M_POST || request->method == M_PUT);

	if (request->method == M_POST)
		snprintf(id, sizeof(id), "vcl%ju", (uintmax_t) time(NULL));
	else
		snprintf(id, sizeof(id), "%s", arg);

	if (!strlen(id))
		http_reply(request->connection, 400, "Bad URL?");
	else {
		status = vcl_store(request, vcl, &vret, core, id);
		http_reply(request->connection, status, vret.answer);
		free(vret.answer);
	}
	return (0);
}
예제 #2
0
파일: vcl.c 프로젝트: varnish/vagent2
static unsigned int
vcl_listshow(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;

	GET_PRIV(core, vcl);

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

	if (!arg)
		ipc_run(vcl->vadmin, &vret, "vcl.list");
	else
		ipc_run(vcl->vadmin, &vret, "vcl.show %s", arg);

	if (vret.status == 200)
		http_reply(request->connection, 200, vret.answer);
	else
		http_reply(request->connection, 400, vret.answer);

	free(vret.answer);
	return (0);
}
예제 #3
0
파일: vcl.c 프로젝트: varnish/vagent2
static unsigned int
vcl_deploy(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;
	int ret;

	GET_PRIV(core, vcl);

	assert(STARTS_WITH(request->url, "/vcldeploy"));
	assert(request->method == M_PUT);

	ipc_run(vcl->vadmin, &vret, "vcl.use %s", arg);
	if (vret.status == 200)
		ret = vcl_persist_active(vcl->logger, arg, core);
	if (vret.status == 200 && ret)
		http_reply(request->connection, 500,
		    "Deployed ok, but NOT PERSISTED.");
	else if (vret.status == 200)
		http_reply(request->connection, 200, vret.answer);
	else
		http_reply(request->connection, 500, vret.answer);
	free(vret.answer);
	return (0);
}
예제 #4
0
파일: vstat.c 프로젝트: varnish/vagent2
static unsigned int
vstat_push_test(struct http_request *request, const char *arg, void *data)
{
	struct vstat_priv_t *vstat;
	struct agent_core_t *core = data;

	(void)arg;
	GET_PRIV(core, vstat);
	if (push_stats(vstat, &vstat->http) < 0)
		http_reply(request->connection, 500, "Stats pushing failed");
	else
		http_reply(request->connection, 200, "Stats pushed");
	return 0;
}
예제 #5
0
파일: vcl.c 프로젝트: varnish/vagent2
static unsigned int
vcl_active(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;
	char **tp, *tok[5];
	char *p, *last;
	char *line;

	(void)arg;

	assert(STARTS_WITH(request->url, "/vclactive"));
	assert(request->method == M_GET);
	GET_PRIV(core, vcl);

	/*
	 * 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);
		free(vret.answer);
		return (0);
	}
	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);
}
예제 #6
0
static unsigned int
vbackends_reply(struct http_request *request, void *data)
{
	const char *arg;
	struct agent_core_t *core = data;
	struct agent_plugin_t *plug;
	struct vbackends_priv_t *vbackends;
	char *body;

	plug = plugin_find(core,"vbackends");
	vbackends = plug->data;

	if (!strcmp(request->url, "/backendjson/") &&
	    request->method == M_GET) {
		backends_json(request, vbackends);
		return (1);
	}
	if (request->method == M_PUT) {
		char *mark;
		assert(((char *)request->data)[request->ndata] == '\0');
		body = strdup(request->data);
		mark = strchr(body,'\n');
		if (mark)
			*mark = '\0';
		arg = request->url + strlen("/backend/");
		assert(arg && *arg);
		run_and_respond(vbackends->vadmin, request->connection,
		    "backend.set_health %s %s", arg, body);
		free(body);
		return (1);
	}

	http_reply(request->connection, 500, "Failed");
	return (1);
}
예제 #7
0
파일: vstat.c 프로젝트: varnish/vagent2
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;
}
예제 #8
0
파일: http.c 프로젝트: netdava/tang
int
http_reply(const char *file, int line,
           enum http_status code, const char *fmt, ...)
{
    const char *msg = NULL;
    va_list ap;
    int a;
    int b;

    switch (code) {
#define XX(num, name, string) case num: msg = # string; break;
    HTTP_STATUS_MAP(XX)
#undef XX
    default:
        return http_reply(file, line, HTTP_STATUS_INTERNAL_SERVER_ERROR, NULL);
    }

    fprintf(stderr, " => %d (%s:%d)\n", code, file, line);

    a = dprintf(STDOUT_FILENO, "HTTP/1.1 %d %s\r\n", code, msg);
    if (a < 0)
        return a;

    va_start(ap, fmt);
    b = vdprintf(STDOUT_FILENO, fmt ? fmt : "Content-Length: 0\r\n\r\n", ap);
    va_end(ap);
    return b < 0 ? b : a + b;
}
예제 #9
0
do_cat(char *f, int fd)
{
	char	*extension = file_type(f);
	char	*type = "text/plain";
	FILE	*fpsock, *fpfile;
	int	c;
	int	bytes = 0;

	if ( strcmp(extension,"html") == 0 )
		type = "text/html";
	else if ( strcmp(extension, "gif") == 0 )
		type = "image/gif";
	else if ( strcmp(extension, "jpg") == 0 )
		type = "image/jpeg";
	else if ( strcmp(extension, "jpeg") == 0 )
		type = "image/jpeg";

	fpsock = fdopen(fd, "w");
	fpfile = fopen( f , "r");
	if ( fpsock != NULL && fpfile != NULL )
	{
		bytes = http_reply(fd,&fpsock,200,"OK",type,NULL);
		while( (c = getc(fpfile) ) != EOF ){
			putc(c, fpsock);
			bytes++;
		}
		fclose(fpfile);
		fclose(fpsock);
	}
	server_bytes_sent += bytes;
}
예제 #10
0
파일: vban.c 프로젝트: KristianLyng/vagent2
static unsigned int vban_reply(struct http_request *request, void *data)
{
	struct agent_core_t *core = data;
	struct vban_priv_t *vban;
	char *body;

	GET_PRIV(core, vban);

	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 = strchr(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) {
				http_reply(request->connection, 500, "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;
}
예제 #11
0
파일: ir.c 프로젝트: Netping/DKSF-70
int ir_http_set_data(void)
{
  // format: data=CCNNPPLLLLLL..LL
  //   CC - 1 byte command, 0x01 = start rec, 0x02 = play rec, 0x03 - save record
  //   NN - 1 byte ir command (record) number, 0xff = play captured from buffer (for Save and Play commands)
  //   PP - 1 byte lablel length in bytes (for Save command)
  //   LL - win1251 chars of command label (for Save command)
  struct {
    unsigned char opcode;
    unsigned char rec_n;
    unsigned char label_len;
  } cmd;
  char label[32];
  unsigned postlen;
  if(http.post_content_length - HTTP_POST_HDR_SIZE < (3<<1) ) return 0; // at least 3 hex byte must be posted
  http_post_data_part(req + HTTP_POST_HDR_SIZE, (void*)&cmd, sizeof cmd);
  switch(cmd.opcode)
  {
  case 0x01:
    ir_start_capture();
    http_reply(200,"ok");
    break;
  case 0x02:
    if(cmd.rec_n != 0xff && cmd.rec_n >= IR_COMMANDS_N) break; // validate cmd number
    ir_play_record(cmd.rec_n);
    http_reply(200,"ok");
    break;
  case 0x03:
    if(cmd.rec_n >= IR_COMMANDS_N) break; // validate cmd number
    postlen = (sizeof cmd + cmd.label_len)<<1;
    if(http.post_content_length != HTTP_POST_HDR_SIZE + postlen) break; // check POST data length
    util_fill((void*)label, sizeof label, 0); // LBS 27.02.2012 - it was wrong function args sequence !!!
    if(cmd.label_len > 31) cmd.label_len = 31; // limit label length
    http_post_data_part(req + HTTP_POST_HDR_SIZE + sizeof cmd * 2, label, cmd.label_len); // read label
    ir_save_record(cmd.rec_n, label);
    http_redirect("/ir.html");
    break;
  default:
    http_redirect("/ir.html");
    break;
  }
  return 0;
}
예제 #12
0
파일: vcl.c 프로젝트: varnish/vagent2
static unsigned int
vcl_delete(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;

	GET_PRIV(core, vcl);

	assert(request->method == M_DELETE);
	assert(STARTS_WITH(request->url, "/vcl"));

	ipc_run(vcl->vadmin, &vret, "vcl.discard %s", arg);
	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);
}
예제 #13
0
파일: gw-http.c 프로젝트: Voxar/spot
static int http_complete_login (RESTSESSION * r)
{
	struct buf *response;

	if (r->client->state != CLIENT_STATE_IDLE_CONNECTED)
		return http_reply_need_auth (r);

	response = buf_new ();
	buf_append_data (response, "logged in!\n", 11);

	return http_reply (r, 200, response);
}
예제 #14
0
/*
 * FIXME: Should be simplified/split up.
 */
static unsigned int vparams_reply(struct http_request *request, void *data)
{
	const char *arg;
	struct agent_core_t *core = data;
	struct vparams_priv_t *vparams;
	char *body;

	GET_PRIV(core, vparams);

	if (!strcmp(request->url, "/paramjson/") && request->method == M_GET) {
		param_json(request, vparams);
		return 1;
	}
	if (request->method == M_GET) {
		if (!strcmp(request->url,"/param/")) {
			run_and_respond(vparams->vadmin,
				request->connection,
				"param.show");
			return 1;
		} else {
			arg = request->url + strlen("/param/");
			assert(arg && *arg);
			run_and_respond(vparams->vadmin,
				request->connection,
				"param.show %s", arg);
			return 1;
		}
	} else if (request->method == M_PUT) {
		char *mark;
		assert(((char *)request->data)[request->ndata] == '\0');
		body = strdup(request->data);
		mark = strchr(body,'\n');
		if (mark)
			*mark = '\0';
		if (!strcmp(request->url, "/param/")) {
			run_and_respond(vparams->vadmin,
				request->connection,
				"param.set %s",body);
		} else {
			arg = request->url + strlen("/param/");
			assert(arg && *arg);
			run_and_respond(vparams->vadmin,
				request->connection,
				"param.set %s %s",arg, body);
		}
		free(body);
		return 1;

	}
	http_reply(request->connection, 500, "Failed");
	return 1;
}
예제 #15
0
파일: vcl.c 프로젝트: varnish/vagent2
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);
}
예제 #16
0
/* handle built-in URLs here.  Only one so far is "status" */
built_in(char *arg, int fd)
{
	FILE	*fp;

	if ( strcmp(arg,"status") != 0 )
		return 0;
	http_reply(fd, &fp, 200, "OK", "text/plain",NULL);

	fprintf(fp,"Server started: %s", ctime(&server_started));
	fprintf(fp,"Total requests: %d\n", server_requests);
	fprintf(fp,"Bytes sent out: %d\n", server_bytes_sent);
	fclose(fp);
	return 1;
}
예제 #17
0
파일: vstat.c 프로젝트: varnish/vagent2
static unsigned int
vstat_push_url(struct http_request *request, const char *arg, void *data)
{
	struct vstat_priv_t *vstat;
	struct agent_core_t *core = data;

	(void)arg;
	GET_PRIV(core, vstat);
	pthread_rwlock_wrlock(&vstat->lck);
	if (vstat->push_url)
		free(vstat->push_url);
	DUP_OBJ(vstat->push_url, request->body, request->bodylen);
	logger(vstat->http.logger, "Got url: \"%s\"", vstat->push_url);
	pthread_rwlock_unlock(&vstat->lck);
	http_reply(request->connection, 200, "Url stored");
	return (0);
}
예제 #18
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);
}
예제 #19
0
do_ls(char *dir, int fd)
{
	DIR	      *dirptr;
	struct dirent *direntp;
	FILE	      *fp;
	int	      bytes = 0;

	bytes = http_reply(fd,&fp,200,"OK","text/plain",NULL);
	bytes += fprintf(fp,"Listing of Directory %s\n", dir);

	if ( (dirptr = opendir(dir)) != NULL ){
		while( direntp = readdir(dirptr) ){
			bytes += fprintf(fp, "%s\n", direntp->d_name);
		}
		closedir(dirptr);
	}
	fclose(fp);
	server_bytes_sent += bytes;
}
예제 #20
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);
}
예제 #21
0
파일: io.c 프로젝트: Netping/DKSF-70
unsigned io_http_set_single_pulse(void)
{
  struct {
    unsigned char ch;
    unsigned char duration;
  } data;
  data.duration = 0xaa;
  http_post_data((void*)&data, sizeof data);
  if(data.duration != 0xaa && data.ch < IO_MAX_CHANNEL)
  {
    struct io_setup_s *setup = &io_setup[data.ch];
    if(setup->pulse_dur != data.duration) // save duration
    {
      setup->pulse_dur = data.duration;
      EEPROM_WRITE(&eeprom_io_setup[data.ch].pulse_dur, &setup->pulse_dur, sizeof eeprom_io_setup[0].pulse_dur);
    }
    io_start_pulse(data.ch);
  }
  //// http_redirect("/io.html");
  http_reply(200, ""); // in 48/52/60/201/202 html used XHR, not submit
  return 0;
}
예제 #22
0
void http1_1_handler(int clientDescriptor) {

    std::vector<std::string> lines = get_request_lines(clientDescriptor);

    std::vector<std::string> startString = split(lines[0], ' ');
    if (!check_request(clientDescriptor, lines, startString)) {
        return;
    }
    std::string requestPath = startString[1];

    if (requestPath[0] == '/') {
        requestPath = requestPath.substr(1, requestPath.length() - 1);
    }
    for (size_t i = 1; i < requestPath.length(); ++i) {
        if (requestPath[i] == '.' && requestPath[i - 1] == '.') {
            process_error(clientDescriptor, FORBIDDEN);
            return;
        }
    }
    if (requestPath == "") {
        requestPath += homePageFile;
    }
    std::string mime = define_MIME(requestPath);
    if (mime == "none") {
        requestPath += ".html";
        mime = "text/html";
    }

    std::string fileBuf;

    FILE *file = popen(("python3 " + CGIPath + "cgi.py " + sitePath + requestPath + " " + CGIPath).c_str(), "r");
    while (!feof(file)) {
        fileBuf += fgetc(file);
    }
    fileBuf.pop_back();

    http_reply(clientDescriptor, OK, mime, fileBuf);
    wr_close(clientDescriptor);
}
예제 #23
0
void http1_1_handler(int clientDescriptor) {

    std::vector<std::string> lines = get_request_lines(clientDescriptor);

    std::vector<std::string> startString = split(lines[0], ' ');
    if (!check_request(clientDescriptor, lines, startString)) {
        return;
    }
    std::string requestPath = startString[1];

    if (requestPath[0] == '/') {
        requestPath = requestPath.substr(1, requestPath.length() - 1);
    }
    for (size_t i = 1; i < requestPath.length(); ++i) {
        if (requestPath[i] == '.' && requestPath[i - 1] == '.') {
            process_error(clientDescriptor, FORBIDDEN);
            return;
        }
    }
    if (requestPath == "") {
        requestPath += homePageFile;
    }
    std::string mime = define_MIME(requestPath);
    if (mime == "none") {
        requestPath += ".html";
        mime = "text/html";
    }

    std::string fileBuf;

    if (get_file(sitePath + requestPath, fileBuf) == -1) {
        process_error(clientDescriptor, NOT_FOUND);
        return;
    }

    http_reply(clientDescriptor, OK, mime, fileBuf);
    wr_close(clientDescriptor);
}
예제 #24
0
파일: http.c 프로젝트: biddyweb/vagent2
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 http_request request;
	struct connection_info_struct *con_info;

	(void)version;

	GET_PRIV(core, http);

	if (*con_cls == NULL) {
		ALLOC_OBJ(con_info);
		*con_cls = con_info;
		return (MHD_YES);
	}
	con_info = *con_cls;
	assert(core->config->userpass);

	log_request(connection, http, method, url);

	if (!strcmp(method, "OPTIONS")) {
		/* We need this for preflight requests (CORS). */
		return (http_reply(connection, 200, NULL));
	} else if (!strcmp(method, "GET") || !strcmp(method, "HEAD") ||
	    !strcmp(method, "DELETE")) {
		if (check_auth(connection, core, con_info))
			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);
	} else 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 ((char *)con_info->answerstring != NULL) {
			if (check_auth(connection, core, con_info))
				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 (http_reply(connection, 200, http->help_page));
	}

	return (http_reply(connection, 500, "Failed"));
}
예제 #25
0
파일: http.c 프로젝트: netdava/tang
static int
on_message_complete(http_parser *parser)
{
    struct http_state *state = parser->data;
    const char *addr = NULL;
    bool pathmatch = false;
    bool methmatch = false;
    int r = 0;

    if (state->req.status != 0)
        goto error;

    addr = getenv("REMOTE_ADDR");
    fprintf(stderr, "%s %s %s",
            addr ? addr : "<unknown>",
            METHOD_NAMES[parser->method],
            state->req.path);

    for (size_t i = 0; state->dispatch[i].re && r == 0; i++) {
        const struct http_dispatch *d = &state->dispatch[i];
        regmatch_t match[d->nmatches];
        regex_t re = {};

        memset(match, 0, sizeof(match));

        r = regcomp(&re, d->re, REG_EXTENDED) == 0 ? 0 : -EINVAL;
        if (r != 0) {
            state->req.status = HTTP_STATUS_INTERNAL_SERVER_ERROR;
            goto error;
        }

        if (regexec(&re, state->req.path, d->nmatches, match, 0) == 0) {
            pathmatch = true;

            if (((1 << parser->method) & d->methods) != 0) {
                methmatch = true;

                r = d->func(parser->method, state->req.path,
                            state->req.body, match, state->misc);
            }
        }

        regfree(&re);
    }

    if (r > 0)
        goto egress;

    if (r == 0) {
        if (!pathmatch)
            state->req.status = HTTP_STATUS_NOT_FOUND;
        else if (!methmatch)
            state->req.status = HTTP_STATUS_METHOD_NOT_ALLOWED;
        else
            state->req.status = HTTP_STATUS_INTERNAL_SERVER_ERROR;
    } else {
        state->req.status = HTTP_STATUS_INTERNAL_SERVER_ERROR;
    }

error:
    http_reply(__FILE__, __LINE__, state->req.status, NULL);

egress:
    memset(&state->req, 0, sizeof(state->req));
    return 0;
}
예제 #26
0
파일: vcl.c 프로젝트: 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;
}
예제 #27
0
파일: gw-http.c 프로젝트: Voxar/spot
int http_handle_request (RESTSESSION * r)
{
	struct buf *b;
	char buf[512];
	char *p;
	SPOTIFYSESSION *client;

	/*
	 * r->httpreq->url has path that was requested
	 * r->httpreq->authheader MIGHT be non-NULL and 
	 * have username:password in base64
	 *
	 */

	/* Default to process next command */
	r->state = REST_STATE_LOAD_COMMAND;

	if ((client = spotify_find_http_client ()) == NULL) {
		/* Force auth if not sent or likely invalid */
		if (!r->httpreq->authheader
				|| strlen (r->httpreq->authheader) > 100)
			return http_reply_need_auth (r);

		memset (buf, 0, sizeof (buf));
		b64decode (r->httpreq->authheader, buf);
		if ((p = strchr (buf, ':')) == NULL) {
			printf ("b64 decode failed '%s'\n", buf);
			return http_reply_need_auth (r);
		}

		*p++ = 0;
		strcpy (r->username, buf);
		strcpy (r->password, p);
		spotify_client_allocate (r);
		spotify_client_mark_for_http (r->client);
		if (r->client->state == CLIENT_STATE_IDLE_CONNECTED)
			return http_complete_login (r);

		r->state = REST_STATE_WAITING;
		r->httpreq->callback = http_complete_login;
		return 0;
	}

	if (0) {

	}
	else {
		b = buf_new ();
		sprintf (buf,
			 "You're logged in as '%s' with password '%s'<br />\n",
			 r->username, r->password);
		if (client)
			buf_append_data(b, buf, strlen (buf));
		sprintf (buf, "The requested URL '%s' was not found!\n",
			 r->httpreq->url);
		buf_append_data(b, buf, strlen (buf));
		return http_reply (r, 404, b);
	}

	return 0;
}
예제 #28
0
END_TEST

#if HAVE_EVHTTP_H
START_TEST(test_http) {
    struct parent_msg msg = {};
    const char *errstr = NULL;
    extern char *http_host, *http_path;
    static struct event_base *base;
    struct evhttp *httpd;
    extern struct evhttp_request *lreq;
    extern struct evhttp_connection *evcon;
    extern int status;
    extern short http_port;
    int sock = -1;

    // check for ipv4 before running the test
    mark_point();
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	return;
    else
	close(sock);

    // this assumes libevent can connect to localhost
    // sounds silly, but I've seen it fail...
    http_host = "127.0.0.1";
    http_path = "/cgi-bin/test.cgi";
    event_set_log_callback(&fake_log_cb);

    mark_point();
    base = event_init();
    httpd = evhttp_new(base);
    for (http_port = 8080; http_port < 8090; http_port++) {
        if (evhttp_bind_socket(httpd, http_host, http_port) != -1)
	    break;
    }
    fail_unless (http_port < 8090, "failed to start httpd on %s", http_host);

    // If either of these two fail then we're screwed anyway
    mark_point();
    http_connect();

    mark_point();
    http_request(&msg, 0);

    mark_point();
    strlcpy(msg.name, "eth0", IFNAMSIZ);
    msg.proto = PROTO_CDP;
    msg.decode = (1 << PEER_HOSTNAME)|(1 << PEER_PORTNAME);
    msg.peer[PEER_HOSTNAME] = strdup("router");
    msg.peer[PEER_PORTNAME] = strdup("Fas'tEthernet42/64");
    http_request(&msg, 0);

    mark_point();
    errstr = "HTTP request failed";
    my_log(CRIT, "check");
    WRAP_FATAL_START();
    http_reply(lreq, NULL);
    WRAP_FATAL_END();
    fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
	"incorrect message logged: %s", check_wrap_errstr);

    mark_point();
    lreq->response_code = 200;
    http_reply(lreq, NULL);
    fail_unless (status == EXIT_SUCCESS,
	"incorrect exit status returned: %d", status);

    mark_point();
    lreq->response_code = 404;
    errstr = "HTTP error 404 received";
    my_log(CRIT, "check");
    http_reply(lreq, NULL);
    fail_unless (strncmp(check_wrap_errstr, errstr, strlen(errstr)) == 0,
	"incorrect message logged: %s", check_wrap_errstr);
    fail_unless (status == EXIT_FAILURE,
	"incorrect exit status returned: %d", status);

    mark_point();
    evhttp_connection_free(evcon);
    lreq = NULL;


    mark_point();
    errstr = "failed";
    my_log(CRIT, "check");
    evcon = evhttp_connection_new("256.256.256.256", 0);
    WRAP_FATAL_START();
    http_request(&msg, 0);
    WRAP_FATAL_END();
    fail_unless (strstr(check_wrap_errstr, errstr) != NULL,
	"incorrect message logged: %s", check_wrap_errstr);
    evhttp_connection_free(evcon);

    mark_point();
    errstr = "failed";
    my_log(CRIT, "check");
    evcon = evhttp_connection_new("localhost", 0);
    WRAP_FATAL_START();
    http_request(&msg, 0);
    http_dispatch();
    WRAP_FATAL_END();
    fail_unless (strstr(check_wrap_errstr, errstr) != NULL,
	"incorrect message logged: %s", check_wrap_errstr);

    mark_point();
    // free the active connection
    evhttp_connection_free(evcon);
    lreq = NULL;
    evcon = evhttp_connection_new(http_host, 80);
    http_dispatch();

    evhttp_free(httpd);
    event_base_free(base);
    peer_free(msg.peer);
}
예제 #29
0
void process_error(int clientDescriptor, HttpResponse error) {
    std::string buf;
    get_file(std::to_string(error) + ".html", buf);
    http_reply(clientDescriptor, error, "text/html", buf);
    wr_close(clientDescriptor);
}
예제 #30
0
파일: vlog.c 프로젝트: KristianLyng/vagent2
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);
}