| #include "apache_request.h" |
| #include "mod_perl.h" |
| |
| typedef ApacheRequest * Apache__Request; |
| typedef ApacheUpload * Apache__Upload; |
| |
| #define ApacheUpload_fh(upload) upload->fp |
| #define ApacheUpload_size(upload) upload->size |
| #define ApacheUpload_name(upload) upload->name |
| #define ApacheUpload_filename(upload) upload->filename |
| #define ApacheUpload_next(upload) upload->next |
| |
| #ifndef PerlLIO_dup |
| #define PerlLIO_dup(fd) dup((fd)) |
| #endif |
| #ifndef PerlLIO_close |
| #define PerlLIO_close(fd) close((fd)) |
| #endif |
| |
| static char *r_keys[] = { "_r", "r", NULL }; |
| |
| static SV *r_key_sv(SV *in) |
| { |
| SV *sv; |
| int i; |
| |
| for (i=0; r_keys[i]; i++) { |
| int klen = strlen(r_keys[i]); |
| if(hv_exists((HV*)SvRV(in), r_keys[i], klen) && |
| (sv = *hv_fetch((HV*)SvRV(in), |
| r_keys[i], klen, FALSE))) |
| { |
| return sv; |
| } |
| } |
| |
| return Nullsv; |
| } |
| |
| static ApacheRequest *sv_2apreq(SV *sv) |
| { |
| if (SvROK(sv) && sv_derived_from(sv, "Apache::Request")) { |
| SV *obj; |
| |
| switch (SvTYPE(SvRV(sv))) { |
| case SVt_PVHV : |
| obj = r_key_sv(sv); |
| break; |
| default: |
| obj = sv; |
| }; |
| return (ApacheRequest *)SvIV((SV*)SvRV(obj)); |
| } |
| else { |
| return ApacheRequest_new(perl_request_rec(NULL)); |
| } |
| } |
| |
| static SV *upload_bless(ApacheUpload *upload) |
| { |
| SV *sv = newSV(0); |
| sv_setref_pv(sv, "Apache::Upload", (void*)upload); |
| return sv; |
| } |
| |
| #define upload_push(upload) \ |
| XPUSHs(sv_2mortal(upload_bless(upload))) |
| |
| static void apreq_add_magic(SV *sv, ApacheRequest *req) |
| { |
| sv_magic(SvRV(sv), Nullsv, '~', (char *)req->r, sizeof(request_rec)); |
| } |
| |
| static void apreq_close_handle(void *data) |
| { |
| GV *handle = (GV*)data; |
| (void)hv_delete(GvSTASH(handle), |
| GvNAME(handle), GvNAMELEN(handle), G_DISCARD); |
| } |
| |
| #ifdef CGI_COMPAT |
| static void register_uploads (ApacheRequest *req) { |
| ApacheUpload *upload; |
| |
| for (upload = req->upload; upload; upload = upload->next) { |
| if(upload->fp && upload->filename) { |
| GV *gv = gv_fetchpv(upload->filename, TRUE, SVt_PVIO); |
| if (do_open(gv, "<&", 2, FALSE, 0, 0, upload->fp)) { |
| ap_register_cleanup(req->r->pool, (void*)gv, |
| apreq_close_handle, ap_null_cleanup); |
| } |
| } |
| } |
| } |
| #else |
| #define register_uploads(req) |
| #endif |
| |
| MODULE = Apache::Request PACKAGE = Apache::Request PREFIX = ApacheRequest_ |
| |
| PROTOTYPES: DISABLE |
| |
| BOOT: |
| av_push(perl_get_av("Apache::Request::ISA",TRUE), newSVpv("Apache",6)); |
| |
| Apache::Request |
| ApacheRequest_new(class, r, ...) |
| SV *class |
| Apache r |
| |
| PREINIT: |
| int i; |
| |
| CODE: |
| class = class; /* -Wall */ |
| RETVAL = ApacheRequest_new(r); |
| register_uploads(RETVAL); |
| |
| for (i=2; i<items; i+=2) { |
| char *key = SvPV(ST(i),na); |
| switch (toLOWER(*key)) { |
| case 'd': |
| if (strcasecmp(key, "disable_uploads") == 0) { |
| RETVAL->disable_uploads = (int)SvIV(ST(i+1)); |
| break; |
| } |
| case 'p': |
| if (strcasecmp(key, "post_max") == 0) { |
| RETVAL->post_max = (int)SvIV(ST(i+1)); |
| break; |
| } |
| default: |
| croak("[libapreq] unknown attribute: `%s'", key); |
| } |
| } |
| |
| OUTPUT: |
| RETVAL |
| |
| CLEANUP: |
| apreq_add_magic(ST(0), RETVAL); |
| |
| char * |
| ApacheRequest_script_name(req) |
| Apache::Request req |
| |
| int |
| ApacheRequest_parse(req) |
| Apache::Request req |
| |
| void |
| ApacheRequest_parms(req) |
| Apache::Request req |
| |
| CODE: |
| ApacheRequest_parse(req); |
| ST(0) = mod_perl_tie_table(req->parms); |
| |
| void |
| ApacheRequest_upload(req, name=NULL) |
| Apache::Request req |
| char *name |
| |
| PREINIT: |
| ApacheUpload *uptr; |
| |
| PPCODE: |
| ApacheRequest_parse(req); |
| if (GIMME == G_SCALAR) { |
| if (name) { |
| uptr = ApacheUpload_find(req->upload, name); |
| if (!uptr) { |
| XSRETURN_UNDEF; |
| } |
| } |
| else { |
| uptr = req->upload; |
| } |
| upload_push(uptr); |
| } |
| else { |
| for (uptr = req->upload; uptr; uptr = uptr->next) { |
| upload_push(uptr); |
| } |
| } |
| |
| char * |
| ApacheRequest_expires(req, time_str) |
| Apache::Request req |
| char *time_str |
| |
| MODULE = Apache::Request PACKAGE = Apache::Upload PREFIX = ApacheUpload_ |
| |
| PROTOTYPES: DISABLE |
| |
| FILE * |
| ApacheUpload_fh(upload) |
| Apache::Upload upload |
| |
| CODE: |
| if (!(RETVAL = ApacheUpload_fh(upload))) { |
| XSRETURN_UNDEF; |
| } |
| |
| OUTPUT: |
| RETVAL |
| |
| CLEANUP: |
| if (ST(0) != &sv_undef) { |
| IO *io = GvIOn((GV*)SvRV(ST(0))); |
| int fd = PerlIO_fileno(IoIFP(io)); |
| FILE *fp; |
| |
| fd = PerlLIO_dup(fd); |
| if (!(fp = PerlIO_fdopen(fd, "r"))) { |
| PerlLIO_close(fd); |
| croak("fdopen failed!"); |
| } |
| fseek(fp, 0, 0); |
| IoIFP(GvIOn((GV*)SvRV(ST(0)))) = fp; |
| ap_register_cleanup(upload->req->r->pool, (void*)SvRV(ST(0)), |
| apreq_close_handle, ap_null_cleanup); |
| } |
| |
| long |
| ApacheUpload_size(upload) |
| Apache::Upload upload |
| |
| char * |
| ApacheUpload_name(upload) |
| Apache::Upload upload |
| |
| char * |
| ApacheUpload_filename(upload) |
| Apache::Upload upload |
| |
| Apache::Upload |
| ApacheUpload_next(upload) |
| Apache::Upload upload |
| |
| const char * |
| ApacheUpload_type(upload) |
| Apache::Upload upload |
| |
| void |
| ApacheUpload_info(upload, key=NULL) |
| Apache::Upload upload |
| char *key |
| |
| CODE: |
| if (key) { |
| const char *val = ApacheUpload_info(upload, key); |
| if (!val) { |
| XSRETURN_UNDEF; |
| } |
| ST(0) = sv_2mortal(newSVpv((char *)val,0)); |
| } |
| else { |
| ST(0) = mod_perl_tie_table(upload->info); |
| } |