fixed psgi fileno() support

This commit is contained in:
roberto@precise64
2012-05-12 17:02:21 +02:00
parent 6e881293ff
commit ff9bab4b4e
4 changed files with 45 additions and 6 deletions

View File

@@ -47,5 +47,6 @@ int psgi_response(struct wsgi_request *, AV*);
SV *uwsgi_perl_obj_call(SV *, char *);
int uwsgi_perl_obj_can(SV *, char *, size_t);
int uwsgi_perl_obj_isa(SV *, char *);
int init_psgi_app(struct wsgi_request *, char *, uint16_t, PerlInterpreter **);
PerlInterpreter *uwsgi_perl_new_interpreter(void);

View File

@@ -384,6 +384,7 @@ int init_psgi_app(struct wsgi_request *wsgi_req, char *app, uint16_t app_len, Pe
perl_eval_pv("use IO::Handle;", 0);
perl_eval_pv("use IO::File;", 0);
perl_eval_pv("use Scalar::Util;", 0);
if (!uperl.no_die_catch) {
perl_eval_pv("use Devel::StackTrace;", 0);
if (!SvTRUE(ERRSV)) {

View File

@@ -101,6 +101,34 @@ int uwsgi_perl_obj_can(SV *obj, char *method, size_t len) {
}
int uwsgi_perl_obj_isa(SV *obj, char *class) {
int ret = 0;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(obj);
PUTBACK;
call_pv( "Scalar::Util::reftype", G_SCALAR|G_EVAL);
SPAGAIN;
char *reftype = POPp;
if (reftype && !strcmp(reftype, class)) {
ret = 1;
}
PUTBACK;
FREETMPS;
LEAVE;
return ret;
}
SV *uwsgi_perl_obj_call(SV *obj, char *method) {
SV *ret = NULL;

View File

@@ -140,15 +140,22 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
// respond to fileno ?
if (uwsgi.async < 2) {
if (uwsgi_perl_obj_can(*hitem, "fileno", 6)) {
// check for fileno() method, IO class or GvIO
if (uwsgi_perl_obj_can(*hitem, "fileno", 6) || uwsgi_perl_obj_isa(*hitem, "IO") || (uwsgi_perl_obj_isa(*hitem, "GLOB") && GvIO(SvRV(*hitem))) ) {
SV *fn = uwsgi_perl_obj_call(*hitem, "fileno");
wsgi_req->sendfile_fd = SvIV(fn);
SvREFCNT_dec(fn);
wsgi_req->response_size += uwsgi_sendfile(wsgi_req);
// no need to close here as perl GC will do the close()
return UWSGI_OK;
if (fn) {
if (SvTYPE(fn) == SVt_IV && SvIV(fn) >= 0) {
wsgi_req->sendfile_fd = SvIV(fn);
SvREFCNT_dec(fn);
wsgi_req->response_size += uwsgi_sendfile(wsgi_req);
// no need to close here as perl GC will do the close()
return UWSGI_OK;
}
SvREFCNT_dec(fn);
}
}
// check for path method
if (uwsgi_perl_obj_can(*hitem, "path", 4)) {
SV *p = uwsgi_perl_obj_call(*hitem, "path");
wsgi_req->sendfile_fd = open(SvPV_nolen(p), O_RDONLY);
@@ -167,6 +174,7 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
internal_server_error(wsgi_req, "exception raised");
break;
}
chitem = SvPV( chunk, hlen);
#ifdef UWSGI_ASYNC
if (uwsgi.async > 1 && wsgi_req->async_force_again) {
@@ -191,6 +199,7 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
#endif
}
SV *closed = uwsgi_perl_obj_call(*hitem, "close");
if (closed) {
SvREFCNT_dec(closed);