+static int suphp_source_handler(request_rec *r) {
+ suphp_conf *conf;
+ int rv;
+ pool *p;
+ int fd;
+ BUFF *script_in, *script_out, *script_err;
+ char buffer[HUGE_STRING_LEN];
+
+ if (strcmp(r->method, "GET")) {
+ return DECLINED;
+ }
+
+ conf = ap_get_module_config(r->server->module_config, &suphp_module);
+ if (conf->php_path == NULL) {
+ return DECLINED;
+ }
+
+ p = r->main ? r->main->pool : r->pool;
+
+ fd = open(r->filename, O_NOCTTY, O_RDONLY);
+ if (fd != -1) {
+ close(fd);
+ } else if (errno == EACCES) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "access to %s denied",
+ r->filename);
+ return HTTP_FORBIDDEN;
+ } else if (errno == ENOENT || errno == ENOTDIR) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "File does not exist: %s",
+ r->filename);
+ return HTTP_NOT_FOUND;
+ } else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "could open file: %s",
+ r->filename);
+ return HTTP_NOT_FOUND;
+ }
+
+ /* Fork child process */
+
+ if (!ap_bspawn_child(p, suphp_source_child, (void *) r, kill_after_timeout,
+ &script_in, &script_out, &script_err)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "couldn't spawn child process for: %s", r->filename);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ /* Read request body */
+
+ if (ap_should_client_block(r)) {
+ char buffer[HUGE_STRING_LEN];
+ int len_read;
+
+ ap_hard_timeout("reading request body", r);
+
+ while (ap_get_client_block(r, buffer, HUGE_STRING_LEN) > 0) {
+ ap_reset_timeout(r);
+ // Ignore input
+ }
+
+ ap_bflush(script_in);
+ ap_kill_timeout(r);
+ }
+
+ ap_bclose(script_in);
+
+ /* Transfer output from PHP to client */
+
+ if (script_out) {
+ /* Output headers and body */
+
+ r->content_type = "text/html";
+ ap_send_http_header(r);
+ if (!r->header_only) {
+ ap_send_fb(script_out, r);
+ }
+ ap_bclose(script_out);
+ /* Errors have already been logged by child */
+ ap_bclose(script_err);
+ }
+
+ return OK;
+
+}
+
+