CGI-SpeedyCGI

 view release on metacpan or  search on metacpan

src/mod_speedycgi.c  view on Meta::CPAN

    prog_argv[0] = "";
    prog_argv[1] = NULL;
    speedy_opt_init(
	(const char * const *)prog_argv, (const char * const *)environ
    );
    speedy_opt_save();
}

/****************************************************************
 *
 * Actual CGI handling...
 */


static int cgi_handler(request_rec *r)
{
    int retval, nph, socks[NUMFDS];
    BUFF *script_io, *script_err;
    int is_included = !strcmp(r->protocol, "INCLUDED");
    char *argv0, *script_argv[2];
    SpeedyBuf buf;

    /* May have been a while since we ran last */
    speedy_util_time_invalidate();

    /* Restore our original option values */
    speedy_opt_restore();

    /* Copy request_rec to global */
    global_r = r;

    if (r->method_number == M_OPTIONS) {
	/* 99 out of 100 CGI scripts, this is all they support */
	r->allowed |= (1 << M_GET);
	r->allowed |= (1 << M_POST);
	return DECLINED;
    }

    if ((argv0 = strrchr(r->filename, '/')) != NULL)
	argv0++;
    else
	argv0 = r->filename;

    nph = !(strncmp(argv0, "nph-", 4));

    if (!(ap_allow_options(r) & OPT_EXECCGI))
	return log_scripterror(r, FORBIDDEN, APLOG_NOERRNO,
			       "Options ExecCGI is off in this directory");
    if (nph && is_included)
	return log_scripterror(r, FORBIDDEN, APLOG_NOERRNO,
			       "attempt to include NPH CGI script");

#if defined(OS2) || defined(WIN32)
    /* Allow for cgi files without the .EXE extension on them under OS/2 */
    if (r->finfo.st_mode == 0) {
	struct stat statbuf;
	char *newfile;

	newfile = ap_pstrcat(r->pool, r->filename, ".EXE", NULL);

	if ((stat(newfile, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode))) {
	    return log_scripterror(r, NOT_FOUND, 0,
				   "script not found or unable to stat");
	} else {
	    r->filename = newfile;
	}
    }
#else
    if (r->finfo.st_mode == 0)
	return log_scripterror(r, NOT_FOUND, APLOG_NOERRNO,
			       "script not found or unable to stat");
#endif
    if (S_ISDIR(r->finfo.st_mode))
	return log_scripterror(r, FORBIDDEN, APLOG_NOERRNO,
			       "attempt to invoke directory as script");
    if (!ap_suexec_enabled) {
	if (!ap_can_exec(&r->finfo))
	    return log_scripterror(r, FORBIDDEN, APLOG_NOERRNO,
				   "file permissions deny server execution");
    }

    if ((retval = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)))
	return retval;

    /* Put the CGI environment vars into r */
    ap_add_common_vars(r);
    ap_add_cgi_vars(r);

#ifdef CHARSET_EBCDIC
    /* Is the generated/included output ALWAYS in text/ebcdic format? */
    /* Or must we check the Content-Type first? */
    ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
#endif /*CHARSET_EBCDIC*/

    /* Set script filename */
    script_argv[0] = r->filename;
    script_argv[1] = NULL;
    speedy_opt_set_script_argv((const char * const *)script_argv);

    /* Allocate argsbuffer and fill in with the env/argv data to send */
    speedy_frontend_mkenv(
	(const char * const *)ap_create_environment(r->pool, r->subprocess_env),
	(const char * const *)script_argv,
	HUGE_STRING_LEN, &buf, 1
    );

    /* Connect up to a speedycgi backend, creating a new one if necessary */
    if (!speedy_frontend_connect(socks, NULL)) {
	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
	    "couldn't spawn child process: %s", r->filename);
	return HTTP_INTERNAL_SERVER_ERROR;
    }

    /*
     * Open up buffered files -- "s" contains stdin/stdout, "e" is stderr
     */
    /* stdin/stdout for script */
    script_io = ap_bcreate(r->pool, B_RDWR|B_SOCKET);
    ap_note_cleanups_for_fd(r->pool, socks[0]);
    ap_note_cleanups_for_fd(r->pool, socks[1]);
    ap_bpushfd(script_io, socks[1], socks[0]);



( run in 0.625 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )