int scfd=-1;
-#define ERROR "500 CGI Bridge Error\r\n\r\nCGI Bridge not working correctly.\r\n"
+#define ERROR \
+ "Status: 500 CGI Bridge Error\r\n" \
+ "Content-Type: text/html\r\n" \
+ "\r\n" \
+ "CGI Bridge not working correctly.\r\n"
void encodeEnviron()
{
char *evc,**evn;
- char buf2[32];
+ char buf2[1024];
int pos=0;
memset(buf,0,sizeof(buf));
//encode SCGI
strcpy(buf+pos,"1");pos+=2;
//encode content length
evc=getenv("CONTENT_LENGTH");
- memcpy(buf,"CONTENT_LENGTH",15);
+ memcpy(buf+pos,"CONTENT_LENGTH",15);pos+=15;
if(evc){
- memcpy(buf,evc,strlen(evc)+1);
- pos+=16+strlen(evc);
+ memcpy(buf+pos,evc,strlen(evc)+1);
+ pos+=strlen(evc)+1;
}else{
- memcpy(buf,"0",2);
- pos+=17;
+ memcpy(buf+pos,"0",2);
+ pos+=2;
}
//encode variables
- evn=environ;
- while(*evn){
- int l1,l2;
- if(strcmp(*evn,"CONTENT_LENGTH")==0)continue;
- if(strncmp(*evn,"SCGI",4)==0)continue;
+ for(evn=environ;*evn;evn++){
+ int l1,l2,i;
+ if(strncmp(*evn,"CONTENT_LENGTH=",15)==0)continue;
+ if(strncmp(*evn,"SCGI=",5)==0)continue;
+ if(strlen(*evn)>=sizeof(buf2))continue;
l1=strlen(*evn)+1;
- evc=getenv(*evn);
- l2=strlen(evc)+1;
- if((l1+l2+pos)>sizeof(buf))break;
- memcpy(buf+pos,*evn,l1);pos+=l1;
- if(evc){
- memcpy(buf+pos,evc,l2);
- pos+=l2;
- }else
- pos++;
- evn++;
+ if((l1+pos)>sizeof(buf))break;
+ strncpy(buf2,*evn,sizeof(buf2));
+ l2=0;
+ for(i=0;i<strlen(buf2);i++){
+ if(buf2[i]=='='){
+ buf2[i]=0;
+ l2=i;
+ break;
+ }
+ }
+ if(l2<=0)continue;
+ memcpy(buf+pos,buf2,l1);pos+=l1;
}
sprintf(buf2,"%i:",pos);
write(scfd,buf2,strlen(buf2));
if(cl>sizeof(buf))l=sizeof(buf);else l=cl;
l=read(STDIN_FILENO,buf,l);
write(scfd,buf,l);
+ cl-=l;
}
}
fd_set rd,ex;
int maxfd=scfd;
int rfd;
- if(STDOUT_FILENO<maxfd)maxfd=STDOUT_FILENO;
+ if(STDOUT_FILENO>maxfd)maxfd=STDOUT_FILENO;
maxfd++;
do{
FD_ZERO(&rd);
FD_SET(scfd,&rd);
rfd=select(maxfd,&rd,0,&ex,0);
if(rfd<0){
- if(errno==EINTR)continue;
+ int err=errno;
+ if(err==EINTR)continue;
+ fprintf(stderr,"Error during relay of response: %s\n",strerror(err));
return;
}
if(rfd==0)continue;
- if(FD_ISSET(scfd,&ex) || FD_ISSET(STDOUT_FILENO,&ex))
+ if(FD_ISSET(scfd,&ex) || FD_ISSET(STDOUT_FILENO,&ex)){
+ fprintf(stderr,"Exception during response relay.\n");
return;
+ }
if(FD_ISSET(scfd,&rd)){
int r;
r=read(scfd,buf,sizeof(buf));
if(r>0)write(STDOUT_FILENO,buf,r);
- else return;
+ else {
+ fprintf(stderr,"End of input.\n");
+ return;
+ }
}
}while(1);
}
{
//check argument list size
if(argc>3){
- fprintf(stderr,"Error: usage %s [socket] | [host port]\n",*argv);
printf(ERROR);
+ printf("Unable to decide where to connect to.\r\n");
+ fprintf(stderr,"Error: usage %s [socket] | [host port]\n",*argv);
+ fprintf(stderr,"Alternatively instead of arguments use environment variables.\n"); fprintf(stderr," socket or $SCGI_FILE - use a unix local file\n");
+ fprintf(stderr," host/port or $SCGI_HOST/$SCGI_PORT - use network connection\n");
return 1;
}
//check environment
openFile();
if(scfd<0)openNet();
if(scfd<0){
- fprintf(stderr,"Error: cannot open socket\n");
printf(ERROR);
+ printf("SCGI Server unreachable.\r\n");
+ fprintf(stderr,"Error: cannot open socket\n");
return 1;
}
//send request