Example #1
0
static int httpd_wait_cgi_child(pid_t target, int opts) {
	pid_t child;

	do {
		child = waitpid(target, NULL, opts);
	} while (child == -1 && errno == EINTR);

	if (child == -1) {
		int err = errno;
		httpd_error("waitpid() : %s", strerror(err));
		return -err;
	}

	return child;
}
Example #2
0
static void httpd_client_process(struct client_info *cinfo) {
	struct http_req hreq;
	int err;
	char httpd_inbuf[BUFF_SZ];
	char httpd_outbuf[BUFF_SZ];

	if (0 > (err = httpd_build_request(cinfo, &hreq, httpd_inbuf, sizeof(httpd_inbuf)))) {
		httpd_error("can't build request: %s", strerror(-err));
	}

	httpd_debug("method=%s uri_target=%s uri_query=%s",
			hreq.method, hreq.uri.target, hreq.uri.query);

	if (httpd_try_respond_file(cinfo, &hreq,
				httpd_outbuf, sizeof(httpd_outbuf))) {
		/* file sent, nothing to do */
	} else {
		httpd_header(cinfo, 404, "");
	}
}
Example #3
0
static void httpd_client_process(struct client_info *cinfo) {
	struct http_req hreq;
	pid_t cgi_child;
	int err;

	if ((err = httpd_build_request(cinfo, &hreq, httpd_g_inbuf, sizeof(httpd_g_inbuf)))) {
		httpd_error("can't build request: %s", strerror(-err));
	}

	httpd_debug("method=%s uri_target=%s uri_query=%s",
			   hreq.method, hreq.uri.target, hreq.uri.query);

	if ((cgi_child = httpd_try_respond_script(cinfo, &hreq))) {
		httpd_on_cgi_child(cinfo, cgi_child);
	} else if (USE_REAL_CMD && (cgi_child = httpd_try_respond_cmd(cinfo, &hreq))) {
		httpd_on_cgi_child(cinfo, cgi_child);
	} else if (httpd_try_respond_file(cinfo, &hreq,
				httpd_g_outbuf, sizeof(httpd_g_outbuf))) {
		/* file sent, nothing to do */
	} else {
		httpd_header(cinfo, 404, "");
	}
}
Example #4
0
int main(int argc, char **argv) {
	int host;
	int i;
	const char *basedir;
#if USE_IP_VER == 4
	struct sockaddr_in inaddr;
	const size_t inaddrlen = sizeof(inaddr);
	const int family = AF_INET;

	inaddr.sin_family = AF_INET;
	inaddr.sin_port= htons(80);
	inaddr.sin_addr.s_addr = htonl(INADDR_ANY);
#elif USE_IP_VER == 6
	struct sockaddr_in6 inaddr;
	const size_t inaddrlen = sizeof(inaddr);
	const int family = AF_INET6;

	inaddr.sin6_family = AF_INET6;
	inaddr.sin6_port= htons(80);
	memcpy(&inaddr.sin6_addr, &in6addr_any, sizeof(inaddr.sin6_addr));
#else
#error Unknown USE_IP_VER
#endif

	basedir = argc > 1 ? argv[1] : "/";

	host = socket(family, SOCK_STREAM, IPPROTO_TCP);
	if (host == -1) {
		httpd_error("socket() failure: %s", strerror(errno));
		return -errno;
	}

	if (-1 == bind(host, (struct sockaddr *) &inaddr, inaddrlen)) {
		httpd_error("bind() failure: %s", strerror(errno));
		close(host);
		return -errno;
	}

	if (-1 == listen(host, 3)) {
		httpd_error("listen() failure: %s", strerror(errno));
		close(host);
		return -errno;
	}


	for (i = 0; i < MAX_CLIENTS_COUNT; ++i) {
		client_is_free[i] = 1;
	}

	while (1) {
		struct client_info *ci;
		pthread_t thread;
		int index = clients_get_free_index();

		if (index == -1) {
			httpd_error("There are no more memory for new connection!");
			continue;
		}

		ci = &clients[index];
		ci->ci_index=index;
		ci->ci_addrlen = inaddrlen;
		ci->ci_sock = accept(host, &ci->ci_addr, &ci->ci_addrlen);
		if (ci->ci_sock == -1) {
			httpd_error("accept() failure: %s", strerror(errno));
			continue;
		}
		assert(ci->ci_addrlen == inaddrlen);
		ci->ci_basedir = basedir;

		pthread_create(&thread, NULL, do_httpd_client_thread, ci);

		pthread_detach(thread);
	}

	close(host);

	return 0;
}
Example #5
0
int main(int argc, char **argv) {
	int host;
	const char *basedir;
#if USE_IP_VER == 4
	struct sockaddr_in inaddr;
	const size_t inaddrlen = sizeof(inaddr);
	const int family = AF_INET;

	inaddr.sin_family = AF_INET;
	inaddr.sin_port= htons(80);
	inaddr.sin_addr.s_addr = htonl(INADDR_ANY);
#elif USE_IP_VER == 6
	struct sockaddr_in6 inaddr;
	const size_t inaddrlen = sizeof(inaddr);
	const int family = AF_INET6;

	inaddr.sin6_family = AF_INET6;
	inaddr.sin6_port= htons(80);
	memcpy(&inaddr.sin6_addr, &in6addr_any, sizeof(inaddr.sin6_addr));
#else
#error Unknown USE_IP_VER
#endif

	basedir = argc > 1 ? argv[1] : "/";

	host = socket(family, SOCK_STREAM, IPPROTO_TCP);
	if (host == -1) {
		httpd_error("socket() failure: %s", strerror(errno));
		return -errno;
	}

	if (-1 == bind(host, (struct sockaddr *) &inaddr, inaddrlen)) {
		httpd_error("bind() failure: %s", strerror(errno));
		close(host);
		return -errno;
	}

	if (-1 == listen(host, 3)) {
		httpd_error("listen() failure: %s", strerror(errno));
		close(host);
		return -errno;
	}

	while (1) {
		struct client_info ci;

		ci.ci_addrlen = inaddrlen;
		ci.ci_sock = accept(host, &ci.ci_addr, &ci.ci_addrlen);
		if (ci.ci_sock == -1) {
			if (errno != EINTR) {
				httpd_error("accept() failure: %s", strerror(errno));
				usleep(100000);
			}
			continue;
		}
		assert(ci.ci_addrlen == inaddrlen);
		ci.ci_basedir = basedir;

		if (USE_PARALLEL_CGI) {
			while (0 < httpd_wait_cgi_child(-1, WNOHANG)) {
				/* wait another one */
			}
		}

		httpd_client_process(&ci);

		close(ci.ci_sock);
	}

	close(host);

	return 0;
}