pier 01/05/10 14:12:36 Modified: connectors/lib Makefile.in wa_main.c wa_request.c Added: connectors/lib pr_warp.c Log: The WARP provider. Revision Changes Path 1.8 +2 -2 jakarta-tomcat-4.0/connectors/lib/Makefile.in Index: Makefile.in =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/connectors/lib/Makefile.in,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- Makefile.in 2001/05/10 15:52:24 1.7 +++ Makefile.in 2001/05/10 21:12:31 1.8 @@ -56,12 +56,12 @@ # ========================================================================= # # @author Pier Fumagalli <mailto:[EMAIL PROTECTED]> -# @version $Id: Makefile.in,v 1.7 2001/05/10 15:52:24 pier Exp $ +# @version $Id: Makefile.in,v 1.8 2001/05/10 21:12:31 pier Exp $ include ../Makedefs OBJS = wa_main.o wa_config.o wa_request.o -PROVS = pr_info.o # pr_warp.o pr_jni.o +PROVS = pr_info.o pr_warp.o # pr_jni.o LIB = libwebapp.a 1.5 +23 -6 jakarta-tomcat-4.0/connectors/lib/wa_main.c Index: wa_main.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/connectors/lib/wa_main.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- wa_main.c 2001/05/10 15:53:58 1.4 +++ wa_main.c 2001/05/10 21:12:32 1.5 @@ -55,7 +55,7 @@ * * * ========================================================================= */ -/* @version $Id: wa_main.c,v 1.4 2001/05/10 15:53:58 pier Exp $ */ +/* @version $Id: wa_main.c,v 1.5 2001/05/10 21:12:32 pier Exp $ */ #include <wa.h> /* The current APR memory pool. */ @@ -65,7 +65,7 @@ /* The list of all compiled in providers */ wa_provider *wa_providers[] = { &wa_provider_info, - //&wa_provider_warp, + &wa_provider_warp, //&wa_provider_jni, NULL, }; @@ -95,7 +95,7 @@ } /* Done */ - wa_debug(WA_MARK,"WebApp Library initialized (PID=%d)",getpid()); + wa_debug(WA_MARK,"WebApp Library initialized"); return(NULL); } @@ -105,7 +105,7 @@ while(wa_providers[x]!=NULL) wa_providers[x++]->startup(); - wa_debug(WA_MARK,"WebApp Library started (PID=%d)",getpid()); + wa_debug(WA_MARK,"WebApp Library started"); } /* Clean up the WebApp Library. */ @@ -124,7 +124,7 @@ wa_configuration=NULL; apr_terminate(); - wa_debug(WA_MARK,"WebApp Library destroyed (PID=%d)",getpid()); + wa_debug(WA_MARK,"WebApp Library destroyed"); } /* Deploy a web-application. */ @@ -194,10 +194,27 @@ at=apr_time_now(); apr_ctime(st, at); - fprintf(stderr,"[%s] (%s:%d) ",st,f,l); va_start(ap,fmt); + fprintf(stderr,"[%s] %d (%s:%d) ",st,getpid(),f,l); vfprintf(stderr,fmt,ap); + fprintf(stderr,"\n"); + fflush(stderr); va_end(ap); +} + + +/* Log an error message. */ +void wa_log(const char *f, const int l, const char *fmt, ...) { + apr_time_t at; + char st[128]; + va_list ap; + + at=apr_time_now(); + apr_ctime(st, at); + va_start(ap,fmt); + fprintf(stderr,"[%s] %d (%s:%d) ",st,getpid(),f,l); + vfprintf(stderr,fmt,ap); fprintf(stderr,"\n"); fflush(stderr); + va_end(ap); } 1.9 +7 -4 jakarta-tomcat-4.0/connectors/lib/wa_request.c Index: wa_request.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/connectors/lib/wa_request.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- wa_request.c 2001/05/10 15:55:16 1.8 +++ wa_request.c 2001/05/10 21:12:33 1.9 @@ -55,7 +55,7 @@ * * * ========================================================================= */ -/* @version $Id: wa_request.c,v 1.8 2001/05/10 15:55:16 pier Exp $ */ +/* @version $Id: wa_request.c,v 1.9 2001/05/10 21:12:33 pier Exp $ */ #include <wa.h> /* Allocate a new request structure. */ @@ -131,7 +131,8 @@ } /* Dump an error response */ -int wa_rerror(wa_request *r, int s, const char *fmt, ...) { +int wa_rerror(const char *file, const int line, wa_request *r, int s, + const char *fmt, ...) { va_list ap; char buf[1024]; @@ -149,11 +150,13 @@ wa_rprintf(r,"\n\n"); wa_rprintf(r,"<html>\n"); wa_rprintf(r," <head>\n"); - wa_rprintf(r," <title>WebApp: %d Error</title>",s); + wa_rprintf(r," <title>WebApp: %d Error (File: %s Line: %d)</title>",s, + file,line); wa_rprintf(r," </head>\n"); wa_rprintf(r," <body>\n"); wa_rprintf(r," <div align=\"center\">"); - wa_rprintf(r," <h1>WebApp: %d Error</h1>",s); + wa_rprintf(r," <h1>WebApp: %d Error (File: %s Line: %d)</h1>",s, + file,line); wa_rprintf(r," </div>\n"); wa_rprintf(r," <hr>\n"); wa_rprintf(r," %s\n",buf); 1.1 jakarta-tomcat-4.0/connectors/lib/pr_warp.c Index: pr_warp.c =================================================================== /* ========================================================================= * * * * The Apache Software License, Version 1.1 * * * * Copyright (c) 1999-2001 The Apache Software Foundation. * * All rights reserved. * * * * ========================================================================= * * * * Redistribution and use in source and binary forms, with or without modi- * * fication, are permitted provided that the following conditions are met: * * * * 1. Redistributions of source code must retain the above copyright notice * * 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. The end-user documentation included with the redistribution, if any, * * must include the following acknowlegement: * * * * "This product includes software developed by the Apache Software * * Foundation <http://www.apache.org/>." * * * * Alternately, this acknowlegement may appear in the software itself, if * * and wherever such third-party acknowlegements normally appear. * * * * 4. The names "The Jakarta Project", "WebApp", and "Apache Software * * Foundation" must not be used to endorse or promote products derived * * from this software without prior written permission. For written * * permission, please contact <[EMAIL PROTECTED]>. * * * * 5. Products derived from this software may not be called "Apache" nor may * * "Apache" appear in their names without prior written permission of the * * Apache Software Foundation. * * * * THIS SOFTWARE IS PROVIDED "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 SOFTWARE FOUNDATION 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 indivi- * * duals on behalf of the Apache Software Foundation. For more information * * on the Apache Software Foundation, please see <http://www.apache.org/>. * * * * ========================================================================= */ /* @version $Id: pr_warp.c,v 1.1 2001/05/10 21:12:32 pier Exp $ */ #include <wa.h> /* ************************************************************************* */ /* WARP CONSTANTS */ /* ************************************************************************* */ /* Look in WarpConstants.java for a description of these definitions. */ #define RID_CONNECTION 0x00000 #define RID_DISCONNECT 0x0ffff #define TYP_CONINIT_HST 0x00000 #define TYP_CONINIT_HID 0x00001 #define TYP_CONINIT_APP 0x00002 #define TYP_CONINIT_AID 0x00003 #define TYP_CONINIT_REQ 0x00004 #define TYP_CONINIT_RID 0x00005 #define TYP_CONINIT_ERR 0x0000F #define TYP_REQINIT_MET 0x00010 #define TYP_REQINIT_URI 0x00011 #define TYP_REQINIT_ARG 0x00012 #define TYP_REQINIT_PRO 0x00013 #define TYP_REQINIT_HDR 0x00014 #define TYP_REQINIT_VAR 0x00015 #define TYP_REQINIT_RUN 0x0001D #define TYP_REQINIT_ERR 0x0001E #define TYP_REQINIT_ACK 0x0001F #define TYP_REQUEST_STA 0x00020 #define TYP_REQUEST_HDR 0x00021 #define TYP_REQUEST_CMT 0x00022 #define TYP_REQUEST_DAT 0x00023 #define TYP_REQUEST_ERR 0x0002E #define TYP_REQUEST_ACK 0x0002F #define MAXPAYLOAD 65536 /* ************************************************************************* */ /* STRUCTURES AND FUNCTIONS DECLARATION */ /* ************************************************************************* */ /* The WARP connection configuration structure */ typedef struct warp_cconfig { apr_sockaddr_t *addr; apr_socket_t *sock; boolean disc; } warp_cconfig; /* The WARP application configuration structure */ typedef struct warp_aconfig { int host; int appl; boolean depl; } warp_aconfig; typedef struct warp_packet { apr_pool_t *pool; /* The APR memory pool where this packet is allocated */ int type; /* The packet type signature */ int size; /* The size of the buffer (used by read) */ int bpos; /* The current position in the buffer */ char *buff; /* The payload buffer */ } warp_packet; /* The list of all configured connections */ static wa_chain *warp_connections=NULL; /* This provider */ wa_provider wa_provider_warp; /* ************************************************************************* */ /* WARP PACKET FUNCTIONS */ /* ************************************************************************* */ static void p_reset(warp_packet *pack) { pack->type=0; pack->bpos=0; pack->size=0; } static warp_packet *p_create(apr_pool_t *pool) { warp_packet *pack=apr_palloc(pool,sizeof(warp_packet)); pack->buff=apr_palloc(pool,MAXPAYLOAD*sizeof(char)); pack->pool=pool; p_reset(pack); return(pack); } static boolean p_wshort(warp_packet *p, int k) { if ((p->bpos+2)>MAXPAYLOAD) return(FALSE); p->buff[p->bpos++]=(char)((k>>8)&0x0ff); p->buff[p->bpos++]=(char)(k&0x0ff); return(TRUE); } static boolean p_wstring(warp_packet *p, char *s) { int l=0; int x=0; if (s==NULL) return(p_wshort(p,0)); // Evaluate string length l=strlen(s); // Store string length if (!p_wshort(p,strlen(s))) return(FALSE); // Check if we have room in the buffer and copy the string if ((p->bpos+l)>MAXPAYLOAD) return(FALSE); for(x=0; x<l; x++) p->buff[p->bpos++]=s[x]; return(TRUE); } static int p_rshort(warp_packet *p) { int k=0; int x=0; // Store the two bytes x=p->bpos; k=((p->buff[p->bpos++]<<8)&0x0ff00); k=((k|(p->buff[p->bpos++]&0x0ff))&0x0ffff); return(k); } static char *p_rstring(warp_packet *p) { int k=p_rshort(p); char *ret=apr_pstrndup(p->pool,p->buff+p->bpos,k); p->bpos+=k; return(ret); } /* ************************************************************************* */ /* NETWORK FUNCTIONS */ /* ************************************************************************* */ /* Attempt to connect to the remote endpoint of the WARP connection (if not done already). */ static boolean n_connect(wa_connection *conn) { warp_cconfig *conf=(warp_cconfig *)conn->conf; apr_status_t ret=APR_SUCCESS; /* Create the APR socket if that has not been yet created */ if (conf->sock==NULL) { ret=apr_socket_create(&conf->sock,AF_INET,SOCK_STREAM,wa_pool); if (ret!=APR_SUCCESS) { conf->sock=NULL; wa_debug(WA_MARK,"Cannot create socket for \"%s\"",conn->name); return(FALSE); } } /* Attempt to connect to the remote endpoint */ if (conf->disc) { ret=apr_connect(conf->sock, conf->addr); if (ret!=APR_SUCCESS) { conf->disc=TRUE; wa_debug(WA_MARK,"Connection \"%s\" cannot connect",conn->name); return(FALSE); } else { conf->disc=FALSE; return(TRUE); } } /* We were already connected */ return(TRUE); } /* Attempt to disconnect a connection if connected. */ static void n_disconnect(wa_connection *conn) { warp_cconfig *conf=(warp_cconfig *)conn->conf; apr_status_t ret=APR_SUCCESS; wa_debug(WA_MARK,"Disconnecting \"%s\"",conn->name); /* Create the APR socket if that has not been yet created */ if (conf->sock==NULL) return; if (conf->disc) return; /* Shutdown and close the socket (ignoring errors) */ ret=apr_shutdown(conf->sock,APR_SHUTDOWN_READWRITE); if (ret!=APR_SUCCESS) wa_debug(WA_MARK,"Cannot shutdown \"%s\"",conn->name); ret=apr_socket_close(conf->sock); if (ret!=APR_SUCCESS) wa_debug(WA_MARK,"Cannot close \"%s\"",conn->name); /* Reset the state */ conf->sock=NULL; conf->disc=TRUE; } /* Send a 16 bits value over a connection */ static boolean n_sshort(wa_connection *conn, int k) { warp_cconfig *c=(warp_cconfig *)conn->conf; apr_size_t len=2; char buf[len]; if (c->sock==NULL) { wa_log(WA_MARK,"Socket not initialized"); n_disconnect(conn); return(FALSE); } if (c->disc) { wa_log(WA_MARK,"Socket not connected"); n_disconnect(conn); return(FALSE); } buf[0]=(k>>8)&0x0ff; buf[1]=k&0x0ff; if (apr_send(c->sock,buf,&len)!=APR_SUCCESS) { wa_log(WA_MARK,"Cannot write to socket"); n_disconnect(conn); return(FALSE); } if (len!=2) { wa_log(WA_MARK,"Cannot write full buffer to socket"); n_disconnect(conn); return(FALSE); } return(TRUE); } /* Send a packet over a connection */ static boolean n_send(wa_connection *conn, int r, warp_packet *p) { warp_cconfig *c=(warp_cconfig *)conn->conf; apr_size_t len=2; /* Send the connection ID */ if (!n_sshort(conn,r)) { p_reset(p); return(FALSE); } /* Send the packet type */ if (!n_sshort(conn,p->type)) { p_reset(p); return(FALSE); } /* Send the packet length */ if (!n_sshort(conn,p->bpos)) { p_reset(p); return(FALSE); } /* Check if we need to send the payload */ if (p->bpos<=0) { p_reset(p); return(TRUE); } /* Send the payload */ len=p->bpos; if (apr_send(c->sock,p->buff,&len)!=APR_SUCCESS) { wa_log(WA_MARK,"Cannot write to socket"); n_disconnect(conn); p_reset(p); return(FALSE); } if (len!=p->bpos) { wa_log(WA_MARK,"Cannot write full buffer to socket"); n_disconnect(conn); p_reset(p); return(FALSE); } wa_debug(WA_MARK,"Sent packet CID=%d TYP=%d LEN=%d",r,p->type,p->bpos); p_reset(p); return(TRUE); } /* Receive a short integer (2 bytes) over a warp connection. */ static int n_rshort(wa_connection *conn) { warp_cconfig *c=(warp_cconfig *)conn->conf; char buf[2]; apr_size_t k=2; if (c->sock==NULL) { wa_log(WA_MARK,"Socket not initialized"); n_disconnect(conn); return(FALSE); } if (c->disc) { wa_log(WA_MARK,"Socket not connected"); n_disconnect(conn); return(FALSE); } if (apr_recv(c->sock,buf,&k)!=APR_SUCCESS) { wa_log(WA_MARK,"Cannot read from socket"); n_disconnect(conn); return(-1); } if (k!=2) { wa_log(WA_MARK,"Cannot read full buffer from socket"); n_disconnect(conn); return(-1); } return((((buf[0]<<8)&0x0ff00)|(buf[1]&0x0ff))&0x0ffff); } /* Receive a warp packet. */ static boolean n_recv(wa_connection *conn, int r, warp_packet *p) { warp_cconfig *c=(warp_cconfig *)conn->conf; apr_size_t num=0; int rid=-1; int typ=-1; int siz=-1; p_reset(p); /* Get the packet RID */ if ((rid=n_rshort(conn))<0) { wa_log(WA_MARK,"NO RID (%d)\n",rid); return(FALSE); } /* Fix this for multithreaded environments (demultiplexing of packets) */ if (rid!=r) { wa_log(WA_MARK,"INVALID RID got %d expected %d\n",rid,r); n_disconnect(conn); return(FALSE); } /* Get the packet TYPE */ if ((typ=n_rshort(conn))<0) { wa_log(WA_MARK,"NO TYP rid=%d typ=%d\n",rid,typ); return(FALSE); } /* Get the packet payload size */ if ((siz=n_rshort(conn))<0) { wa_log(WA_MARK,"NO SIZ rid=%d typ=%d siz=%d\n",rid,typ,siz); return(FALSE); } /* Update the packet */ p->type=typ; p->size=siz; if (siz==0) return(TRUE); /* Read from the socket and fill the packet buffer */ while(TRUE) { num=siz-p->bpos; if (apr_recv(c->sock,p->buff+p->bpos,&num)!=APR_SUCCESS) { wa_log(WA_MARK,"Cannot read from socket"); n_disconnect(conn); return(FALSE); } p->bpos+=num; if (p->bpos<siz) { wa_debug(WA_MARK,"SHORT len=%d siz=%d\n",p->bpos,siz); } else if (p->bpos>siz) { wa_log(WA_MARK,"INCONSIST len=%d siz=%d\n",p->bpos,siz); n_disconnect(conn); return(FALSE); } else { p->bpos=0; return(TRUE); } } } /* ************************************************************************* */ /* LOCAL FUNCTIONS FOR CONFIGURATION */ /* ************************************************************************* */ /* Configure a web application over its connection */ static void x_configure(wa_application *appl, apr_pool_t *pool) { wa_connection *conn=(wa_connection *)appl->conn; warp_aconfig *conf=(warp_aconfig *)appl->conf; warp_packet *i=NULL; warp_packet *o=NULL; int hostid=-1; int applid=-1; if (!n_connect(conn)) return; wa_debug(WA_MARK,"Configuring application \"%s\" for http://%s:%d%s", appl->name, appl->host->name, appl->host->port, appl->rpth); /* Allocate a couple of packets */ i=p_create(pool); o=p_create(pool); /* Retrieve the WARP HOSTID for the host */ o->type=TYP_CONINIT_HST; p_wstring(o,appl->host->name); p_wshort(o,appl->host->port); if (!n_send(conn,RID_CONNECTION,o)) return; if (!n_recv(conn,RID_CONNECTION,i)) return; if (i->type!=TYP_CONINIT_HID) { wa_debug(WA_MARK,"Invalid response received (%04X)",i->type); wa_log(WA_MARK,"Invalid virtual host%s:%d", appl->host->name, appl->host->port); return; } hostid=p_rshort(i); wa_debug(WA_MARK,"Host %s:%d has ID %d",appl->host->name, appl->host->port, hostid); p_reset(i); p_reset(o); /* Retrieve the WARP APPLID for the application */ o->type=TYP_CONINIT_APP; p_wshort(o,hostid); p_wstring(o,appl->name); p_wstring(o,appl->rpth); if (!n_send(conn,RID_CONNECTION,o)) return; if (!n_recv(conn,RID_CONNECTION,i)) return; if (i->type!=TYP_CONINIT_AID) { wa_debug(WA_MARK,"Invalid response received (%04X)",i->type); wa_log(WA_MARK,"Invalid application %s for http://%s:%d%s",appl->name, appl->host->name, appl->host->port, appl->rpth); return; } applid=p_rshort(i); wa_debug(WA_MARK,"Application %s under %s has ID %d",appl->name, appl->rpth, applid); conf->host=hostid; conf->appl=applid; conf->depl=TRUE; } /* ************************************************************************* */ /* WEBAPP LIBRARY PROVIDER FUNCTIONS */ /* ************************************************************************* */ /* Initialize this provider. */ static const char *warp_init(void) { wa_debug(WA_MARK,"WARP provider initialized"); return(NULL); } /* Notify this provider of its imminent startup. */ static void warp_startup(void) { wa_chain *elem=wa_configuration; apr_pool_t *pool=NULL; /* Configre all deployed applications */ while(elem!=NULL) { wa_virtualhost *host=(wa_virtualhost *)elem->curr; wa_chain *apps=host->apps; while(apps!=NULL) { wa_application *appl=(wa_application *)apps->curr; /* Configure the application with a temporary pool */ if (strcasecmp(appl->conn->prov->name,"warp")==0) { apr_pool_create(&pool,wa_pool); x_configure(appl,pool); apr_pool_destroy(pool); } apps=apps->next; } elem=elem->next; } wa_debug(WA_MARK,"WARP provider started"); } /* Cleans up all resources allocated by this provider. */ static void warp_destroy(void) { wa_chain *elem=warp_connections; while(elem!=NULL) { wa_connection *curr=(wa_connection *)elem->curr; wa_debug(WA_MARK,"Destroying connection \"%s\"",curr->name); n_disconnect(curr); elem=elem->next; } wa_debug(WA_MARK,"WARP provider destroyed"); } /* Configure a connection with the parameter from the web server configuration file. */ static const char *warp_connect(wa_connection *conn, const char *param) { apr_status_t r=APR_SUCCESS; warp_cconfig *conf=NULL; apr_port_t port=0; char *addr=NULL; char *scop=NULL; /* Allocation and checking */ conf=(warp_cconfig *)apr_palloc(wa_pool,sizeof(warp_cconfig)); if (conf==NULL) return("Cannot allocate connection configuration"); /* Check and parse parameter */ if (param==NULL) return("Parameter for connection not specified"); if (apr_parse_addr_port(&addr,&scop,&port,param,wa_pool)!=APR_SUCCESS) return("Invalid format for parameter"); if (addr==NULL) return("Host name not specified in parameter"); if (scop!=NULL) return("Invalid format for parameter (scope)"); if (port==0) return("Port number not specified in parameter"); /* Create and APR sockaddr structure */ r=apr_sockaddr_info_get(&(conf->addr),addr,APR_INET,port,0,wa_pool); if (r!=APR_SUCCESS) return("Cannot get socket address information"); /* Done */ conf->sock=NULL; conf->disc=TRUE; conn->conf=conf; return(NULL); } /* Receive notification of the deployment of an application. */ static const char *warp_deploy(wa_application *appl) { wa_chain *elem=warp_connections; wa_connection *conn=appl->conn; warp_aconfig *conf=NULL; conf=(warp_aconfig *)apr_palloc(wa_pool,sizeof(warp_aconfig)); if (conf==NULL) return("Cannot allocate application configuration"); conf->host=-1; conf->appl=-1; conf->depl=FALSE; appl->conf=conf; /* Check if the connection specified in this application has already been stored in our local array of connections */ while (elem!=NULL) { wa_connection *curr=(wa_connection *)elem->curr; if (strcasecmp(conn->name,curr->name)==0) break; elem=elem->next; } if (elem==NULL) { elem=(wa_chain *)apr_palloc(wa_pool,sizeof(wa_chain)); elem->curr=conn; elem->next=warp_connections; warp_connections=elem; } return(NULL); } /* Describe the configuration member found in a connection. */ static char *warp_conninfo(wa_connection *conn, apr_pool_t *pool) { warp_cconfig *conf=(warp_cconfig *)conn->conf; apr_port_t port=0; char *addr=NULL; char *name=NULL; char *mesg=NULL; char *buff=NULL; if (conf==NULL) return("Invalid configuration member"); apr_sockaddr_port_get(&port,conf->addr); apr_sockaddr_ip_get(&addr,conf->addr); apr_getnameinfo(&name,conf->addr,0); if (conf->sock==NULL) mesg="Socket not initialized"; else { if (conf->disc) mesg="Socket disconnected"; else mesg="Socket connected"; } buff=apr_psprintf(pool,"Host: %s Port:%d Address:%s (%s)", name,port,addr,mesg); return(buff); } /* Describe the configuration member found in a web application. */ static char *warp_applinfo(wa_application *appl, apr_pool_t *pool) { warp_aconfig *conf=(warp_aconfig *)appl->conf; char *h=NULL; char *a=NULL; if (conf==NULL) return("Invalid configuration member"); if (conf->host<0) h="(Not initialized)"; else h=apr_psprintf(pool,"%d",conf->host); if (conf->appl<0) a="(Not initialized)"; else a=apr_psprintf(pool,"%d",conf->appl); return(apr_psprintf(pool,"Application ID: %s Host ID: %s",a,h)); } typedef struct warp_rheader { wa_connection *conn; warp_packet *pack; boolean fail; int wrid; } warp_rheader; /* Transmit headers */ static int r_headers(void *d, const char *n, const char *v) { warp_rheader *data=(warp_rheader *)d; wa_connection *conn=data->conn; warp_packet *p=data->pack; int rid=data->wrid; p->type=TYP_REQINIT_HDR; p_wstring(p,(char *)n); p_wstring(p,(char *)v); n_send(conn,rid,p); return(TRUE); } /* Handle a connection from the web server. */ static int warp_handle(wa_request *r, wa_application *a) { warp_rheader *h=(warp_rheader *)apr_palloc(r->pool,sizeof(warp_rheader)); warp_cconfig *cc=(warp_cconfig *)a->conn->conf; warp_aconfig *ac=(warp_aconfig *)a->conf; warp_packet *i=p_create(r->pool); warp_packet *o=p_create(r->pool); wa_connection *conn=a->conn; boolean committed=FALSE; int rid=0; int sta=500; /* Check wether we are connected and configured right */ if (cc->disc) wa_rerror(WA_MARK,r,500,"We are disconnected"); if (!ac->depl) wa_rerror(WA_MARK,r,500,"Application not deployed correctly"); /* Request connection ID */ o->type=TYP_CONINIT_REQ; p_wshort(o,ac->host); p_wshort(o,ac->appl); if (!n_send(conn,RID_CONNECTION,o)) return(wa_rerror(WA_MARK,r,500,"I/O Error")); if (!n_recv(conn,RID_CONNECTION,i)) return(wa_rerror(WA_MARK,r,500,"I/O Error")); if (i->type!=TYP_CONINIT_RID) { wa_debug(WA_MARK,"Invalid response received (%04X)",i->type); return(wa_rerror(WA_MARK,r,500,"Cannot retrieve request ID")); } rid=p_rshort(i); /* The request method */ o->type=TYP_REQINIT_MET; p_wstring(o,r->meth); if (!n_send(conn,rid,o)) return(wa_rerror(WA_MARK,r,500,"I/O Error")); /* The request URI */ o->type=TYP_REQINIT_URI; p_wstring(o,r->ruri); if (!n_send(conn,rid,o)) return(wa_rerror(WA_MARK,r,500,"I/O Error")); /* The request arguments */ o->type=TYP_REQINIT_ARG; p_wstring(o,r->args); if (!n_send(conn,rid,o)) return(wa_rerror(WA_MARK,r,500,"I/O Error")); /* The request protocol */ o->type=TYP_REQINIT_PRO; p_wstring(o,r->prot); if (!n_send(conn,rid,o)) return(wa_rerror(WA_MARK,r,500,"I/O Error")); /* The request headers */ h->conn=conn; h->pack=o; h->wrid=rid; apr_table_do(r_headers,h,r->hdrs,NULL); /* And we're ready to go */ o->type=TYP_REQINIT_RUN; if (!n_send(conn,rid,o)) return(wa_rerror(WA_MARK,r,500,"I/O Error")); /* Now we need to wait for what the servlet container issues us */ while (TRUE) { if(!n_recv(conn,rid,i)) { n_disconnect(conn); return(wa_rerror(WA_MARK,r,500,"No packets received waiting response")); } /* Check if we got an ERR packet */ if (i->type==TYP_REQUEST_ERR) { return(wa_rerror(WA_MARK,r,500,"Error in response")); } /* Check if we got an ACK packet (close) */ if (i->type==TYP_REQUEST_ACK) { wa_rflush(r); return(sta); } /* Check if we got an STA packet */ if (i->type==TYP_REQUEST_STA) { wa_debug(WA_MARK,"Status1 \"%s\"",p_rstring(i)); wa_rsetstatus(r,p_rshort(i)); wa_debug(WA_MARK,"Status2 \"%s\"",p_rstring(i)); } /* Check if we got an HDR packet (header) */ if (i->type==TYP_REQUEST_HDR) { char *nam=p_rstring(i); char *val=p_rstring(i); wa_debug(WA_MARK,"Header \"%s\": \"%s\"",nam,val); if (strcasecmp("Connection",nam)!=0) { wa_rsetheader(r,nam,val); } if (strcasecmp("Content-Type",nam)==0) { wa_rsetctype(r,val); } } /* Check if we got an CMT packet (commit) */ if (i->type==TYP_REQUEST_CMT) { if (!committed) { wa_rcommit(r); committed=TRUE; } } /* Check if we got an DAT packet (data) */ if (i->type==TYP_REQUEST_DAT) { if (!committed) { wa_rcommit(r); committed=TRUE; } wa_rwrite(r,i->buff,i->size); wa_rflush(r); } } } /* The warp provider structure */ wa_provider wa_provider_warp = { "warp", warp_init, warp_startup, warp_destroy, warp_connect, warp_deploy, warp_conninfo, warp_applinfo, warp_handle, };