diff --git a/libs/libscgi/perl/FSSCGI.pm b/libs/libscgi/perl/FSSCGI.pm index 7dfd256e05..05370a12a7 100644 --- a/libs/libscgi/perl/FSSCGI.pm +++ b/libs/libscgi/perl/FSSCGI.pm @@ -79,8 +79,10 @@ sub DESTROY { *disconnect = *FSSCGIc::SCGIhandle_disconnect; *addParam = *FSSCGIc::SCGIhandle_addParam; *addBody = *FSSCGIc::SCGIhandle_addBody; +*getBody = *FSSCGIc::SCGIhandle_getBody; +*getParam = *FSSCGIc::SCGIhandle_getParam; *sendRequest = *FSSCGIc::SCGIhandle_sendRequest; -*recv = *FSSCGIc::SCGIhandle_recv; +*respond = *FSSCGIc::SCGIhandle_respond; *bind = *FSSCGIc::SCGIhandle_bind; *accept = *FSSCGIc::SCGIhandle_accept; sub DISOWN { diff --git a/libs/libscgi/perl/scgi_wrap.cpp b/libs/libscgi/perl/scgi_wrap.cpp index aaa8e40219..cc96e9494c 100644 --- a/libs/libscgi/perl/scgi_wrap.cpp +++ b/libs/libscgi/perl/scgi_wrap.cpp @@ -1556,6 +1556,26 @@ SWIG_AsCharPtrAndSize(SV *obj, char** cptr, size_t* psize, int *alloc) +SWIGINTERNINLINE SV * +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + SV *obj = sv_newmortal(); + if (carray) { + sv_setpvn(obj, carray, size); + } else { + sv_setsv(obj, &PL_sv_undef); + } + return obj; +} + + +SWIGINTERNINLINE SV * +SWIG_FromCharPtr(const char *cptr) +{ + return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); +} + + #include #if !defined(SWIG_NO_LLONG_MAX) # if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) @@ -1683,26 +1703,6 @@ SWIG_AsVal_int SWIG_PERL_DECL_ARGS_2(SV * obj, int *val) return res; } - -SWIGINTERNINLINE SV * -SWIG_FromCharPtrAndSize(const char* carray, size_t size) -{ - SV *obj = sv_newmortal(); - if (carray) { - sv_setpvn(obj, carray, size); - } else { - sv_setsv(obj, &PL_sv_undef); - } - return obj; -} - - -SWIGINTERNINLINE SV * -SWIG_FromCharPtr(const char *cptr) -{ - return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); -} - #ifdef __cplusplus extern "C" { #endif @@ -1951,13 +1951,80 @@ XS(_wrap_SCGIhandle_addBody) { } +XS(_wrap_SCGIhandle_getBody) { + { + SCGIhandle *arg1 = (SCGIhandle *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int argvi = 0; + dXSARGS; + + if ((items < 1) || (items > 1)) { + SWIG_croak("Usage: SCGIhandle_getBody(self);"); + } + res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_SCGIhandle, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SCGIhandle_getBody" "', argument " "1"" of type '" "SCGIhandle *""'"); + } + arg1 = reinterpret_cast< SCGIhandle * >(argp1); + result = (char *)(arg1)->getBody(); + ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; + + XSRETURN(argvi); + fail: + + SWIG_croak_null(); + } +} + + +XS(_wrap_SCGIhandle_getParam) { + { + SCGIhandle *arg1 = (SCGIhandle *) 0 ; + char *arg2 = (char *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + int argvi = 0; + dXSARGS; + + if ((items < 2) || (items > 2)) { + SWIG_croak("Usage: SCGIhandle_getParam(self,name);"); + } + res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_SCGIhandle, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SCGIhandle_getParam" "', argument " "1"" of type '" "SCGIhandle *""'"); + } + arg1 = reinterpret_cast< SCGIhandle * >(argp1); + res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SCGIhandle_getParam" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = reinterpret_cast< char * >(buf2); + result = (char *)(arg1)->getParam((char const *)arg2); + ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; + + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + XSRETURN(argvi); + fail: + + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; + SWIG_croak_null(); + } +} + + XS(_wrap_SCGIhandle_sendRequest) { { SCGIhandle *arg1 = (SCGIhandle *) 0 ; char *arg2 = (char *) 0 ; int arg3 ; int arg4 ; - int result; + char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; int res2 ; @@ -1993,8 +2060,8 @@ XS(_wrap_SCGIhandle_sendRequest) { SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "SCGIhandle_sendRequest" "', argument " "4"" of type '" "int""'"); } arg4 = static_cast< int >(val4); - result = (int)(arg1)->sendRequest((char const *)arg2,arg3,arg4); - ST(argvi) = SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ; + result = (char *)(arg1)->sendRequest((char const *)arg2,arg3,arg4); + ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; if (alloc2 == SWIG_NEWOBJ) delete[] buf2; @@ -2010,29 +2077,40 @@ XS(_wrap_SCGIhandle_sendRequest) { } -XS(_wrap_SCGIhandle_recv) { +XS(_wrap_SCGIhandle_respond) { { SCGIhandle *arg1 = (SCGIhandle *) 0 ; - char *result = 0 ; + char *arg2 = (char *) 0 ; + int result; void *argp1 = 0 ; int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; int argvi = 0; dXSARGS; - if ((items < 1) || (items > 1)) { - SWIG_croak("Usage: SCGIhandle_recv(self);"); + if ((items < 2) || (items > 2)) { + SWIG_croak("Usage: SCGIhandle_respond(self,msg);"); } res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_SCGIhandle, 0 | 0 ); if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SCGIhandle_recv" "', argument " "1"" of type '" "SCGIhandle *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SCGIhandle_respond" "', argument " "1"" of type '" "SCGIhandle *""'"); } arg1 = reinterpret_cast< SCGIhandle * >(argp1); - result = (char *)(arg1)->recv(); - ST(argvi) = SWIG_FromCharPtr((const char *)result); argvi++ ; + res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SCGIhandle_respond" "', argument " "2"" of type '" "char *""'"); + } + arg2 = reinterpret_cast< char * >(buf2); + result = (int)(arg1)->respond(arg2); + ST(argvi) = SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ; + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; XSRETURN(argvi); fail: + if (alloc2 == SWIG_NEWOBJ) delete[] buf2; SWIG_croak_null(); } } @@ -2154,8 +2232,10 @@ static swig_command_info swig_commands[] = { {"FSSCGIc::SCGIhandle_disconnect", _wrap_SCGIhandle_disconnect}, {"FSSCGIc::SCGIhandle_addParam", _wrap_SCGIhandle_addParam}, {"FSSCGIc::SCGIhandle_addBody", _wrap_SCGIhandle_addBody}, +{"FSSCGIc::SCGIhandle_getBody", _wrap_SCGIhandle_getBody}, +{"FSSCGIc::SCGIhandle_getParam", _wrap_SCGIhandle_getParam}, {"FSSCGIc::SCGIhandle_sendRequest", _wrap_SCGIhandle_sendRequest}, -{"FSSCGIc::SCGIhandle_recv", _wrap_SCGIhandle_recv}, +{"FSSCGIc::SCGIhandle_respond", _wrap_SCGIhandle_respond}, {"FSSCGIc::SCGIhandle_bind", _wrap_SCGIhandle_bind}, {"FSSCGIc::SCGIhandle_accept", _wrap_SCGIhandle_accept}, {0,0} diff --git a/libs/libscgi/perl/testclient.pl b/libs/libscgi/perl/testclient.pl new file mode 100644 index 0000000000..59415baf72 --- /dev/null +++ b/libs/libscgi/perl/testclient.pl @@ -0,0 +1,19 @@ +use FSSCGI; + + +my $handle = new FSSCGI::SCGIhandle(); + + $handle->addParam( "REQUEST_METHOD", "POST"); + $handle->addParam( "REQUEST_URI", "/deepthought"); + $handle->addParam( "TESTING", "TRUE"); + $handle->addParam( "TESTING", "TRUE"); + $handle->addBody("What is the answer to life?"); + + + +if ((my $response = $handle->sendRequest("127.0.0.1", 7777, 10000))) { + print "RESP[$response]\n"; +} else { + print "ERROR!\n"; +} + diff --git a/libs/libscgi/perl/testserver.pl b/libs/libscgi/perl/testserver.pl new file mode 100644 index 0000000000..6e03d5c5e4 --- /dev/null +++ b/libs/libscgi/perl/testserver.pl @@ -0,0 +1,17 @@ +use FSSCGI; + + +my $handle = new FSSCGI::SCGIhandle(); + +if ($handle->bind("127.0.0.1", 7777)) { + + while($handle->accept()) { + print "REQ: " . $handle->getBody(). "\n\n"; + $handle->respond("W00t!!!!!!\n"); + } + + print "DONE\n"; + +} else { + print "FAIL\n"; +} diff --git a/libs/libscgi/src/include/scgi.h b/libs/libscgi/src/include/scgi.h index 8a789a3a9f..b6a5165858 100644 --- a/libs/libscgi/src/include/scgi.h +++ b/libs/libscgi/src/include/scgi.h @@ -183,6 +183,7 @@ typedef void (*scgi_listen_callback_t)(scgi_socket_t server_sock, scgi_socket_t 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); +SCGI_DECLARE(scgi_status_t) scgi_parse(scgi_socket_t sock, scgi_handle_t *handle); SCGI_DECLARE(int) scgi_wait_sock(scgi_socket_t sock, uint32_t ms, scgi_poll_t flags); SCGI_DECLARE(ssize_t) scgi_recv(scgi_handle_t *handle, unsigned char *buf, size_t buflen); SCGI_DECLARE(scgi_status_t) scgi_send_request(scgi_handle_t *handle); @@ -196,6 +197,10 @@ SCGI_DECLARE(const char *) scgi_get_param(scgi_handle_t *handle, const char *nam 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); +#ifndef WIN32 +#define closesocket(x) shutdown(x, 2); close(x) +#endif + #ifdef __cplusplus } #endif /* defined(__cplusplus) */ diff --git a/libs/libscgi/src/include/scgi_oop.h b/libs/libscgi/src/include/scgi_oop.h index a49c96cdd1..64f3267779 100644 --- a/libs/libscgi/src/include/scgi_oop.h +++ b/libs/libscgi/src/include/scgi_oop.h @@ -45,8 +45,12 @@ extern "C" { class SCGIhandle { private: + scgi_socket_t server_sock; scgi_handle_t handle; unsigned char buf[65536]; + char *data_buf; + int buflen; + int bufsize; public: SCGIhandle(); virtual ~SCGIhandle(); @@ -55,8 +59,10 @@ class SCGIhandle { 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(); + char *getBody(); + char *getParam(const char *name); + char *sendRequest(const char *host, int port, int timeout); + int respond(char *msg); int bind(const char *host, int port); int accept(void); }; diff --git a/libs/libscgi/src/scgi.c b/libs/libscgi/src/scgi.c index f33afe30c8..9f8e9956e0 100644 --- a/libs/libscgi/src/scgi.c +++ b/libs/libscgi/src/scgi.c @@ -34,7 +34,6 @@ #include #ifndef WIN32 -#define closesocket(x) shutdown(x, 2); close(x) #include #include #else @@ -385,11 +384,9 @@ SCGI_DECLARE(scgi_status_t) scgi_disconnect(scgi_handle_t *handle) return SCGI_FAIL; } - handle->destroyed = 1; - handle->connected = 0; - - scgi_destroy_params(handle); - scgi_safe_free(handle->body); + if (!handle->sock) { + abort(); + } if (handle->sock != SCGI_SOCK_INVALID) { closesocket(handle->sock); @@ -397,6 +394,12 @@ SCGI_DECLARE(scgi_status_t) scgi_disconnect(scgi_handle_t *handle) status = SCGI_SUCCESS; } + handle->destroyed = 1; + handle->connected = 0; + + scgi_destroy_params(handle); + scgi_safe_free(handle->body); + return status; } @@ -577,9 +580,11 @@ SCGI_DECLARE(scgi_status_t) scgi_bind(const char *host, scgi_port_t port, scgi_s end: - if (server_sock != SCGI_SOCK_INVALID) { - closesocket(server_sock); - server_sock = SCGI_SOCK_INVALID; + if (status == SCGI_FAIL) { + if (server_sock != SCGI_SOCK_INVALID) { + closesocket(server_sock); + server_sock = SCGI_SOCK_INVALID; + } } else { *socketp = server_sock; } @@ -601,11 +606,11 @@ SCGI_DECLARE(scgi_status_t) scgi_accept(scgi_socket_t server_sock, scgi_socket_t if (!echoClntAddr) { echoClntAddr = &local_echoClntAddr; } - - + clntLen = sizeof(*echoClntAddr); if ((client_sock = accept(server_sock, (struct sockaddr *) echoClntAddr, &clntLen)) == SCGI_SOCK_INVALID) { + printf("FRICK %s\n", strerror(errno)); status = SCGI_FAIL; } else { *client_sock_p = client_sock; @@ -652,10 +657,12 @@ SCGI_DECLARE(scgi_status_t) scgi_parse(scgi_socket_t sock, scgi_handle_t *handle char *body = NULL; char comma = 0; + memset(handle, 0, sizeof(*handle)); + handle->sock = sock; + handle->connected = 1; sock_setup(handle); - for(;;) { diff --git a/libs/libscgi/src/scgi_oop.cpp b/libs/libscgi/src/scgi_oop.cpp index c5b98334b9..4001b748a3 100644 --- a/libs/libscgi/src/scgi_oop.cpp +++ b/libs/libscgi/src/scgi_oop.cpp @@ -12,9 +12,12 @@ SCGIhandle::SCGIhandle(void) SCGIhandle::~SCGIhandle() { - if (handle.connected) { - scgi_disconnect(&handle); - } + + scgi_disconnect(&handle); + scgi_safe_free(data_buf); + buflen = 0; + bufsize = 0; + } int SCGIhandle::socketDescriptor() @@ -29,11 +32,7 @@ int SCGIhandle::socketDescriptor() int SCGIhandle::disconnect() { - if (handle.connected) { - return scgi_disconnect(&handle); - } - - return 0; + return scgi_disconnect(&handle); } int SCGIhandle::connected() @@ -51,11 +50,22 @@ int SCGIhandle::addBody(const char *value) return (int) scgi_add_body(&handle, value); } - -int SCGIhandle::sendRequest(const char *host, int port, int timeout) +char *SCGIhandle::getBody() { + return handle.body; +} + +char *SCGIhandle::getParam(const char *name) +{ + return (char *) scgi_get_param(&handle, name); +} + +char *SCGIhandle::sendRequest(const char *host, int port, int timeout) +{ + ssize_t len; + if (!host) { - return -2; + return 0; } if (timeout < 1000) { @@ -63,27 +73,30 @@ int SCGIhandle::sendRequest(const char *host, int port, int timeout) } if (scgi_connect(&handle, host, port, timeout) == SCGI_SUCCESS) { - return (int) scgi_send_request(&handle); + if (scgi_send_request(&handle) == SCGI_SUCCESS) { + while((len = scgi_recv(&handle, buf, sizeof(buf))) > 0) { + if (buflen + len > bufsize) { + bufsize = buflen + len + 1024; + void *tmp = realloc(data_buf, bufsize); + assert(tmp); + data_buf = (char *)tmp; + + *(data_buf+buflen) = '\0'; + } + snprintf(data_buf+buflen, bufsize-buflen, "%s", buf); + buflen += len; + } + + return data_buf; + } } - return -2; + return (char *) ""; } -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); + return (scgi_bind(host, port, &server_sock) == SCGI_SUCCESS) ? 1 : 0; } @@ -91,11 +104,24 @@ int SCGIhandle::accept(void) { scgi_socket_t client_sock; - if (scgi_accept(handle.sock, &client_sock, NULL) == SCGI_SUCCESS) { - return (int) client_sock; + if (scgi_accept(server_sock, &client_sock, NULL) == SCGI_SUCCESS) { + if (scgi_parse(client_sock, &handle) == SCGI_SUCCESS) { + return 1; + } + + closesocket(client_sock); } - return -1; + return 0; } +int SCGIhandle::respond(char *msg) +{ + int b = write(handle.sock, msg, strlen(msg)); + scgi_disconnect(&handle); + scgi_safe_free(data_buf); + buflen = 0; + bufsize = 0; + return b; +} diff --git a/libs/libscgi/testserver.c b/libs/libscgi/testserver.c index 2a784e83a8..153a215c0e 100644 --- a/libs/libscgi/testserver.c +++ b/libs/libscgi/testserver.c @@ -4,7 +4,7 @@ static void callback(scgi_socket_t server_sock, scgi_socket_t *client_sock, stru { scgi_handle_t handle = { 0 }; - if (scgi_parse(client_sock, &handle) == SCGI_SUCCESS) { + if (scgi_parse(*client_sock, &handle) == SCGI_SUCCESS) { scgi_param_t *pp; *client_sock = SCGI_SOCK_INVALID;