コード例 #1
0
ファイル: fcgiwrap.c プロジェクト: Jille/fcgiwrap
static void fcgi_pass(struct fcgi_context *fc)
{
	char buf[FCGI_BUF_SIZE];
	fd_set rset;
	int maxfd = 1 + max_va(fc->fd_stdout, fc->fd_stderr, MAX_VA_SENTINEL);
	int nready;
	const char *err;

	if (!fcgi_pass_request(fc))
		return;

	/* now pass CGI reply back */
	while (fc->fd_stdout >= 0 || fc->fd_stderr >= 0) {
		FD_ZERO(&rset);
		if (fc->fd_stdout >= 0) FD_SET(fc->fd_stdout, &rset);
		if (fc->fd_stderr >= 0) FD_SET(fc->fd_stderr, &rset);
		nready = select(maxfd, &rset, NULL, NULL, NULL);
		if (nready < 0) {
			if (errno == EAGAIN) continue;
			fcgi_finish(fc, "waiting for CGI reply");
			return;
		}
		if (fc->fd_stdout >= 0 && FD_ISSET(fc->fd_stdout, &rset)) {
			err = fcgi_pass_fd(fc, &fc->fd_stdout, FCGI_stdout, buf, sizeof(buf));
			if (err) {
				fcgi_finish(fc, err);
				return;
			}
		}
		if (fc->fd_stderr >= 0 && FD_ISSET(fc->fd_stderr, &rset)) {
			if (stderr_to_fastcgi)
				err = fcgi_pass_fd(fc, &fc->fd_stderr, FCGI_stderr, buf, sizeof(buf));
			else
				err = fcgi_pass_raw_fd(&fc->fd_stderr, 2, buf, sizeof(buf));
			if (err) {
				fcgi_finish(fc, err);
				return;
			}
		}
	}

	fc->cgi_pid = 0;

	fcgi_finish(fc, "reading CGI reply (no response received)");
}
コード例 #2
0
ファイル: fcgiwrap.c プロジェクト: jeremyz/fcgiwrap
static bool fcgi_pass_request(struct fcgi_context *fc)
{
	char buf[FCGI_BUF_SIZE];
	ssize_t nread;

	/* eat the whole request and pass it to CGI */
	while ((nread = FCGI_fread(buf, 1, sizeof(buf), FCGI_stdin)) > 0) {
		if (write_all(fc->fd_stdin, buf, nread) <= 0) {
			fcgi_finish(fc, "reading the request");
			return false;
		}
	}
	close(fc->fd_stdin);
	fc->fd_stdin = -1;

	return true;
}
コード例 #3
0
ファイル: fcgi.c プロジェクト: keriharris/pl-fcgi
foreign_t
fcgi_accept(control_t h)
{
  FCGX_Request *req;
  fd_set fds;
  fcgi_context *ctxt;
  int status;

  FCGI_debug("fcgi_accept()");

  if ( FCGX_IsCGI() )
  { return TRUE;
  }

  ctxt = pthread_getspecific(key);

  if ( !ctxt )
  { ctxt = malloc(sizeof(*ctxt));
    memset(ctxt, 0, sizeof(*ctxt));
  }

  if ( ctxt->req )
  { fcgi_finish();
  }

  req = malloc(sizeof(*req));
  memset(req, 0, sizeof(*req));

  status = FCGX_InitRequest(req, 0, 0);
  if ( status != FCGI_SUCCESS )
  { return fcgi_raise_error(status, "FCGX_InitRequest() failed");
  }

  FD_ZERO(&fds);
  FD_SET(req->listen_sock, &fds);
  if ( select(req->listen_sock+1, &fds, NULL, NULL, NULL) < 1 )
  { return FALSE;
  }

  status = FCGX_Accept_r(req);
  if ( status != FCGI_SUCCESS )
  { return fcgi_raise_error(status, "FCGX_Accept_r() failed");
  }

  FCGI_debug("REMOTE_ADDR: %s, REQUEST_METHOD: %s, REQUEST_URI: %s",
             FCGX_GetParam("REMOTE_ADDR", req->envp),
             FCGX_GetParam("REQUEST_METHOD", req->envp),
             FCGX_GetParam("REQUEST_URI", req->envp));

  if ( !ctxt )
  { ctxt = malloc(sizeof(*ctxt));
    memset(ctxt, 0, sizeof(*ctxt));
  }

  ctxt->req = req;

  ctxt->pl_in = Suser_input;
  ctxt->h_in = Suser_input->handle;
  ctxt->fn_in = Suser_input->functions;
  ctxt->fcgi_in = req->in;

  ctxt->pl_out = Suser_output;
  ctxt->h_out = Suser_output->handle;
  ctxt->fn_out = Suser_output->functions;
  ctxt->fcgi_out = req->out;

  ctxt->pl_err = Suser_error;
  ctxt->h_err = Suser_error->handle;
  ctxt->fn_err = Suser_error->functions;
  ctxt->fcgi_err = req->err;

  ctxt->env = req->envp;

  pthread_setspecific(key, ctxt);

  Suser_input->handle = req->in;
  Suser_input->functions = &fcgi_functions;

  Suser_output->handle = req->out;
  Suser_output->functions = &fcgi_functions;

  Suser_error->handle = req->err;
  Suser_error->functions = &fcgi_functions;

  PL_retry(0);
}