httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Randy Terbush <ra...@zyzzyva.com>
Subject Re: ScriptAlias-like extensions for perl etc
Date Fri, 26 Apr 1996 15:54:35 GMT
>  
> > Rob> CGIBinary /usr/local/bin/perl pl
> > Rob> DefaultBinary /usr/local/bin/perl
> > 
> > Rob> or something along those lines.
> > 
> > Rob> thoughts?
> > 
> > I don't have any thoughts on the specific change you suggest.  I'm
> > just curious to know if you tried using mod_perl.  I wonder what the
> > speed improvement there would be like.
> 
> Me too. I didn't get an answer (that I saw) when I asked for a pointer
> a couple of days back. I went to the author's pages but didn't find it,
> and Alta Vista's update-to-date'ness has slipped a bit so, no luck there
> either.
> 
> > I realize this isn't a generic solution.  But if you do write a lot of
> > CGIs in Perl, it might be a pretty good solution.
> 
> All my CGI is in perl :-)   and the scripts are pretty big 1000-2000
> lines each. One thing I already do is pre-process the "requires" lines
> of my scripts so that the stuff in the script dirs already has the
> require'd modules embedded in the main file... saves me ~10 file open/reads
> per CGI call.
> 

Attached below is a patch that was submitted for mod_perl. I don't
know that this is the one that is being discussed or not.


From: aas@sn.no
Subject: Embeding perl in the Apache httpd

This patch is relative to apache-1.0.3.

You should add a line like this:

  AddType httpd/perl .pl

to your server configuration files to activate the perl mime type.

Example of a simple perl script that works with this configuration is:

  # These two lines are always needed to set up the envirionment
  Apache->bootstrap;
  @request_recPtr::ISA = 'Apache';

  $req->set_content_type("text/html");
  $req->send_http_header;

  $req->write_client_block("<h1>This is a stupid test</h1>\n");




Index: www/apache/src/Configuration
diff -c www/apache/src/Configuration:1.1.1.1 www/apache/src/Configuration:1.2
*** www/apache/src/Configuration:1.1.1.1	Mon Mar 25 10:58:52 1996
--- www/apache/src/Configuration	Mon Mar 25 13:21:50 1996
***************
*** 166,169 ****
  
  # Module config_log_module mod_log_config.o
  
! 
--- 166,169 ----
  
  # Module config_log_module mod_log_config.o
  
! Module perl_module  mod_perl.o
Index: www/apache/src/Makefile
diff -c www/apache/src/Makefile:1.1.1.1 www/apache/src/Makefile:1.2
*** www/apache/src/Makefile:1.1.1.1	Mon Mar 25 10:58:56 1996
--- www/apache/src/Makefile	Mon Mar 25 13:22:05 1996
***************
*** 1,104 ****
! # Makefile for the Apache httpd. 
! 
! # For normal machines with ANSI compilers
! # CC= cc
! # For Suns or other non-ANSI platforms. Please make sure your gcc is
! # 2.0 or later, as 1.40 seems to create bad code for the Sun 4.
! CC= gcc -Wall
! 
! # CFLAGS, compile flags.
! 
! # If you want no reverse hostname resolution, use -DMINIMAL_DNS
! # If you want to have more secure hostname resolution at the cost of some 
! # performance, use -DMAXIMUM_DNS
! 
! #CFLAGS= -O2 
! CFLAGS= -g 
! 
! # Modules precompiled with the server.  Note that these must also be
! # in the list in modules.c in order to be active.
! 
! MODULES = mod_mime.o mod_access.o mod_alias.o mod_cgi.o mod_include.o \
! 	mod_dir.o mod_auth.o mod_auth_dbm.o mod_negotiation.o mod_userdir.o \
! 	mod_log_common.o mod_asis.o
! 
! # Place here any extra libraries you may need to link to. 
! # If you want DBM auth, -lndbm is commonly required.
! EXTRA_LIBS=
! 
! # AUX_CFLAGS are system-specific control flags.
! # NOTE: IF YOU DO NOT CHOOSE ONE OF THESE, EDIT httpd.h AND CHOOSE
! # SETTINGS FOR THE SYSTEM FLAGS. IF YOU DON'T, BAD THINGS WILL HAPPEN.
! 
! # For SunOS 4
  AUX_CFLAGS= -DSUNOS4
! # For Solaris 2.
! # AUX_CFLAGS= -DSOLARIS2 -DFCNTL_SERIALIZED_ACCEPT
! # EXTRA_LIBS= -lsocket -lnsl
! # For SGI IRIX. Use the EXTRA_LIBS line if you're using NIS and want
! # user-supported directories
! #AUX_CFLAGS= -DIRIX -DFCNTL_SERIALIZED_ACCEPT
! #EXTRA_LIBS= -lsun
! # For HP-UX
! #AUX_CFLAGS= -DHPUX
! # For AIX
! #AUX_CFLAGS= -DAIX -U__STR__
! # For Ultrix
! #AUX_CFLAGS= -DULTRIX
! # For DEC OSF/1
! #AUX_CFLAGS= -DOSF1
! # For NeXT
! #AUX_CFLAGS= -DNEXT
! # For Sequent
! #AUX_CFLAGS= -DSEQUENT
! # For Linux -m486 ONLY IF YOU HAVE 486 BINARY SUPPORT IN KERNEL
! #AUX_CFLAGS= -DLINUX -DFCNTL_SERIALIZED_ACCEPT
! # For A/UX
! #AUX_CFLAGS= -DAUX
! #EXTRA_LIBS= -lbsd -lposix -s
! # For SCO ODT
! # libcrypt_i available from sosco.sco.com, files /SLS/lng225b.Z and
! # /SLS/lng225b.ltr.Z
! #AUX_CFLAGS= -DSCO
! #EXTRA_LIBS= -lPW -lsocket -lmalloc -lcrypt_i
! # For SVR4
! #AUX_CFLAGS= -DSVR4
! #EXTRA_LIBS= -lsocket -lnsl -lc
! # For Amdahl UTS 2.1
! # -Xa enables ANSI mode, -eft is expanded types
! #AUX_CFLAGS= -Xa -eft -DUTS21
! #EXTRA_LIBS= -lsocket -lbsd -la
! # For HP/Apollo Domain/OS
! #AUX_CFLAGS= -DAPOLLO
! # For NetBSD/FreeBSD/BSDI 2.x
! # -m486 only if you are running on Intel 486/586
! #AUX_CFLAGS= -m486
! # BSDI doesn't need -lcrypt
! #EXTRA_LIBS= -lcrypt
! 
! # Place here any flags you may need upon linking, such as a flag to
! # prevent dynamic linking (if desired)
! LFLAGS= 
  
! # You shouldn't have to edit anything else.
  
  OBJS= alloc.o http_main.o http_core.o http_config.o http_request.o \
!   http_log.o http_protocol.o rfc931.o util.o util_script.o modules.o $(MODULES)
  
  .c.o:
  	$(CC) -c $(CFLAGS) $(AUX_CFLAGS) $<
  
  all: httpd
  
  httpd: $(OBJS)
! 	$(CC) $(LFLAGS) -o httpd $(OBJS) $(EXTRA_LIBS)
  
  clean:
  	rm -f httpd $(OBJS) *pure*
  
  #Dependencies
  #Core code
! $(OBJS): Makefile httpd.h alloc.h conf.h
  
  http_config.o http_core.o http_main.o util.o: http_conf_globals.h
  http_config.o http_core.o http_main.o: http_config.h http_log.h
--- 1,65 ----
! # Makefile automatically generated from Makefile.tmpl
! # and configuration file by Apache config script. 
! # Hand-edited changes will be lost if the config script
! # is re-run.
! CC= gcc
! CFLAGS= -O2
! LFLAGS=
! EXTRA_LIBS=-L/local/perl/lib/sun4-sunos/5.002/CORE -lperl -ldbm -ldl -lm -lc -lposix
  AUX_CFLAGS= -DSUNOS4
! MODULES=\
!   mod_mime.o \
!   mod_access.o \
!   mod_auth.o \
!   mod_negotiation.o \
!   mod_include.o \
!   mod_dir.o \
!   mod_cgi.o \
!   mod_userdir.o \
!   mod_alias.o \
!   mod_log_common.o \
!   mod_asis.o \
!   mod_imap.o \
!   mod_perl.o
  
! # Apache makefile template (well, suffix).
! 
! # This is combined with the information in the "Configuration" file
! # by the configure script to make the actual Makefile.
  
  OBJS= alloc.o http_main.o http_core.o http_config.o http_request.o \
!   http_log.o http_protocol.o rfc931.o util.o util_script.o modules.o $(MODULES)  perl_glue.o
  
  .c.o:
  	$(CC) -c $(CFLAGS) $(AUX_CFLAGS) $<
  
  all: httpd
  
+ mod_perl.o: mod_perl.c
+ 	$(CC) -I/local/perl/lib/sun4-sunos/5.002/CORE -I/usr/local/include -c $(CFLAGS) $(AUX_CFLAGS)
$<
+ 
+ perl_glue.o: perl_glue.c
+ 	$(CC) -I/local/perl/lib/sun4-sunos/5.002/CORE -I/usr/local/include -c $(CFLAGS) $(AUX_CFLAGS)
$<
+ 
+ perl_glue.c: perl_glue.xs
+ 	perl /local/perl/lib/ExtUtils/xsubpp -typemap /local/perl/lib/ExtUtils/typemap perl_glue.xs
>perl_glue.c
+ 
  httpd: $(OBJS)
! 	$(CC) $(LFLAGS) $(AUX_LFLAGS) -o httpd $(OBJS) $(EXTRA_LIBS) $(AUX_LIBS)
  
  clean:
  	rm -f httpd $(OBJS) *pure*
  
+ dist.tar: 
+ 	# Assure a semi-sensible configuration going out...
+ 	cp Makefile.orig Makefile
+ 	cp modules.c.orig modules.c
+ 	tar cvf dist.tar README INSTALL CHANGES TODO API.html \
+ 		Configuration Configure Makefile.tmpl Makefile *.h *.c
+ 
  #Dependencies
  #Core code
! $(OBJS): httpd.h alloc.h conf.h
  
  http_config.o http_core.o http_main.o util.o: http_conf_globals.h
  http_config.o http_core.o http_main.o: http_config.h http_log.h
Index: www/apache/src/conf.h
diff -c www/apache/src/conf.h:1.1.1.1 www/apache/src/conf.h:1.2
*** www/apache/src/conf.h:1.1.1.1	Mon Mar 25 10:58:52 1996
--- www/apache/src/conf.h	Mon Mar 25 13:14:19 1996
***************
*** 51,56 ****
--- 51,59 ----
   *
   */
  
+ #define die   apache_die
+ #define usage apacha_usage
+ 
  
  /*
   * conf.h: system-dependant #defines and includes...
***************
*** 66,72 ****
  #define HAVE_RESOURCE 1
  #undef NO_KILLPG
  #undef NO_SETSID
! char *crypt(char *pw, char *salt);
  #define JMP_BUF sigjmp_buf
  #define NEED_STRERROR
  #include <sys/time.h>     
--- 69,75 ----
  #define HAVE_RESOURCE 1
  #undef NO_KILLPG
  #undef NO_SETSID
! char *crypt(const char *pw, const char *salt);
  #define JMP_BUF sigjmp_buf
  #define NEED_STRERROR
  #include <sys/time.h>     
Index: www/apache/src/mod_perl.c
diff -c /dev/null www/apache/src/mod_perl.c:1.1
*** /dev/null	Mon Mar 25 13:24:42 1996
--- www/apache/src/mod_perl.c	Mon Mar 25 13:13:35 1996
***************
*** 0 ****
--- 1,212 ----
+ /* ====================================================================
+  * Copyright (c) 1995 The Apache Group.  All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  *
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer. 
+  *
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in
+  *    the documentation and/or other materials provided with the
+  *    distribution.
+  *
+  * 3. All advertising materials mentioning features or use of this
+  *    software must display the following acknowledgment:
+  *    "This product includes software developed by the Apache Group
+  *    for use in the Apache HTTP server project (http://www.apache.org/)."
+  *
+  * 4. The names "Apache Server" and "Apache Group" must not be used to
+  *    endorse or promote products derived from this software without
+  *    prior written permission.
+  *
+  * 5. Redistributions of any form whatsoever must retain the following
+  *    acknowledgment:
+  *    "This product includes software developed by the Apache Group
+  *    for use in the Apache HTTP server project (http://www.apache.org/)."
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+  * OF THE POSSIBILITY OF SUCH DAMAGE.
+  * ====================================================================
+  *
+  * This software consists of voluntary contributions made by many
+  * individuals on behalf of the Apache Group and was originally based
+  * on public domain software written at the National Center for
+  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+  * For more information on the Apache Group and the Apache HTTP server
+  * project, please see <http://www.apache.org/>.
+  *
+  */
+ 
+ /* This module embeds a perl interpreter within the Apache httpd. Files
+  * classfied as "httpd/perl" are interpreted as a perl script by the
+  * server.  The apache C API is directly available to the perl script
+  * as through the perl_glue.xs routines.
+  *
+  * This should be much faster than what you can achieved with CGI
+  * scripts and you also has more direct contol over the connection
+  * back to the client.
+  */
+ 
+ #include <EXTERN.h>
+ #include <perl.h>
+ 
+ #include "httpd.h"
+ #include "http_config.h"
+ #include "http_protocol.h"
+ #include "http_log.h"
+ #include "http_main.h"
+ 
+ void boot_Apache _((CV* cv));
+ 
+ static void xs_init()
+ {
+   newXS("Apache::bootstrap", boot_Apache, __FILE__);
+ }
+ 
+ 
+ int perl_handler(request_rec *r)
+ {
+   char *argv[] = { "", r->filename, NULL };
+   int status;
+ 
+   PerlInterpreter *perl = perl_alloc();
+ 
+ 
+   /* If the method is POST and the Content-Type is 
+    * application/x-www-form-urlencoded, then we read the data here
+    * so that the perl script does not have to do it.
+    */
+ 
+   if (r->method_number == M_POST) {
+     char *ct = table_get(r->headers_in, "Content-Type");
+     if (ct && strEQ(ct, "application/x-www-form-urlencoded")) {
+       char *lenp = table_get(r->headers_in, "Content-Length");
+       long len = lenp ? atoi(lenp) : 0;
+       if (len) {
+ 	/* We read the data */
+ 	char *content = (char*)palloc(r->pool, len+1);
+ 	long n = read_client_block(r, content, len);
+ 	if (n != len) {
+ 	  log_reason("Can't read request form content", r->filename, r);
+ 	  return BAD_REQUEST;
+ 	}
+ 	content[len] = '\0';
+ 	r->args = content;
+ 	/* Make this hint to the script so it does not try to read also */
+ 	table_set(r->headers_in, "Content-Length", "0");
+       }
+     }
+   }
+ 
+   perl_construct(perl);
+   perl_parse(perl, xs_init, 2, argv, NULL);
+ 
+   /* Make a pointer to the request structure available as $req */
+   sv_setref_pv(perl_get_sv("req", TRUE), "request_recPtr", (void*)r);
+ 
+   /* Make basic information available as perl variables */
+   sv_setpv(perl_get_sv("method",      TRUE), r->method);
+   sv_setpv(perl_get_sv("protocol",    TRUE), r->protocol);
+   sv_setpv(perl_get_sv("uri",         TRUE), r->uri);
+   sv_setpv(perl_get_sv("path_into",   TRUE), r->path_info);
+   sv_setpv(perl_get_sv("args",        TRUE), r->args);
+ 
+   /* Parse the r->args a form if the string contains an unencoded '=' */
+   if (r->args && strchr(r->args, '=')) {
+     /* This parsing destroys the value of the r->args string, but since
+      * we don't need it any more we don't bother with a pstrdup().
+      */
+     AV *av = perl_get_av("args", TRUE);
+     char *a = r->args;
+     char *end = a;
+     char *k, *v;
+     while (*end) {
+       a = end;
+       /* find next '&' character */
+       while (*end && *end != '&')
+ 	end++;
+ 
+       if (*end)
+ 	*end++ = '\0';
+ 
+       /* split on '=' */
+       k = a;
+       v = a;
+       while (*v && *v != '=')
+ 	v++;
+       if (*v)
+ 	*v++ = '\0';
+ 
+       /* Then we unescape the 'keyword' and the 'value'. */
+       unescape_url(k);
+       unescape_url(v);
+ 
+       /* XXX: An unescaped %00 might have terminated the string before
+        * we wanted, but there is not easy way to obtain the real unescaped
+        * string length so we ignore this problem for now.
+        */
+       av_push(av, newSVpv(k, 0));
+       av_push(av, newSVpv(v, 0));
+     }
+   }
+ 
+   /* Make the r->headers_in available as %headers_in */
+   {
+     array_header *hdrs_arr = table_elts (r->headers_in);
+     table_entry *hdrs = (table_entry *)hdrs_arr->elts;
+     int i;
+     HV *in = perl_get_hv("headers_in", TRUE);
+     for (i = 0; i < hdrs_arr->nelts; ++i) {
+       char *key = hdrs[i].key;
+       if (!key) continue;
+       hv_store(in, key, strlen(key), newSVpv(hdrs[i].val, 0), 0);
+     }
+   }
+ 
+   perl_run(perl);
+ 
+   status = statusvalue;
+   if (status == 65535)  /* this is what we get by exit(-1) in perl */
+     status = DECLINED;
+ 
+   perl_destruct(perl);
+   perl_free(perl);
+ 
+   return status;
+ }
+ 
+ handler_rec perl_handlers[] = {
+ { "httpd/perl", perl_handler },
+ { NULL }
+ };
+ 
+ module perl_module = {
+    STANDARD_MODULE_STUFF,
+    NULL,			/* initializer */
+    NULL,			/* create per-directory config structure */
+    NULL,			/* merge per-directory config structures */
+    NULL,			/* create per-server config structure */
+    NULL,			/* merge per-server config structures */
+    NULL,			/* command table */
+    perl_handlers,		/* handlers */
+    NULL,			/* translate_handler */
+    NULL,			/* check_user_id */
+    NULL,			/* check auth */
+    NULL,			/* check access */
+    NULL,			/* type_checker */
+    NULL,			/* pre-run fixups */
+    NULL				/* logger */
+ };
Index: www/apache/src/modules.c
diff -c www/apache/src/modules.c:1.1.1.1 www/apache/src/modules.c:1.2
*** www/apache/src/modules.c:1.1.1.1	Mon Mar 25 10:58:52 1996
--- www/apache/src/modules.c	Mon Mar 25 13:21:03 1996
***************
*** 18,23 ****
--- 18,24 ----
  extern module common_log_module;
  extern module asis_module;
  extern module imap_module;
+ extern module perl_module;
  
  module *prelinked_modules[] = {
    &core_module,
***************
*** 33,37 ****
--- 34,39 ----
    &common_log_module,
    &asis_module,
    &imap_module,
+   &perl_module,
    NULL
  };
Index: www/apache/src/perl_glue.xs
diff -c /dev/null www/apache/src/perl_glue.xs:1.1
*** /dev/null	Mon Mar 25 13:24:44 1996
--- www/apache/src/perl_glue.xs	Mon Mar 25 13:13:34 1996
***************
*** 0 ****
--- 1,129 ----
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ #include "EXTERN.h"
+ #include "perl.h"
+ #include "XSUB.h"
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ #include "httpd.h"
+ #include "http_config.h"
+ #include "http_protocol.h"
+ #include "http_log.h"
+ #include "http_main.h"
+ 
+ MODULE = Apache  PACKAGE = Apache
+ 
+ PROTOTYPES: ENABLE
+ 
+ void
+ send_http_header(req)
+ 	request_rec *req
+ 
+ 
+ # Beware that we have changes the order of the arguments for this
+ # function.
+ 
+ int
+ send_fd(req, f)
+ 	request_rec *req
+ 	FILE *f
+ 	CODE:
+ 	RETVAL = send_fd(f, req);
+ 
+ void
+ set_content_type(r, type)
+ 	request_rec *r
+ 	char *type
+ 	CODE:
+ 	r->content_type = pstrdup(r->pool, type);
+ 
+ void
+ set_content_encoding(r, encoding)
+ 	request_rec *r
+ 	char *encoding
+ 	CODE:
+ 	r->content_encoding = pstrdup(r->pool, encoding);
+ 
+ void
+ set_content_language(r, lang)
+ 	request_rec *r
+ 	char *lang
+ 	CODE:
+ 	r->content_language = pstrdup(r->pool, lang);
+ 
+ void
+ set_status(r, status)
+ 	request_rec *r
+ 	int status
+ 	CODE:
+ 	r->status = status;
+ 
+ void
+ set_status_line(r, line)
+ 	request_rec *r
+ 	char *line
+ 	CODE:
+ 	r->status_line = pstrdup(r->pool, line);
+ 
+ void
+ set_header_out(r, key, val)
+ 	request_rec *r
+ 	char *key
+ 	char *val
+ 	CODE:
+ 	table_set(r->headers_out, key, val);
+ 
+ void
+ set_err_headers_out(r, key, val)
+ 	request_rec *r
+ 	char *key
+ 	char *val
+ 	CODE:
+ 	table_set(r->err_headers_out, key, val);
+ 
+ void
+ set_no_cache(r, val)
+ 	request_rec *r
+ 	int val
+ 	CODE:
+ 	r->no_cache = val;
+ 	
+ long
+ read_client_block(r, buffer, bufsiz)
+ 	request_rec *r
+ 	char	    *buffer
+ 	int 	     bufsiz
+ 	OUTPUT:
+ 	buffer
+ 
+ long
+ write_client_block(r, buffer)
+ 	request_rec* r
+ 	char *       buffer = NO_INIT
+ 	PREINIT:
+ 	int size;
+ 	CODE:
+ 	buffer = (char *)SvPV(ST(1), size);
+ 	RETVAL = fwrite(buffer, sizeof(char), size, r->connection->client);
+ 
+ 
+ # Beware, we have changed the order of the arguments for the log_reason()
+ # funtion.
+ 
+ void
+ log_reason(r, reason, filename)
+ 	request_rec*	r
+ 	char *	reason
+ 	char *	filename
+ 	CODE:
+ 	log_reason(reason, filename, r);
+ 
+ void
+ log_error(r, mess)
+ 	request_rec*	r
+ 	char *		mess
+ 	CODE:
+ 	log_error(mess, r->server);
Index: www/apache/src/typemap
diff -c /dev/null www/apache/src/typemap:1.1
*** /dev/null	Mon Mar 25 13:24:44 1996
--- www/apache/src/typemap	Mon Mar 25 13:13:33 1996
***************
*** 0 ****
--- 1,2 ----
+ TYPEMAP
+ request_rec *	T_PTROBJ




Mime
View raw message