Beispiel #1
0
int
clip_FCGI_ACCEPT(ClipMachine *mp)
{
	int r;

	if (inited)
	{
		flush_bufs();
		FCGX_Finish();
	}

	r = FCGX_Accept(&in, &out, &err, &envp);
	/*r = FCGI_Accept();*/
	_clip_retl(mp, (r >= 0) ? 1 : 0);

	if (!inited)
	{
		inited = 1;

		init_Buf(&obuf);
		init_Buf(&ebuf);

		mp->obuf = &obuf;
		mp->ebuf = &ebuf;
	}

	return 0;
}
int main()
{
	FCGX_Stream *in, *out, *err;
	FCGX_ParamArray envp;
	redisContext *rc = faptime_redis_connect();
	if (NULL == rc) {
		error_log("Unable to connect to Redis");
		/* exit(1); */
	}

	faptime_create_lookup_table();

	/* int count = 0; */
	int redis_errno = 0;
	long long id = 0;
	char *redirect_to, *req_uri;
	while (FCGX_Accept(&in, &out, &err, &envp) >= 0) {
		FAPTIME_REQ_INIT();
		req_uri = FCGX_GetParam("REQUEST_URI", envp);
		error_log("This is an error mofo");
		debug_log("== Begin Request ==");

		/* default_message(out, &envp, &count); */
		/* continue; */

		if (req_uri == NULL) {
			error_log("request_uri was NULL");
			faptime_set_status(500);
			FAPTIME_REQ_FINISH();
			continue;
		}

		if (valid_hash(req_uri) != FAPTIME_HASH_OK || !(id = faptime_decode(req_uri))) {
			debug_log("Request URI '%s' was not valid", req_uri);
			faptime_set_status(404);
			FAPTIME_REQ_FINISH();
			continue;

		}

		if ((redirect_to = faptime_get_url(rc, id, &redis_errno)) == NULL) {
			assert(redirect_to == NULL);
			debug_log("Request hash %lld (%s) had no url", id, req_uri);
			faptime_set_status(404);
			FAPTIME_REQ_FINISH();
			continue;

		}

		faptime_set_status(302);
		faptime_set_redirect(redirect_to);
		free(redirect_to);
		FAPTIME_REQ_FINISH();
	}
	return 0;
}
int fcgi_accept()
{
#ifdef Q_OS_WIN
  if ( FCGX_IsCGI() )
    return FCGI_Accept();
  else
    return FCGX_Accept( &FCGI_stdin->fcgx_stream, &FCGI_stdout->fcgx_stream, &FCGI_stderr->fcgx_stream, &environ );
#else
  return FCGI_Accept();
#endif
}
Beispiel #4
0
int main(int argc, char *argv[])
{
	if(argc > 1){
		if(argc == 3){
			// as normal program, not cgi now
			printf("update dns, domain: %s, host: %s\n", argv[1], argv[2]);
			int ret = dns_update(argv[1], argv[2]);
			if(ret < 0){
			        printf("Internal error.\n");
			}else if(ret == 1){
			        printf("Recorde can't find.\n");
			}else if(ret == 2){
			        printf("Recorde still fresh.\n");
			}else if(ret == 0){
			        printf("Recorde refreshed.\n");
			}else{
			        printf("Unknown error.\n");
			}
		}else{
			printf("Usage: %s <domain> <host>\n", argv[0]);
		}
		return 0;
	}

	FCGX_Stream *in;
	FCGX_Stream *out;
	FCGX_Stream *err;
	FCGX_ParamArray envp;

	char *method = NULL;
	while(FCGX_Accept(&in, &out, &err, &envp) >= 0)
	{
		method = FCGX_GetParam("REQUEST_METHOD", envp);
		if(strcmp(method, "POST") == 0){
			//request_post(in, out, &envp);
		}else if(strcmp(method, "GET") == 0){
			request_get(in, out, &envp);
		}

	}

	FCGX_Finish();

	//test();

	return 0;
}
Beispiel #5
0
int main ()
{
    FCGX_Stream *in, *out, *err;
    FCGX_ParamArray envp;
    int count = 0;

    while (FCGX_Accept(&in, &out, &err, &envp) >= 0) {
        char *contentLength = FCGX_GetParam("CONTENT_LENGTH", envp);
        int len = 0;

        FCGX_FPrintF(out,
           "Content-type: text/html\r\n"
           "\r\n"
           "<title>FastCGI echo (fcgiapp version)</title>"
           "<h1>FastCGI echo (fcgiapp version)</h1>\n"
           "Request number %d,  Process ID: %d<p>\n", ++count, getpid());

        if (contentLength != NULL)
            len = strtol(contentLength, NULL, 10);

        if (len <= 0) {
            FCGX_FPrintF(out, "No data from standard input.<p>\n");
        }
        else {
            int i, ch;

            FCGX_FPrintF(out, "Standard input:<br>\n<pre>\n");
            for (i = 0; i < len; i++) {
                if ((ch = FCGX_GetChar(in)) < 0) {
                    FCGX_FPrintF(out,
                        "Error: Not enough bytes received on standard input<p>\n");
                    break;
                }
                FCGX_PutChar(ch, out);
            }
            FCGX_FPrintF(out, "\n</pre><p>\n");
        }

        PrintEnv(out, "Request environment", envp);
        PrintEnv(out, "Initial environment", environ);
    } /* while */

    return 0;
}
Beispiel #6
0
int FCGI_Accept(void)
{
    if(!acceptCalled) {
        /*
         * First call to FCGI_Accept.  Is application running
         * as FastCGI or as CGI?
         */
        isCGI = FCGX_IsCGI();
        acceptCalled = TRUE;
        atexit(&FCGI_Finish);
    } else if(isCGI) {
        /*
         * Not first call to FCGI_Accept and running as CGI means
         * application is done.
         */
        return(EOF);
    }
    if(isCGI) {
        FCGI_stdin->stdio_stream = stdin;
        FCGI_stdin->fcgx_stream = NULL;
        FCGI_stdout->stdio_stream = stdout;
        FCGI_stdout->fcgx_stream = NULL;
        FCGI_stderr->stdio_stream = stderr;
        FCGI_stderr->fcgx_stream = NULL;
    } else {
        FCGX_Stream *in, *out, *error;
        FCGX_ParamArray envp;
        int acceptResult = FCGX_Accept(&in, &out, &error, &envp);
        if(acceptResult < 0) {
            return acceptResult;
        }
        FCGI_stdin->stdio_stream = NULL;
        FCGI_stdin->fcgx_stream = in;
        FCGI_stdout->stdio_stream = NULL;
        FCGI_stdout->fcgx_stream = out;
        FCGI_stderr->stdio_stream = NULL;
        FCGI_stderr->fcgx_stream = error;
        environ = envp;
    }
    return 0;
}
Beispiel #7
0
void process( redisContext *c )
{

	FCGX_Stream *in, *out, *err;
	FCGX_ParamArray envp;
	redisReply *r;
	
	json reason = { .type = STRING, .name = "reason", .str = NULL };
	json* failureEls[1] = { &reason };
	json success = { .type = OBJECT, .length = 0, .name = NULL, .objArr = NULL }; 
	json failure = { .type = OBJECT, .length = 1, .name = NULL, .objArr = failureEls }; 

	while ( FCGX_Accept( &in, &out, &err, &envp ) >= 0 )
	{
		
		// Check method
		if ( check_method_post( out, envp ) )
			continue;

		// Check user is logged in
		char sid[33];
		char *user = session( c, envp, sid );
		if ( !user )
		{
			header( out, 401, NULL );
			reason.str = "Not logged in.";
			json_out( out, &failure );
			continue;
		}

		// Initialize reused variables	
		reason.str = "";

		// Get contentlength
		long len = content_length( envp );
		
		// Get post params
		char *s;
		if ( !read_stream( &s, in, len ) )
		{
			header( out, 400, NULL );
			reason.str = "No parameters provided";
			json_out( out, &failure );
			continue;
		}

		// Parse POST params
		param *p;
		ssize_t num = convert_to_params( &p, s, "&", "=", -1 );
		
		// Get parameters
		char *courses = NULL, *date = NULL, *start = NULL, *finish = NULL, *students = NULL, *idStr = NULL;
		for ( int i = 0; i < num; ++i )
		{
			if ( !courses && !strcmp( p[i].name, "courses" ) ) {
				courses = p[i].value;
            } else if ( !date && !strcmp( p[i].name, "date" ) ) { 
                date = p[i].value;
            } else if ( !start && !strcmp( p[i].name, "start" ) ) { 
                start = p[i].value;
            } else if ( !finish && !strcmp( p[i].name, "finish" ) ) { 
                finish = p[i].value;
            } else if ( !students && !strcmp( p[i].name, "students" ) ) { 
                students = p[i].value;
			} else if ( !idStr && !strcmp( p[i].name, "id" ) ) {
				idStr = p[i].value;
			}
		}

		// Check all parameters entered
		if ( !courses || !date || !start || !finish || !students )
		{
			header( out, 400, NULL );
			reason.str = "All details must be entered.";
			json_out( out, &failure );
			goto err;
		}

		// URL decode components
		inplace_url_decode( courses );
		inplace_url_decode( date );
		inplace_url_decode( start );
		inplace_url_decode( finish );
		inplace_url_decode( students );

		// Get next tute id
		long long id = -1;
		if ( idStr ) {
			// Convert to long long 
			id = strtol( idStr, NULL, 10 );
			
			// Check user owns tute
			r = redisCommand( c, "SISMEMBER tute:tutor:%s %lld", user, id );
			if ( r->type != REDIS_REPLY_INTEGER )
			{
				header( out, 500, NULL );
				reason.str = "DB Error.";
				json_out( out, &failure );
				freeReplyObject( r );
				goto err;
			}
			if ( r->type != 1 )
			{
				header( out, 400, NULL );
				reason.str = "Invalid ID.";
				json_out( out, &failure );
				freeReplyObject( r );
				goto err;
			}
		} else {
			r = redisCommand( c, "INCR tute:tute:counter" );
			if ( r->type != REDIS_REPLY_INTEGER )
			{
				header( out, 500, NULL );
				reason.str = "Could not fetch tute counter.";
				json_out( out, &failure );
				freeReplyObject( r );
				goto err;
			}
			id = r->integer;
			freeReplyObject( r );
		}

		// Save tute
		r = redisCommand( c, "HMSET tute:tute:%lld tutor %s date %s start %s finish %s", id, user, date, start, finish );
		if ( r->type == REDIS_REPLY_ERROR )
		{
			header( out, 500, NULL );
			reason.str = "Could not save tute.";
			json_out( out, &failure );
			freeReplyObject( r );
			goto err;
		}
		freeReplyObject( r );

		// Save id to tutor
		r = redisCommand( c, "SADD tute:tutor:%s %lld", user, id );
		if ( r->type == REDIS_REPLY_ERROR )
		{
			header( out, 500, NULL );
			reason.str = "Could not save tute.";
			json_out( out, &failure );
			freeReplyObject( r );
			goto err;
		}
		freeReplyObject( r );

		// Parse codes
		param *course;
		ssize_t numCourses = convert_to_params( &course, courses, ";", ":", -1 ); 
		num = numCourses;
		while ( num-- )
		{
			// convert to lower
			to_lower( course[num].name );

			// Save each code to tute id
			r = redisCommand( c, "SADD tute:tute:%lld:courses %s", id, course[num].name );
			if ( r->type == REDIS_REPLY_ERROR )
			{
				header( out, 500, NULL );
				reason.str = "Could not save tute.";
				json_out( out, &failure );
				freeReplyObject( r );
				goto courseErr;
			}
			freeReplyObject( r );

			// Add tute id to each code
			r = redisCommand( c, "SADD tute:course:%s:tutes %lld", course[num].name, id );
			if ( r->type == REDIS_REPLY_ERROR )
			{
				header( out, 500, NULL );
				reason.str = "Could not save tute.";
				json_out( out, &failure );
				freeReplyObject( r );
				goto courseErr;
			}
			freeReplyObject( r );

		}
		
		// Parse students 
		param *student;
		num = convert_to_params( &student, students, ";", ":", -1 ); 
		while ( num-- )
		{
			// Add each student to tute
			r = redisCommand( c, "SADD tute:tute:%lld:students %s", id, student[num].name );
			if ( r->type == REDIS_REPLY_ERROR )
			{
				header( out, 500, NULL );
				reason.str = "Could not save tute.";
				json_out( out, &failure );
				freeReplyObject( r );
				goto studentErr;
			}
			freeReplyObject( r );

			// Save student data
			param *data;
			ssize_t fields = convert_to_params( &data, student[num].value, ",", "|", -1 );
			if ( fields ) { 

				char *college = NULL, *first = NULL, *last = NULL;	
				while ( fields-- )
				{
					if ( !college && !strcmp( data[fields].name, "college" ) ) {
						college = data[fields].value;
					} else if ( !first && !strcmp( data[fields].name, "first" ) ) {
						first = data[fields].value;
					} else if ( !last && !strcmp( data[fields].name, "last" ) ) {
						last = data[fields].value;
					}
				}
				
				if ( college && first && last )
				{
					r = redisCommand( c, "HMSET tute:student:%s college %s first %s last %s", student[num].name, college, first, last );
					if ( r->type == REDIS_REPLY_ERROR )
					{
						header( out, 500, NULL );
						reason.str = "Could not save tute.";
						json_out( out, &failure );
						freeReplyObject( r );
						free( data );
						goto studentErr;
					}
					freeReplyObject( r );
				}

				free( data );
			}

			// Add tute id to each student
			r = redisCommand( c, "SADD tute:attendee:%s %lld", student[num].name, id );
			if ( r->type == REDIS_REPLY_ERROR )
			{
				header( out, 500, NULL );
				reason.str = "Could not save tute.";
				json_out( out, &failure );
				freeReplyObject( r );
				goto studentErr;
			}
			freeReplyObject( r );

			// Add student to each course
			ssize_t n = numCourses;
			while ( n-- )
			{
				r = redisCommand( c, "SADD tute:course:%s:students %s", course[n].name, student[num].name );
				if ( r->type == REDIS_REPLY_ERROR )
				{
					header( out, 500, NULL );
					reason.str = "Could not save tute.";
					json_out( out, &failure );
					freeReplyObject( r );
					goto studentErr;
				}
				freeReplyObject( r );
			}

		}

		// Output success
		header( out, 200, sid );
		json_out( out, &success );
		
		studentErr:
			free( student ); // free params structure
		courseErr:
			free( course );
		err:
			free( user );
			free( p ); // Free params structure
			free( s ); // Free POST stream
	}
}

int main ( int argc, char *argv[] )
{
	return init( &process );
}
Beispiel #8
0
int main() {

#ifdef	PROFILE
    int i;
#endif
    const char *config_url, *username, *password, *config_options;
    strtbl *options = NULL;
    int exit_status = 0;

    // install SIGUSR1, SIGPIPE, SIGTERM handler
    signal(SIGTERM, sig_handler);
    signal(SIGUSR1, sig_handler);
    signal(SIGPIPE, sig_handler);

      /* Provide a hook via an environment variable to define the config URL */
      config_url = getenv(WO_CONFIG_URL);
      if (!config_url) {
         /* Flat file URL */
         /* config_url = "file:///Local/Library/WebObjects/Configuration/WOConfig.xml"; */
         /* Local wotaskd */
         /* config_url = "http://localhost:1085"; */
         /* Multicast URL */
         config_url = CONFIG_URL; /* Actually "webobjects://239.128.14.2:1085"; */
      }
      WOLog(WO_INFO,"<FastCGI> config url is %s", config_url);
      options = st_new(8);
      st_add(options, WOCONFIG, config_url, 0);

      /*
         * If your webserver is configured to pass these environment variables, we use them to
       * protect WOAdaptorInfo output.
       */
      username = getenv(WO_ADAPTOR_INFO_USERNAME);
      if (username && strlen(username) != 0) {
         st_add(options, WOUSERNAME, username, 0);
         password = getenv(WO_ADAPTOR_INFO_PASSWORD);
         if(password && strlen(password) != 0) {
            st_add(options, WOPASSWORD, password, 0);
         }
      }

      config_options = getenv(WO_CONFIG_OPTIONS);
      if (config_options)
         st_add(options, WOOPTIONS, config_options, 0);
      /*
       * SECURITY ALERT
       *
       * To disable WOAdaptorInfo, uncomment the next line.
       * st_add(options, WOUSERNAME, "disabled", 0);
       *
       * To specify an WOAdaptorInfo username and password, uncomment the next two lines.
       * st_add(options, WOUSERNAME, "joe", 0);
       * st_add(options, WOPASSWORD, "secret", 0);
       *
       */

      if (init_adaptor(options)) {
          WOLog( WO_ERR, "<FastCGI> Adaptor initialization failed.");
    	    exit(-1);
      }

    WOLog( WO_INFO,"<FastCGI> process started" );
   
    while (!should_terminate) {

      HTTPRequest *req;
      HTTPResponse *resp = NULL;
      WOURLComponents wc = WOURLComponents_Initializer;
      const char *qs;
      unsigned int qs_len;
      char *url;
      const char *script_name, *path_info;
      const char *reqerr;
      WOURLError urlerr;
      FCGX_ParamArray hdrp_org;
     
      exit_status = FCGX_Accept(&in, &out, &err, &hdrp );
      if ( exit_status < 0 ) {
	    break;
      }

#ifdef	PROFILE
    for (i=0; i < 50000; i++) {
#endif

      WOLog( WO_INFO,"<FastCGI> request accepted" );

#ifdef WIN32
      _setmode(_fileno(stdout), _O_BINARY);
      _setmode(_fileno(stdin), _O_BINAR1Y);
#endif

      script_name = FCGX_GetParam( CGI_SCRIPT_NAME, hdrp);
      path_info = FCGX_GetParam( CGI_PATH_INFO, hdrp);

      WOLog( WO_INFO,"<FastCGI> CGI_SCRIPT_NAME = %s", script_name );
      WOLog( WO_INFO,"<FastCGI> CGI_PATH_INFO = %s", path_info );

      if (script_name == NULL) {
         prepareAndSendErrorResponse(INV_SCRIPT, HTTP_NOT_FOUND);
         break;
      } else if (path_info == NULL) {
         path_info = "/";
      }

      /*
       *	extract WebObjects application name from URI
       */

      url = WOMALLOC(strlen(path_info) + strlen(script_name) + 1);
      strcpy(url, script_name);
      strcat(url, path_info);
      WOLog(WO_INFO,"<FastCGI> new request: %s",url);
      
      urlerr = WOParseApplicationName(&wc, url);
      if (urlerr != WOURLOK) {
         const char *_urlerr;
         _urlerr = WOURLstrerror(urlerr);
         WOLog(WO_INFO,"<FastCGI> URL Parsing Error: %s", _urlerr);

         if (urlerr == WOURLInvalidApplicationName) {
             if (ac_authorizeAppListing(&wc)) {
                 resp = WOAdaptorInfo(NULL, &wc);
                 sendErrorResponse(resp);
             } else {
                 prepareAndSendErrorResponse(_urlerr, HTTP_NOT_FOUND);
             }
             WOFREE(url);
             break;
         }

         prepareAndSendErrorResponse(_urlerr, HTTP_BAD_REQUEST);
         WOFREE(url);
         break;
      }


      /*
       *	build the request...
       */
      req = req_new( FCGX_GetParam("REQUEST_METHOD", hdrp), NULL);


      /*
       *	validate the method
       */
      reqerr = req_validateMethod(req);
      if (reqerr) {
          prepareAndSendErrorResponse(reqerr, HTTP_BAD_REQUEST);
          WOFREE(url);
          break;
      }

      /*
       *	copy the headers.  This looks wierd... all we're doing is copying
       *	*every* environment variable into our headers.  It may be beyond
       *	the spec, but more information probably won't hurt.
       */
      hdrp_org=hdrp;
      while (hdrp && *hdrp) {
         char *key, *value;
         /* copy env. line. */
         key = WOSTRDUP(*hdrp);

         for (value = key; *value && !isspace((int)*value) && (*value != '='); value++) {}
         if (*value) {
            *value++ = '\0';	/* null terminate 'key' */
         }
         while (*value && (isspace((int)*value) || (*value == '='))) {
            value++;
         }
         /* BEGIN Support for getting the client's certificate. */
         if (strcmp((const char *)key, "SSL_CLIENT_CERTIFICATE") == 0 || strcmp((const char *)key, "SSL_SERVER_CERTIFICATE") == 0 ) {
             value = 0;
             WOLog(WO_INFO,"<FastCGI> DROPPING ENV VAR (DUPLICATE) = %s", key);
         }
         if (strcmp((const char *)key, "SSL_CLIENT_CERT") == 0 || strcmp((const char *)key, "SSL_SERVER_CERT") == 0) {
             value = make_cert_one_line(value);
             //WOLog(WO_INFO,"<FastCGI> PASSING %s = %s", key, value);
         }
         /*  END Support for getting the client's certificate  */

         if (key && *key && value && *value) {
            /* must specify copy key and value because key translation might replace this key, and value lives in the same buffer */
            req_addHeader(req, key, value, STR_COPYKEY|STR_COPYVALUE);
         }

         /*  BEGIN Support for getting the client's certificate  */
         if (freeValueNeeded ) {
             free(value);
             freeValueNeeded=0;
         }
         /*  END Support for getting the client's certificate  */

         WOFREE(key);
         hdrp++;			/* next env variable */
      }
      hdrp=hdrp_org;

      /*
       *	get form data if any
       *	assume that POSTs with content length will be reformatted to GETs later
       */
	
      WOLog ( WO_INFO, "Getting request data, length: %d",req->content_length );
      if (req->content_length > 0) {
         req_allocateContent(req, req->content_length, 1);
         req->getMoreContent = (req_getMoreContentCallback)readContentData;
         WOLog ( WO_INFO, "content_buffer_size: %d",req->content_buffer_size );
         if (req->content_buffer_size == 0) {
            prepareAndSendErrorResponse(ALLOCATION_FAILURE, HTTP_SERVER_ERROR);
            WOFREE(url);
            break;
         }
         if (readContentData(req, req->content, req->content_buffer_size, 1) == -1) {
            prepareAndSendErrorResponse(WOURLstrerror(WOURLInvalidPostData), HTTP_BAD_REQUEST);
            WOFREE(url);
            break;
         }
      }

      /* Always get the query string */
      qs = FCGX_GetParam("QUERY_STRING", hdrp);
      if (qs) {
         qs_len = strlen(qs);
      } else {
         qs_len = 0;
      }

      if (qs_len > 0) {
         wc.queryString.start = qs;
         wc.queryString.length = qs_len;
         WOLog(WO_INFO,"<FastCGI> new request with Query String: %s", qs);
      }

      /*
       *	message the application & collect the response
       */
      resp = tr_handleRequest(req, url, &wc, FCGX_GetParam(CGI_SERVER_PROTOCOL, hdrp), documentRoot());

      if (resp != NULL) {
         sendResponse(resp);
         resp_free(resp);		/* dump the response */
      }

      WOFREE(url);
      req_free(req);

#if defined(FINDLEAKS)
      showleaks();
#endif
    }

#ifdef	PROFILE
    }
#endif


    st_free(options);
    WOLog( WO_INFO,"<FastCGI> process exiting" );

    return exit_status;
}
Beispiel #9
0
int main(const int argc, const char* argv[])
{
  const char* prgm_path = FCGX_GetParam("PROGRAM_PATH", environ);
  if(!prgm_path) {
    cerr << "Unable to find program, please ensure the 'PROGRAM_PATH' variable has been set correctly." << endl;
    exit(1);
  }
  
  // load program
  srand(time(NULL)); rand();
  Loader loader(prgm_path);
  loader.Load();

  // ignore web applications
  if(!loader.IsWeb()) {
    cerr << "Please recompile the code to be a web application." << endl;
    exit(1);
  }
  
#ifdef _TIMING
  clock_t start = clock();
#endif
  
  // locate starting class and method
  StackMethod* mthd = loader.GetStartMethod();
  if(!mthd) {
    cerr << "Unable to locate the 'Request(args)' function." << endl;
    exit(1);
  }
  
#ifdef _DEBUG
  cerr << "### Loaded method: " << mthd->GetName() << " ###" << endl;
#endif
  
  Runtime::StackInterpreter intpr(Loader::GetProgram());
  
  // go into accept loop...
  FCGX_Stream*in;
  FCGX_Stream* out;
  FCGX_Stream* err;
  FCGX_ParamArray envp;
  
  while(mthd && (FCGX_Accept(&in, &out, &err, &envp) >= 0)) {    
    // execute method
    long* op_stack = new long[CALC_STACK_SIZE];
    long* stack_pos = new long;
    
    // create request
    long* req_obj = MemoryManager::Instance()->AllocateObject("FastCgi.Request", 
							      op_stack, *stack_pos, false);
    if(req_obj) {
      req_obj[0] = (long)in;
      req_obj[1] = (long)envp;
      
      // create response
      long* res_obj = MemoryManager::Instance()->AllocateObject("FastCgi.Response", 
								op_stack, *stack_pos, false);
      if(res_obj) { 	
	res_obj[0] = (long)out;
	res_obj[1] = (long)err;
	
	// set calling parameters
	op_stack[0] = (long)req_obj;
	op_stack[1] = (long)res_obj;
	*stack_pos = 2;
 	
	// execute method
	intpr.Execute((long*)op_stack, (long*)stack_pos, 0, mthd, NULL, false);
      }
      else {
	cerr << ">>> DLL call: Unable to allocate object FastCgi.Response <<" << endl;
	// TODO: error
	return 1;
      }
    }
    else {
      cerr << ">>> DLL call: Unable to allocate object FastCgi.Request <<<" << endl;
      // TODO: error
      return 1;
    }
    
#ifdef _DEBUG
    cout << "# final stack: pos=" << (*stack_pos) << " #" << endl;
    if((*stack_pos) > 0) {
      for(int i = 0; i < (*stack_pos); i++) {
	cout << "dump: value=" << (void*)(*stack_pos) << endl;
      } 
    }
#endif
    
    // clean up
    delete[] op_stack;
    op_stack = NULL;

    delete stack_pos;
    stack_pos = NULL;
    
#ifdef _DEBUG
    PrintEnv(out, "Request environment", envp);
    PrintEnv(out, "Initial environment", environ);
#endif
  }
  
  return 0;
}