forked from Mirrors/freeswitch
add perl wrapper to scgi
This commit is contained in:
parent
a5cd951c53
commit
bb3f72cb66
|
@ -0,0 +1,6 @@
|
|||
%{
|
||||
#include "scgi.h"
|
||||
#include "scgi_oop.h"
|
||||
%}
|
||||
|
||||
%include "scgi_oop.h"
|
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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
|
@ -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
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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 (;;) {
|
||||
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 echoClntAddr;
|
||||
struct sockaddr_in local_echoClntAddr;
|
||||
#ifdef WIN32
|
||||
int clntLen;
|
||||
#else
|
||||
unsigned int clntLen;
|
||||
#endif
|
||||
|
||||
clntLen = sizeof(echoClntAddr);
|
||||
if (!echoClntAddr) {
|
||||
echoClntAddr = &local_echoClntAddr;
|
||||
}
|
||||
|
||||
if ((client_sock = accept(server_sock, (struct sockaddr *) &echoClntAddr, &clntLen)) == SCGI_SOCK_INVALID) {
|
||||
|
||||
clntLen = sizeof(*echoClntAddr);
|
||||
|
||||
if ((client_sock = accept(server_sock, (struct sockaddr *) echoClntAddr, &clntLen)) == SCGI_SOCK_INVALID) {
|
||||
status = SCGI_FAIL;
|
||||
goto end;
|
||||
} else {
|
||||
*client_sock_p = client_sock;
|
||||
}
|
||||
|
||||
callback(server_sock, client_sock, &echoClntAddr);
|
||||
return status;
|
||||
}
|
||||
|
||||
end:
|
||||
SCGI_DECLARE(scgi_status_t) scgi_listen(const char *host, scgi_port_t port, scgi_listen_callback_t callback)
|
||||
{
|
||||
|
||||
if (server_sock != SCGI_SOCK_INVALID) {
|
||||
closesocket(server_sock);
|
||||
server_sock = SCGI_SOCK_INVALID;
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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,9 +17,8 @@ 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue