add perl wrapper to scgi

This commit is contained in:
Anthony Minessale 2012-05-23 09:37:54 -05:00
parent a5cd951c53
commit bb3f72cb66
12 changed files with 7025 additions and 30 deletions

6
libs/libscgi/FSSCGI.i Normal file
View File

@ -0,0 +1,6 @@
%{
#include "scgi.h"
#include "scgi_oop.h"
%}
%include "scgi_oop.h"

View File

@ -9,10 +9,12 @@ MYLIB=libscgi.a
LIBS=
LDFLAGS=-L.
OBJS=src/scgi.o
SRC=src/scgi.c
HEADERS=src/include/scgi.h
SRC=src/scgi.c src/scgi_oop.cpp
HEADERS=src/include/scgi.h src/include/scgi_oop.h
SOLINK=-shared -Xlinker -x
# comment the next line to disable c++ (no swig mods for you then)
OBJS += src/scgi_oop.o
all: $(MYLIB) testclient testserver
@ -23,13 +25,27 @@ $(MYLIB): $(OBJS) $(HEADERS) $(SRC)
%.o: %.c $(HEADERS)
$(CC) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@
%.o: %.cpp $(HEADERS)
$(CXX) $(CXX_CFLAGS) $(CXXFLAGS) -c $< -o $@
testclient: $(MYLIB) testclient.c
$(CC) $(CC_CFLAGS) $(CFLAGS) testclient.c -o testclient -lscgi $(LDFLAGS) $(LIBS)
testserver: $(MYLIB) testserver.c
$(CC) $(CC_CFLAGS) $(CFLAGS) testserver.c -o testserver -lscgi $(LDFLAGS) $(LIBS)
clean:
rm -f *.o src/*.o libscgi.a *~ src/*~ src/include/*~ testclient testserver
$(MAKE) -C perl clean
reswig: swigclean
$(MAKE) -C perl reswig
swigclean: clean
$(MAKE) -C perl swigclean
perlmod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C perl
perlmod-install: perlmod
$(MAKE) -C perl install

103
libs/libscgi/perl/FSSCGI.pm Normal file
View File

@ -0,0 +1,103 @@
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 1.3.35
#
# Don't modify this file, modify the SWIG interface instead.
package FSSCGI;
require Exporter;
require DynaLoader;
@ISA = qw(Exporter DynaLoader);
package FSSCGIc;
bootstrap FSSCGI;
package FSSCGI;
@EXPORT = qw( );
# ---------- BASE METHODS -------------
package FSSCGI;
sub TIEHASH {
my ($classname,$obj) = @_;
return bless $obj, $classname;
}
sub CLEAR { }
sub FIRSTKEY { }
sub NEXTKEY { }
sub FETCH {
my ($self,$field) = @_;
my $member_func = "swig_${field}_get";
$self->$member_func();
}
sub STORE {
my ($self,$field,$newval) = @_;
my $member_func = "swig_${field}_set";
$self->$member_func($newval);
}
sub this {
my $ptr = shift;
return tied(%$ptr);
}
# ------- FUNCTION WRAPPERS --------
package FSSCGI;
############# Class : FSSCGI::SCGIhandle ##############
package FSSCGI::SCGIhandle;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( FSSCGI );
%OWNER = ();
%ITERATORS = ();
sub new {
my $pkg = shift;
my $self = FSSCGIc::new_SCGIhandle(@_);
bless $self, $pkg if defined($self);
}
sub DESTROY {
return unless $_[0]->isa('HASH');
my $self = tied(%{$_[0]});
return unless defined $self;
delete $ITERATORS{$self};
if (exists $OWNER{$self}) {
FSSCGIc::delete_SCGIhandle($self);
delete $OWNER{$self};
}
}
*connected = *FSSCGIc::SCGIhandle_connected;
*socketDescriptor = *FSSCGIc::SCGIhandle_socketDescriptor;
*disconnect = *FSSCGIc::SCGIhandle_disconnect;
*addParam = *FSSCGIc::SCGIhandle_addParam;
*addBody = *FSSCGIc::SCGIhandle_addBody;
*sendRequest = *FSSCGIc::SCGIhandle_sendRequest;
*recv = *FSSCGIc::SCGIhandle_recv;
*bind = *FSSCGIc::SCGIhandle_bind;
*accept = *FSSCGIc::SCGIhandle_accept;
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
# ------- VARIABLE STUBS --------
package FSSCGI;
1;

View File

@ -0,0 +1,38 @@
PERL=$(shell which perl)
PERL_SITEDIR=$(shell perl -MConfig -e 'print $$Config{sitelibexp}')
PERL_LIBDIR=-L$(shell perl -MConfig -e 'print $$Config{archlib}')/CORE
PERL_LIBS=$(shell perl -MConfig -e 'print $$Config{libs}')
LOCAL_CFLAGS=-w -DMULTIPLICITY $(shell $(PERL) -MExtUtils::Embed -e ccopts) -DEMBED_PERL
LOCAL_LDFLAGS=$(shell $(PERL) -MExtUtils::Embed -e ldopts) $(shell $(PERL) -MConfig -e 'print $$Config{libs}')
GCC_WARNING_JUNK=-w
PERL_INC=$(shell $(PERL) -MExtUtils::Embed -e perl_inc)
all: FSSCGI.so
scgi_wrap.cpp:
swig -module FSSCGI -shadow -perl5 -c++ -DMULTIPLICITY -I../src/include -o scgi_wrap.cpp ../FSSCGI.i
perlxsi.c:
$(PERL) -MExtUtils::Embed -e xsinit -- -o perlxsi.c
perlxsi.o: perlxsi.c
$(CC) $(CC_CFLAGS) $(CFLAGS) $(LOCAL_CFLAGS) -c perlxsi.c -o perlxsi.o
scgi_wrap.o: scgi_wrap.cpp
$(CXX) $(CXX_CFLAGS) $(CXXFLAGS) $(GCC_WARNING_JUNK) $(PERL_INC) -c scgi_wrap.cpp -o scgi_wrap.o
FSSCGI.so: scgi_wrap.o perlxsi.o
$(CXX) $(SOLINK) scgi_wrap.o perlxsi.o $(MYLIB) $(LOCAL_LDFLAGS) -o FSSCGI.so -L. $(LIBS)
clean:
rm -f *.o *.so *~
swigclean:
rm -f scgi_wrap.* FSSCGI.so FSSCGI.pm perlxsi.*
reswig: swigclean scgi_wrap.cpp perlxsi.c
install: FSSCGI.so
install -m 755 FSSCGI.so $(PERL_SITEDIR)
install -m 755 FSSCGI.pm $(PERL_SITEDIR)
install -d -m 755 FSSCGI $(PERL_SITEDIR)/FSSCGI
install -m 755 FSSCGI/* $(PERL_SITEDIR)/FSSCGI

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
#include <EXTERN.h>
#include <perl.h>
EXTERN_C void xs_init (pTHX);
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
EXTERN_C void
xs_init(pTHX)
{
char *file = __FILE__;
dXSUB_SYS;
/* DynaLoader is a special case */
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
}

File diff suppressed because it is too large Load Diff

View File

@ -179,7 +179,7 @@ typedef enum {
SCGI_GENERR
} scgi_status_t;
typedef void (*scgi_listen_callback_t)(scgi_socket_t server_sock, scgi_socket_t client_sock, struct sockaddr_in *addr);
typedef void (*scgi_listen_callback_t)(scgi_socket_t server_sock, scgi_socket_t *client_sock, struct sockaddr_in *addr);
SCGI_DECLARE(scgi_status_t) scgi_connect(scgi_handle_t *handle, const char *host, scgi_port_t port, uint32_t timeout);
SCGI_DECLARE(scgi_status_t) scgi_disconnect(scgi_handle_t *handle);
@ -193,6 +193,8 @@ SCGI_DECLARE(scgi_status_t) scgi_destroy_params(scgi_handle_t *handle);
SCGI_DECLARE(scgi_status_t) scgi_listen(const char *host, scgi_port_t port, scgi_listen_callback_t callback);
SCGI_DECLARE(const char *) scgi_get_body(scgi_handle_t *handle);
SCGI_DECLARE(const char *) scgi_get_param(scgi_handle_t *handle, const char *name);
SCGI_DECLARE(scgi_status_t) scgi_bind(const char *host, scgi_port_t port, scgi_socket_t *socketp);
SCGI_DECLARE(scgi_status_t) scgi_accept(scgi_socket_t server_sock, scgi_socket_t *client_sock_p, struct sockaddr_in *echoClntAddr);
#ifdef __cplusplus
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * 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.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER
* OR 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.
*/
#ifndef _SCGI_OOP_H_
#define _SCGI_OOP_H_
#include <scgi.h>
#ifdef __cplusplus
extern "C" {
#endif
#define this_check(x) do { if (!this) { scgi_log(SCGI_LOG_ERROR, "object is not initalized\n"); return x;}} while(0)
#define this_check_void() do { if (!this) { scgi_log(SCGI_LOG_ERROR, "object is not initalized\n"); return;}} while(0)
class SCGIhandle {
private:
scgi_handle_t handle;
unsigned char buf[65536];
public:
SCGIhandle();
virtual ~SCGIhandle();
int connected();
int socketDescriptor();
int disconnect(void);
int addParam(const char *name, const char *value);
int addBody(const char *value);
int sendRequest(const char *host, int port, int timeout);
char *recv();
int bind(const char *host, int port);
int accept(void);
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -548,7 +548,7 @@ static int scgi_socket_reuseaddr(scgi_socket_t socket)
#endif
}
SCGI_DECLARE(scgi_status_t) scgi_listen(const char *host, scgi_port_t port, scgi_listen_callback_t callback)
SCGI_DECLARE(scgi_status_t) scgi_bind(const char *host, scgi_port_t port, scgi_socket_t *socketp)
{
scgi_socket_t server_sock = SCGI_SOCK_INVALID;
struct sockaddr_in addr;
@ -575,30 +575,62 @@ SCGI_DECLARE(scgi_status_t) scgi_listen(const char *host, scgi_port_t port, scgi
goto end;
}
for (;;) {
int client_sock;
struct sockaddr_in echoClntAddr;
#ifdef WIN32
int clntLen;
#else
unsigned int clntLen;
#endif
clntLen = sizeof(echoClntAddr);
if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == SCGI_SOCK_INVALID) {
status = SCGI_FAIL;
goto end;
}
callback(server_sock, client_sock, &echoClntAddr);
}
end:
if (server_sock != SCGI_SOCK_INVALID) {
closesocket(server_sock);
server_sock = SCGI_SOCK_INVALID;
} else {
*socketp = server_sock;
}
return status;
}
SCGI_DECLARE(scgi_status_t) scgi_accept(scgi_socket_t server_sock, scgi_socket_t *client_sock_p, struct sockaddr_in *echoClntAddr)
{
scgi_status_t status = SCGI_SUCCESS;
int client_sock;
struct sockaddr_in local_echoClntAddr;
#ifdef WIN32
int clntLen;
#else
unsigned int clntLen;
#endif
if (!echoClntAddr) {
echoClntAddr = &local_echoClntAddr;
}
clntLen = sizeof(*echoClntAddr);
if ((client_sock = accept(server_sock, (struct sockaddr *) echoClntAddr, &clntLen)) == SCGI_SOCK_INVALID) {
status = SCGI_FAIL;
} else {
*client_sock_p = client_sock;
}
return status;
}
SCGI_DECLARE(scgi_status_t) scgi_listen(const char *host, scgi_port_t port, scgi_listen_callback_t callback)
{
scgi_socket_t server_sock = SCGI_SOCK_INVALID, client_sock = SCGI_SOCK_INVALID;
scgi_status_t status = SCGI_FAIL;
struct sockaddr_in echoClntAddr;
if ((status = scgi_bind(host, port, &server_sock)) == SCGI_SUCCESS) {
while(scgi_accept(server_sock, &client_sock, &echoClntAddr) == SCGI_SUCCESS) {
callback(server_sock, &client_sock, &echoClntAddr);
if (client_sock != SCGI_SOCK_INVALID) {
closesocket(client_sock);
client_sock = SCGI_SOCK_INVALID;
}
}
}
return status;

View File

@ -0,0 +1,101 @@
#include <scgi.h>
#include <scgi_oop.h>
#define connection_construct_common() memset(&handle, 0, sizeof(handle))
SCGIhandle::SCGIhandle(void)
{
connection_construct_common();
}
SCGIhandle::~SCGIhandle()
{
if (handle.connected) {
scgi_disconnect(&handle);
}
}
int SCGIhandle::socketDescriptor()
{
if (handle.connected) {
return (int) handle.sock;
}
return -1;
}
int SCGIhandle::disconnect()
{
if (handle.connected) {
return scgi_disconnect(&handle);
}
return 0;
}
int SCGIhandle::connected()
{
return handle.connected;
}
int SCGIhandle::addParam(const char *name, const char *value)
{
return (int) scgi_add_param(&handle, name, value);
}
int SCGIhandle::addBody(const char *value)
{
return (int) scgi_add_body(&handle, value);
}
int SCGIhandle::sendRequest(const char *host, int port, int timeout)
{
if (!host) {
return -2;
}
if (timeout < 1000) {
timeout = 1000;
}
if (scgi_connect(&handle, host, port, timeout) == SCGI_SUCCESS) {
return (int) scgi_send_request(&handle);
}
return -2;
}
char *SCGIhandle::recv(void)
{
ssize_t len = scgi_recv(&handle, buf, sizeof(buf));
if (len > 0) {
return (char *)buf;
}
return NULL;
}
int SCGIhandle::bind(const char *host, int port)
{
return (int) scgi_bind(host, port, &handle.sock);
}
int SCGIhandle::accept(void)
{
scgi_socket_t client_sock;
if (scgi_accept(handle.sock, &client_sock, NULL) == SCGI_SUCCESS) {
return (int) client_sock;
}
return -1;
}

View File

@ -1,12 +1,14 @@
#include <scgi.h>
static void callback(scgi_socket_t server_sock, scgi_socket_t client_sock, struct sockaddr_in *addr)
static void callback(scgi_socket_t server_sock, scgi_socket_t *client_sock, struct sockaddr_in *addr)
{
scgi_handle_t handle = { 0 };
if (scgi_parse(client_sock, &handle) == SCGI_SUCCESS) {
scgi_param_t *pp;
*client_sock = SCGI_SOCK_INVALID;
for(pp = handle.params; pp; pp = pp->next) {
printf("HEADER: [%s] VALUE: [%s]\n", pp->name, pp->value);
}
@ -15,10 +17,9 @@ static void callback(scgi_socket_t server_sock, scgi_socket_t client_sock, struc
printf("\n\nBODY:\n%s\n\n", handle.body);
}
scgi_disconnect(&handle);
}
scgi_disconnect(&handle);
}
int main(int argc, char *argv[])