class FCGI

There is no C version of 'each_cgi' Note: for ruby-1.6.8 at least, the constants CGI_PARAMS/CGI_COOKIES are defined within module 'CGI', even if you have subclassed it

Constants

FCGI_ABORT_REQUEST
FCGI_AUTHORIZER
FCGI_BEGIN_REQUEST

Record types

FCGI_CANT_MPX_CONN
FCGI_DATA
FCGI_END_REQUEST
FCGI_FILTER
FCGI_GET_VALUES
FCGI_GET_VALUES_RESULT
FCGI_KEEP_CONN

FCGI_BEGIN_REQUEST.flags

FCGI_MAXTYPE
FCGI_NULL_REQUEST_ID
FCGI_OVERLOADED
FCGI_PARAMS
FCGI_REQUEST_COMPLETE

FCGI_END_REQUEST.protocolStatus

FCGI_RESPONDER

FCGI_BEGIN_REQUSET.role

FCGI_STDERR
FCGI_STDIN
FCGI_STDOUT
FCGI_UNKNOWN_ROLE
FCGI_UNKNOWN_TYPE
ProtocolVersion

Public Class Methods

accept() click to toggle source
static VALUE fcgi_s_accept(VALUE self)
{
  int status;
  FCGX_Request *req;
  fd_set readfds;

  req = ALLOC(FCGX_Request);

  status = FCGX_InitRequest(req,0,0);
  if (status != 0) {
    rb_raise(eFCGIError, "FCGX_Init() failed");
    return Qnil;
  }

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

  status = FCGX_Accept_r(req);
  if (status >= 0) {
    fcgi_data *data;
    fcgi_stream_data *stream_data;
    char      **env;
    VALUE     obj,key, value;
    char      *pkey,*pvalue;
    int       flags, fd;

    /* Unset NONBLOCKING */
    fd = ((FCGX_Request*) req)->ipcFd;
    flags = fcntl(fd, F_GETFL);

    if (flags & O_NONBLOCK) {
       fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
    }

    obj = Data_Make_Struct(self, fcgi_data, fcgi_mark, fcgi_free_req, data);
    data->req = req;
    data->in = Data_Make_Struct(cFCGIStream, fcgi_stream_data, fcgi_stream_mark, fcgi_stream_free, stream_data);
    stream_data->stream = req->in;
    stream_data->req = obj;
    data->out = Data_Make_Struct(cFCGIStream, fcgi_stream_data, fcgi_stream_mark, fcgi_stream_free, stream_data);
    stream_data->stream = req->out;
    stream_data->req = obj;
    data->err = Data_Make_Struct(cFCGIStream, fcgi_stream_data, fcgi_stream_mark, fcgi_stream_free, stream_data);
    stream_data->stream = req->err;
    stream_data->req = obj;
    data->env = rb_hash_new();
    env = req->envp;
    for (; *env; env++) {
      int size = 0;
      pkey = *env;
      pvalue = pkey;
      while( *(pvalue++) != '=') size++;
      key   = rb_str_new(pkey, size);
      value = rb_str_new2(pvalue);
      OBJ_TAINT(key);
      OBJ_TAINT(value);
      rb_hash_aset(data->env, key, value);
    }

    return obj;
  } else {
    FCGX_Free(req, 1);
    free(req);
    return Qnil;
  }
}
default_connection() click to toggle source
# File lib/fcgi.rb, line 53
def self.default_connection
  ::Socket.for_fd($stdin.fileno)
end
each() click to toggle source
static VALUE fcgi_s_each(VALUE self)
{
  VALUE fcgi;

  while ((fcgi = fcgi_s_accept(self)) != Qnil) {
    rb_yield(fcgi);
  }
  return Qnil;
}
each_cgi(*args) { |cgi(*args)| ... } click to toggle source
# File lib/fcgi.rb, line 588
  def self.each_cgi(*args)
    require 'cgi'

    eval(<<-EOS,TOPLEVEL_BINDING)
    class CGI
      public :env_table
      def self.remove_params
        if (const_defined?(:CGI_PARAMS))
          remove_const(:CGI_PARAMS)
          remove_const(:CGI_COOKIES)
        end
      end
    end # ::CGI class

    class FCGI
      class CGI < ::CGI
        def initialize(request, *args)
          ::CGI.remove_params
          @request = request
          super(*args)
          @args = *args
        end
        def args
          @args
        end
        def env_table
          @request.env
        end
        def stdinput
          @request.in
        end
        def stdoutput
          @request.out
        end
      end # FCGI::CGI class
    end # FCGI class
    EOS

    if FCGI::is_cgi?
      yield ::CGI.new(*args)
    else
      exit_requested = false
      FCGI::each do |request|

        $stdout, $stderr = request.out, request.err

        yield CGI.new(request, *args)

        request.finish
      end
    end
  end
each_request() click to toggle source
static VALUE fcgi_s_each(VALUE self)
{
  VALUE fcgi;

  while ((fcgi = fcgi_s_accept(self)) != Qnil) {
    rb_yield(fcgi);
  }
  return Qnil;
}
is_cgi?() click to toggle source
static VALUE fcgi_s_iscgi(VALUE self)
{
  if (FCGX_IsCGI()) {
    return Qtrue;
  } else {
    return Qfalse;
  }
}

Public Instance Methods

env() click to toggle source
static VALUE fcgi_env(VALUE self)
{
  fcgi_data *data;

  Data_Get_Struct(self, fcgi_data, data);
  return data->env;
}
err() click to toggle source
static VALUE fcgi_err(VALUE self)
{
  fcgi_data *data;

  Data_Get_Struct(self, fcgi_data, data);
  return data->err;
}
finish() click to toggle source
static VALUE fcgi_finish(VALUE self)
{
  fcgi_data *data;
  fcgi_stream_data *stream_data;

  Data_Get_Struct(self, fcgi_data, data);

  if (Qnil != data->in) {
    Data_Get_Struct(data->in, fcgi_stream_data, stream_data);
    stream_data->req = Qnil; stream_data->stream = NULL;
  }
  if (Qnil != data->out) {
    Data_Get_Struct(data->out, fcgi_stream_data, stream_data);
    stream_data->req = Qnil; stream_data->stream = NULL;
  }
  if (Qnil != data->err) {
    Data_Get_Struct(data->err, fcgi_stream_data, stream_data);
    stream_data->req = Qnil; stream_data->stream = NULL;
  }

  data->in = data->out = data->err = Qnil;
  FCGX_Finish_r(data->req);

  return Qtrue;
}
in() click to toggle source
static VALUE fcgi_in(VALUE self)
{
  fcgi_data *data;

  Data_Get_Struct(self, fcgi_data, data);
  return data->in;
}
out() click to toggle source
static VALUE fcgi_out(VALUE self)
{
  fcgi_data *data;

  Data_Get_Struct(self, fcgi_data, data);
  return data->out;
}