SV *PerlIONginxInput_newhandle(pTHX_ ngx_http_request_t *r)
{
    ngx_log_t *log = r->connection->log;

    GV *gv = (GV*)SvREFCNT_inc(newGVgen("Nginx::PSGI::Input"));
    if (!gv)
        return &PL_sv_undef;

    (void) hv_delete(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), G_DISCARD);

    /* Body in memory */
    if (r->request_body == NULL || r->request_body->temp_file == NULL) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "Open filehandle with 'ngx_input' layer to read from buffers");

        PerlIO *f = PerlIO_allocate(aTHX);

        if (!(f = PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_nginx_input), "<", NULL)) ) {
            ngx_log_error(NGX_LOG_ERR, log, 0,
                    "Error pushing layer to FH"
                    );
            return &PL_sv_undef;
        }

        if (!do_open(gv, "+<&", 3, FALSE, O_RDONLY, 0, f)) {
            ngx_log_error(NGX_LOG_ERR, log, 0,
                    "Error opening GV"
                    );
            // FIXME PerlIO_close
            return &PL_sv_undef;
        }

        PerlIONginxInput *st = PerlIOSelf(f, PerlIONginxInput);
        st->r = r;

    } else {
        /* Body in temp file */

        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "Open PSGI request body temp file '%s'",
                r->request_body->temp_file->file.name.data
                );
        bool result = do_open(gv,(char*)r->request_body->temp_file->file.name.data, r->request_body->temp_file->file.name.len,FALSE,O_RDONLY,0,NULL);

        if (!result) {
            ngx_log_error(NGX_LOG_ERR, log, 0,
                    "Error opening file"
                    );
            // FIXME PerlIO_close
            return NULL;

        }
    }

    return (SV*)newRV_noinc((SV *)gv);
}
Ejemplo n.º 2
0
SV *
PerlIOVia_method(pTHX_ PerlIO * f, char *method, CV ** save, int flags,
		 ...)
{
    PerlIOVia *s = PerlIOSelf(f, PerlIOVia);
    CV *cv =
	(*save) ? *save : PerlIOVia_fetchmethod(aTHX_ s, method, save);
    SV *result = Nullsv;
    va_list ap;
    va_start(ap, flags);
    if (cv != (CV *) - 1) {
	IV count;
	dSP;
	SV *arg;
	PUSHSTACKi(PERLSI_MAGIC);
	ENTER;
	SPAGAIN;
	PUSHMARK(sp);
	XPUSHs(s->obj);
	while ((arg = va_arg(ap, SV *))) {
	    XPUSHs(arg);
	}
	if (*PerlIONext(f)) {
	    if (!s->fh) {
		GV *gv = newGVgen(HvNAME(s->stash));
		GvIOp(gv) = newIO();
		s->fh = newRV_noinc((SV *) gv);
		s->io = GvIOp(gv);
	    }
	    IoIFP(s->io) = PerlIONext(f);
	    IoOFP(s->io) = PerlIONext(f);
	    XPUSHs(s->fh);
	}
	else {
	    PerlIO_debug("No next\n");
	    /* FIXME: How should this work for OPEN etc? */
	}
	PUTBACK;
	count = call_sv((SV *) cv, flags);
	if (count) {
	    SPAGAIN;
	    result = POPs;
	    PUTBACK;
	}
	else {
	    result = &PL_sv_undef;
	}
	LEAVE;
	POPSTACK;
    }
Ejemplo n.º 3
0
SV *PerlIONginxError_newhandle(pTHX_ ngx_http_request_t *r)
{
    GV *gv = (GV*)SvREFCNT_inc(newGVgen("Nginx::PSGI::Error"));
    if (!gv)
        return &PL_sv_undef;

    (void) hv_delete(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), G_DISCARD);
    PerlIO *f = PerlIO_allocate(aTHX);

    if (!(f = PerlIO_push(aTHX_ f, PERLIO_FUNCS_CAST(&PerlIO_nginx_error), ">", NULL)) ) {
         return &PL_sv_undef;
    }

    if (!do_open(gv, "+>&", 3, FALSE, O_WRONLY, 0, f)) {
        return &PL_sv_undef;
    }

    PerlIONginxError *st = PerlIOSelf(f, PerlIONginxError);
    st->log = r->connection->log;

    return newRV_noinc((SV*)gv);
}