Exemplo n.º 1
0
static void
on_write(uv_write_t* req, int status) {
  http_response* response = (http_response*) req->data;

  if (status != 0) {
    fprintf(stderr, "Write error: %s: %s\n", uv_err_name(status), uv_strerror(status));
    destroy_response(response, 1);
    return;
  }

  if (response->response_offset >= response->response_size) {
    destroy_response(response, !response->request->keep_alive);
    return;
  }

  int r = uv_fs_read(loop, &response->read_req, response->fd, &response->buf, 1, response->response_offset, on_fs_read);
  if (r) {
    fprintf(stderr, "File read error: %s: %s\n", uv_err_name(r), uv_strerror(r));
    response_error(response->handle, 500, "Internal Server Error", NULL);
    destroy_request(response->request, 1);
  }
}
Exemplo n.º 2
0
static void
on_fs_read(uv_fs_t *req) {
  http_response* response = (http_response*) req->data;
  int result = req->result;

  uv_fs_req_cleanup(req);
  if (result < 0) {
    fprintf(stderr, "File read error: %s: %s\n", uv_err_name(result), uv_strerror(result));
    response_error(response->handle, 500, "Internal Server Error", NULL);
    destroy_response(response, 1);
    return;
  } else if (result == 0) {
    destroy_response(response, 1);
    return;
  }

  uv_buf_t buf = uv_buf_init(response->pbuf, result);
  int r = uv_write(&response->write_req, (uv_stream_t*) response->handle, &buf, 1, on_write);
  if (r) {
    destroy_response(response, 1);
    return;
  }
  response->response_offset += result;
}
Exemplo n.º 3
0
static void
on_fs_open(uv_fs_t* req) {
  http_request* request = (http_request*) req->data;
  int result = req->result;

  uv_fs_req_cleanup(req);
  free(req);
  if (result < 0) {
    fprintf(stderr, "Open error: %s: %s\n", uv_err_name(result), uv_strerror(result));
    response_error(request->handle, 404, "Not Found\n", NULL);
    destroy_request(request, 1);
    return;
  }

  uv_fs_t stat_req;
  int r = uv_fs_fstat(loop, &stat_req, result, NULL);
  if (r) {
    fprintf(stderr, "Stat error: %s: %s\n", uv_err_name(r), uv_strerror(r));
    response_error(request->handle, 404, "Not Found\n", NULL);
    destroy_request(request, 1);
    return;
  }

  uint64_t response_size = stat_req.statbuf.st_size;
  uv_fs_req_cleanup(&stat_req);

  const static char* ctype = "application/octet-stream";
  const char* dot = request->file_path;
  const char* ptr = dot;
  while (dot) {
    ptr = dot;
    dot = strchr(dot + 1, '.');
  }
  khint_t k = kh_get(mime_type, mime_type, ptr);
  if (k != kh_end(mime_type)) {
    ctype = kh_value(mime_type, k);
  }

  http_response* response = calloc(1, sizeof(http_response));
  if (response == NULL) {
    fprintf(stderr, "Allocate error: %s\n", strerror(r));
    response_error(request->handle, 404, "Not Found\n", NULL);
    destroy_request(request, 1);
    return;
  }
  response->response_size = response_size;
  response->fd = result;
  response->request = request;
  response->handle = request->handle;
  response->pbuf = malloc(WRITE_BUF_SIZE);
  if (response->pbuf == NULL) {
    fprintf(stderr, "Allocate error: %s\n", strerror(r));
    response_error(request->handle, 404, "Not Found\n", NULL);
    destroy_response(response, 1);
    return;
  }
  response->buf = uv_buf_init(response->pbuf, WRITE_BUF_SIZE);
  response->read_req.data = response;
  response->write_req.data = response;

  char bufline[1024];
  int nbuf = snprintf(bufline,
      sizeof(bufline),
      "HTTP/1.1 200 OK\r\n"
      "Content-Length: %" PRId64 "\r\n"
      "Content-Type: %s\r\n"
      "Connection: %s\r\n"
      "\r\n",
      response_size,
      ctype,
      (request->keep_alive ? "keep-alive" : "close"));
  uv_buf_t buf = uv_buf_init(bufline, nbuf);

#ifndef _WIN32
  r = uv_try_write((uv_stream_t*) request->handle, &buf, 1);
  if (r == 0) {
    fprintf(stderr, "Write error\n");
    destroy_response(response, 1);
    return;
  }
#else
  r = uv_write(&response->write_req, (uv_stream_t*) request->handle, &buf, 1, NULL);
  if (r) {
    fprintf(stderr, "Write error: %s: %s\n", uv_err_name(r), uv_strerror(r));
    destroy_response(response, 1);
    return;
  }
#endif

  r = uv_fs_read(loop, &response->read_req, result, &response->buf, 1, -1, on_fs_read);
  if (r) {
    response_error(request->handle, 500, "Internal Server Error\n", NULL);
    destroy_response(response, 1);
  }
}
Exemplo n.º 4
0
int main(int argc, char *argv[]) {
	int port = 1220;
	if (argc > 1) 
		port = atoi(argv[1]);

	int fd = socket(AF_INET, SOCK_STREAM, 0);
	int flags = 1;
	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags));
	setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));

	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);

	if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		perror("bind()");
		if(fd > 0) close(fd);
		exit(1);
	}

	if (listen(fd, 1024) < 0) {
		perror("listen()");
		exit(1);
	}

	RespRequest *req = create_request(BUF_SIZE);
	RespResponse *res = create_response(BUF_SIZE);
	while (1) {
		reset_request(req);
		reset_response(res);	

		socklen_t addr_len = sizeof(addr);
		int cfd = accept(fd, (struct sockaddr*)&addr, &addr_len);
		if (cfd < 0) {
			perror("accept()");
			continue;
		}
		char buf[1024];
		int rnum = read(cfd,buf,sizeof(buf));
		
		if (decode_request(req, buf, rnum) == 0 && 
			(req->state == OK || req->state == PART_OK) ){
			if (req->argc > 1 && strncmp(request_argv(req,0), "add", 3) == 0) {
				int total = 0;
				for (int i = 1; i < req->argc; i++)
					total += atoi(request_argv(req,i));
				encode_response_integer(res, total);
			}
			else {
				encode_response_status(res,0,"ERR unknown command");
			}
		}
		else {
			encode_response_status(res,0,"ERR decode command fail");
		}
		write(cfd, res->buf, res->used_size);
		close(cfd);
	}
	destroy_request(req);
	destroy_response(res);

	close(fd);
	return 0;
}