Skip to content
This repository has been archived by the owner on Sep 13, 2024. It is now read-only.

Commit

Permalink
big PSGI update
Browse files Browse the repository at this point in the history
  • Loading branch information
roberto@debian32 committed May 6, 2011
1 parent cf08972 commit 4bd381b
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 87 deletions.
3 changes: 2 additions & 1 deletion plugins/psgi/psgi.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
struct uwsgi_perl {

int fd;
int custom_input;
char *psgibuffer;
char *psgi;
char *locallib;
Expand All @@ -25,6 +24,7 @@ struct uwsgi_perl {
CV *stream_responder;
HV *streaming_stash;
HV *input_stash;
HV *error_stash;

};

Expand All @@ -40,3 +40,4 @@ int psgi_response(struct wsgi_request *, PerlInterpreter *, AV*);
#define psgi_check_args(x) if (items < x) Perl_croak(aTHX_ "Usage: uwsgi::%s takes %d arguments", __FUNCTION__ + 3, x)

SV *uwsgi_perl_obj_call(SV *, char *);
int uwsgi_perl_obj_can(SV *, char *, size_t);
82 changes: 50 additions & 32 deletions plugins/psgi/psgi_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,18 @@ XS(XS_input_seek) {
XSRETURN(0);
}

XS(XS_error) {
dXSARGS;

psgi_check_args(0);

ST(0) = sv_bless(newRV(sv_newmortal()), uperl.error_stash);
XSRETURN(1);
}

XS(XS_input) {

dXSARGS;

uwsgi_log("new custom input\n");
psgi_check_args(0);

ST(0) = sv_bless(newRV(sv_newmortal()), uperl.input_stash);
Expand All @@ -28,39 +35,35 @@ XS(XS_stream)
{
dXSARGS;
struct wsgi_request *wsgi_req = current_wsgi_req();
SV *stack;
AV *response;

psgi_check_args(1);
stack = ST(0);

if (items == 2) {
response = (AV* ) SvRV(stack) ;
AV *response = (AV* ) SvREFCNT_inc(SvRV(ST(0))) ;

if (av_len(response) == 2) {

#ifdef my_perl
psgi_response(wsgi_req, my_perl, response);
while (psgi_response(wsgi_req, my_perl, response) != UWSGI_OK);
#else
psgi_response(wsgi_req, uperl.main, response);
while (psgi_response(wsgi_req, uperl.main, response) != UWSGI_OK);
#endif
}
else if (items == 1) {
response = (AV* ) SvRV(stack) ;

}
else if (av_len(response) == 1) {
#ifdef my_perl
psgi_response(wsgi_req, my_perl, response);
while (psgi_response(wsgi_req, my_perl, response) != UWSGI_OK);
#else
psgi_response(wsgi_req, uperl.main, response);
while (psgi_response(wsgi_req, uperl.main, response) != UWSGI_OK);
#endif
SvREFCNT_dec(response);
ST(0) = sv_bless(newRV(sv_newmortal()), uperl.streaming_stash);
XSRETURN(1);
}
else {
uwsgi_log("invalid PSGI response: array size %d\n", av_len(response));
}

}
else {
uwsgi_log("invalid PSGI response: array size %d\n", items+1);
}

//mXPUSHp("x", 1);
XSRETURN(0);
SvREFCNT_dec(response);
XSRETURN(0);

}

Expand All @@ -81,8 +84,6 @@ XS(XS_input_read) {
read_buf = ST(1);
len = SvIV(ST(2));

uwsgi_log("calling read() %d of %d\n", len, wsgi_req->post_cl);

// return empty string if no post_cl or pos >= post_cl
if (!wsgi_req->post_cl || (size_t) wsgi_req->post_pos >= wsgi_req->post_cl) {
sv_setpvn(read_buf, "", 0);
Expand All @@ -91,7 +92,6 @@ XS(XS_input_read) {

if (wsgi_req->body_as_file) {
fd = fileno((FILE *)wsgi_req->async_post);
uwsgi_log("fd = %d\n", fd);
}
else if (uwsgi.post_buffering > 0) {
fd = -1;
Expand Down Expand Up @@ -127,7 +127,6 @@ XS(XS_input_read) {

}

uwsgi_log("allocating %d bytes\n", remains);
tmp_buf = uwsgi_malloc(remains);

if (uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]) <= 0) {
Expand All @@ -144,7 +143,6 @@ XS(XS_input_read) {
}

wsgi_req->post_pos += bytes;
uwsgi_log("post data: %.*s\n", bytes, tmp_buf);
sv_setpvn(read_buf, tmp_buf, bytes);

free(tmp_buf);
Expand All @@ -158,6 +156,7 @@ XS(XS_streaming_close) {

dXSARGS;
psgi_check_args(0);

XSRETURN(0);
}

Expand All @@ -177,6 +176,21 @@ XS(XS_streaming_write) {
XSRETURN(0);
}

XS(XS_error_print) {

dXSARGS;
STRLEN blen;
char *body;

psgi_check_args(1);

if (items > 1) {
body = SvPV(ST(1), blen);
uwsgi_log("%.*s", blen, body);
}

XSRETURN(0);
}

/* automatically generated */

Expand All @@ -199,17 +213,21 @@ xs_init(pTHX)

uperl.input_stash = gv_stashpv("uwsgi::input", 0);

uperl.stream_responder = newXS("uwsgi::stream", XS_stream, "uwsgi");

#ifdef UWSGI_EMBEDDED
init_perl_embedded_module();
#endif
newXS("uwsgi::error::new", XS_error, "uwsgi::error");
newXS("uwsgi::error::print", XS_error_print, "uwsgi::print");
uperl.error_stash = gv_stashpv("uwsgi::error", 0);

uperl.stream_responder = newXS("uwsgi::stream", XS_stream, "uwsgi");

newXS("uwsgi::streaming::write", XS_streaming_write, "uwsgi::streaming");
newXS("uwsgi::streaming::close", XS_streaming_close, "uwsgi::streaming");

uperl.streaming_stash = gv_stashpv("uwsgi::streaming", 0);

#ifdef UWSGI_EMBEDDED
init_perl_embedded_module();
#endif

}

/* end of automagically generated part */
Expand Down
112 changes: 61 additions & 51 deletions plugins/psgi/psgi_plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ struct option uwsgi_perl_options[] = {

{"psgi", required_argument, 0, LONG_ARGS_PSGI},
{"perl-local-lib", required_argument, 0, LONG_ARGS_PERL_LOCAL_LIB},
{"psgi-custom-input", no_argument, &uperl.custom_input, 1},
{0, 0, 0, 0},

};
Expand Down Expand Up @@ -42,30 +41,55 @@ SV *uwsgi_perl_obj_new(char *class, size_t class_len) {

}

SV *uwsgi_perl_obj_call(SV *obj, char *method) {

SV *ret = NULL;
SV *uwsgi_perl_call_stream(SV *func) {

SV *ret = NULL;
// set current context ?
//dTHX;
dSP;

ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs( sv_2mortal(newRV((SV*) uperl.stream_responder)));
PUTBACK;

XPUSHs(obj);
call_sv( func, G_SCALAR | G_EVAL);

SPAGAIN;
if(SvTRUE(ERRSV)) {
uwsgi_log("%s\n", SvPV_nolen(ERRSV));
}
else {
ret = SvREFCNT_inc(POPs);
}

PUTBACK;
FREETMPS;
LEAVE;

call_method( method, G_SCALAR | G_EVAL);
return ret;
}

int uwsgi_perl_obj_can(SV *obj, char *method, size_t len) {

int ret;
// set current context ? needed for threading
//dTHX;
dSP;

ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(obj);
XPUSHs(sv_2mortal(newSVpv(method, len)));
PUTBACK;

call_method( "can", G_SCALAR);

SPAGAIN;
if(SvTRUE(ERRSV)) {
uwsgi_log("%s\n", SvPV_nolen(ERRSV));
}
else {
ret = SvREFCNT_inc(POPs);
}

ret = SvROK(POPs);
PUTBACK;
FREETMPS;
LEAVE;
Expand All @@ -75,38 +99,39 @@ SV *uwsgi_perl_obj_call(SV *obj, char *method) {
}


SV *uwsgi_perl_obj_call2(SV *obj, char *method, SV *arg1, SV *arg2) {
SV *uwsgi_perl_obj_call(SV *obj, char *method) {

SV *ret;
SV *ret = NULL;

dSP;
dSP;

ENTER;
SAVETMPS;
PUSHMARK(SP);

XPUSHs(obj);
XPUSHs(sv_2mortal(arg1));
XPUSHs(sv_2mortal(arg2));
XPUSHs(obj);

PUTBACK;


call_method( method, G_SCALAR);
call_method( method, G_SCALAR | G_EVAL);

SPAGAIN;
if(SvTRUE(ERRSV)) {
uwsgi_log("%s\n", SvPV_nolen(ERRSV));
}
else {
ret = SvREFCNT_inc(POPs);
}


ret = POPs;
PUTBACK;
FREETMPS;
LEAVE;


return ret;

}


AV *psgi_call(struct wsgi_request *wsgi_req, SV *psgi_func, SV *env) {

AV *ret = NULL;
Expand Down Expand Up @@ -228,22 +253,12 @@ SV *build_psgi_env(struct wsgi_request *wsgi_req) {


SV *pi = uwsgi_perl_obj_new("uwsgi::input", 12);

if (!hv_store(env, "psgi.input", 10, pi, 0)) goto clear;

/* disable for now...
if (!hv_store(env, "psgix.io", 8, pi, 0)) goto clear;
*/
if (!hv_store(env, "psgix.input.buffered", 20, newSViv(wsgi_req->body_as_file), 0)) goto clear;

if (!hv_store(env, "psgix.input.buffered", 20, newSViv(0), 0)) goto clear;


SV *io_err = uwsgi_perl_obj_new("IO::Handle", 10);
uwsgi_log("task001 %p %d\n", io_err, SvREFCNT(io_err));
//SV *pe = uwsgi_perl_obj_call2(io_err, "fdopen", newSViv(2), newSVpv("w", 1));
uwsgi_log("done\n");

//if (!hv_store(env, "psgi.errors", 11, pe, 0)) goto clear;
SV *pe = uwsgi_perl_obj_new("uwsgi::error", 12);
if (!hv_store(env, "psgi.errors", 11, pe, 0)) goto clear;

return newRV_noinc((SV *)env);

Expand All @@ -266,7 +281,11 @@ int uwsgi_perl_init(){
uwsgi_error("setenv()");
}

#ifdef PERL_VERSION_STRING
uwsgi_log("initializing Perl %s environment\n", PERL_VERSION_STRING);
#else
uwsgi_log("initializing Perl environment\n");
#endif
PERL_SYS_INIT3(&argc, (char ***) &uperl.embedding, &environ);
uperl.main = perl_alloc();
if (!uperl.main) {
Expand Down Expand Up @@ -345,8 +364,6 @@ void uwsgi_perl_enable_threads() {

int uwsgi_perl_request(struct wsgi_request *wsgi_req) {

dSP;

SV *psgi_func = uperl.psgi_main;
// ugly hack
register PerlInterpreter *my_perl = uperl.main;
Expand Down Expand Up @@ -389,23 +406,16 @@ int uwsgi_perl_request(struct wsgi_request *wsgi_req) {
if (!wsgi_req->async_result) goto clear;

if (SvTYPE((AV *)wsgi_req->async_result) == SVt_PVCV) {

PUSHMARK(SP);
XPUSHs( newRV((SV*) uperl.stream_responder));
PUTBACK;

perl_call_sv( (SV*)wsgi_req->async_result, G_SCALAR | G_EVAL);

if(SvTRUE(ERRSV)) {
SV *stream_result = uwsgi_perl_call_stream((SV*)wsgi_req->async_result);
if (!stream_result) {
internal_server_error(wsgi_req, "exception raised");
uwsgi_log("%s\n", SvPV_nolen(ERRSV));
}

else {
SvREFCNT_dec(stream_result);
}
goto clear2;
}

uwsgi_log("ok...\n");

while (psgi_response(wsgi_req, my_perl, wsgi_req->async_result) != UWSGI_OK) {
#ifdef UWSGI_ASYNC
if (uwsgi.async > 1) {
Expand Down
Loading

0 comments on commit 4bd381b

Please sign in to comment.