Author: joes
Date: Wed Feb 23 13:47:52 2005
New Revision: 155078
URL: http://svn.apache.org/viewcvs?view=rev&rev=155078
Log:
Change v->size semantics: now it represents the total
amount of memory appended to the apreq_value_t struct.
Added supporting apreq_param_nlen(), apreq_param_vlen(),
apreq_param_size(), apreq_cookie_nlen(), apreq_cookie_vlen(),
apreq_cookie_size(), apreq_value_table_add().
Also a few more performance tweaks for the new perl APIs.
Added:
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Cookie/APR__Request__Cookie.h
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Param/APR__Request__Param.h
Modified:
httpd/apreq/branches/multi-env-unstable/CHANGES
httpd/apreq/branches/multi-env-unstable/glue/perl/lib/Apache/Cookie.pm
httpd/apreq/branches/multi-env-unstable/glue/perl/lib/Apache/Request.pm
httpd/apreq/branches/multi-env-unstable/glue/perl/t/response/TestAPI/cookie.pm
httpd/apreq/branches/multi-env-unstable/glue/perl/t/response/TestAPI/param.pm
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Apache2/APR__Request__Apache2.h
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Cookie/Cookie.xs
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Param/Param.xs
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/apreq_xs_postperl.h
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/apreq_xs_tables.h
httpd/apreq/branches/multi-env-unstable/include/apreq.h
httpd/apreq/branches/multi-env-unstable/include/apreq_cookie.h
httpd/apreq/branches/multi-env-unstable/include/apreq_param.h
httpd/apreq/branches/multi-env-unstable/include/apreq_parser.h
httpd/apreq/branches/multi-env-unstable/library/cookie.c
httpd/apreq/branches/multi-env-unstable/library/param.c
httpd/apreq/branches/multi-env-unstable/library/parser_header.c
httpd/apreq/branches/multi-env-unstable/library/parser_multipart.c
httpd/apreq/branches/multi-env-unstable/library/parser_urlencoded.c
httpd/apreq/branches/multi-env-unstable/library/t/params.c
httpd/apreq/branches/multi-env-unstable/library/util.c
httpd/apreq/branches/multi-env-unstable/module/test_cgi.c
Modified: httpd/apreq/branches/multi-env-unstable/CHANGES
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/CHANGES?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/CHANGES (original)
+++ httpd/apreq/branches/multi-env-unstable/CHANGES Wed Feb 23 13:47:52 2005
@@ -4,6 +4,12 @@
@section v2_05_dev Changes with libapreq2-2.05-dev
+- C API [joes]
+ Change v->size semantics: now it represents the total
+ amount of memory appended to the apreq_value_t struct.
+ Added supporting apreq_param_nlen(), apreq_param_vlen(),
+ apreq_param_size(), apreq_cookie_nlen(), apreq_cookie_vlen(),
+ apreq_cookie_size(), apreq_value_table_add().
- C API [joes]
Remove apreq_cookie_attr().
Modified: httpd/apreq/branches/multi-env-unstable/glue/perl/lib/Apache/Cookie.pm
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/glue/perl/lib/Apache/Cookie.pm?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/glue/perl/lib/Apache/Cookie.pm
(original)
+++ httpd/apreq/branches/multi-env-unstable/glue/perl/lib/Apache/Cookie.pm Wed
Feb 23 13:47:52 2005
@@ -81,6 +81,6 @@
package Apache::Cookie::Jar;
use APR::Request::Apache2;
push our @ISA, qw/APR::Request::Apache2/;
-sub cookies { shift->jar(@_) }
+sub cookies { Apache::Cookie->fetch(shift) }
1;
Modified:
httpd/apreq/branches/multi-env-unstable/glue/perl/lib/Apache/Request.pm
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/glue/perl/lib/Apache/Request.pm?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/glue/perl/lib/Apache/Request.pm
(original)
+++ httpd/apreq/branches/multi-env-unstable/glue/perl/lib/Apache/Request.pm Wed
Feb 23 13:47:52 2005
@@ -1,4 +1,5 @@
package Apache::Request;
+use APR::Request::Param;
use APR::Request::Apache2;
use Apache::RequestRec;
push our @ISA, qw/Apache::RequestRec APR::Request::Apache2/;
Modified:
httpd/apreq/branches/multi-env-unstable/glue/perl/t/response/TestAPI/cookie.pm
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/glue/perl/t/response/TestAPI/cookie.pm?view=diff&r1=155077&r2=155078
==============================================================================
---
httpd/apreq/branches/multi-env-unstable/glue/perl/t/response/TestAPI/cookie.pm
(original)
+++
httpd/apreq/branches/multi-env-unstable/glue/perl/t/response/TestAPI/cookie.pm
Wed Feb 23 13:47:52 2005
@@ -12,7 +12,7 @@
sub handler {
my $r = shift;
- plan $r, tests => 28;
+ plan $r, tests => 30;
$r->headers_in->{Cookie} = "foo=1;bar=2;foo=3;quux=4";
my $req = APR::Request::Apache2->new($r);
@@ -46,6 +46,7 @@
ok t_cmp join(" ", $jar->get("foo")), "1 3", '$jar->get("foo")';
+ ok not defined $jar->cookie_class("APR::Request::Cookie");
ok t_cmp $_->tainted, 1, "is tainted: $_" for values %$jar;
$_->tainted(0) for values %$jar;
ok t_cmp $_->tainted, 0, "not tainted: $_" for values %$jar;
@@ -53,7 +54,7 @@
eval { $jar->cookie_class("APR::Request::Param") };
ok t_cmp qr/^Usage/, $@, "Bad class name";
- $jar->cookie_class(__PACKAGE__);
+ ok t_cmp $jar->cookie_class(__PACKAGE__), "APR::Request::Cookie", "class
upgrade";
ok $jar->{foo}->isa(__PACKAGE__);
return 0;
Modified:
httpd/apreq/branches/multi-env-unstable/glue/perl/t/response/TestAPI/param.pm
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/glue/perl/t/response/TestAPI/param.pm?view=diff&r1=155077&r2=155078
==============================================================================
---
httpd/apreq/branches/multi-env-unstable/glue/perl/t/response/TestAPI/param.pm
(original)
+++
httpd/apreq/branches/multi-env-unstable/glue/perl/t/response/TestAPI/param.pm
Wed Feb 23 13:47:52 2005
@@ -13,7 +13,7 @@
sub handler {
my $r = shift;
- plan $r, tests => 28;
+ plan $r, tests => 30;
$r->args("foo=1;bar=2;foo=3;quux=4");
my $req = APR::Request::Apache2->new($r);
@@ -46,6 +46,7 @@
ok t_cmp join(" ", $args->get("foo")), "1 3", '$args->get("foo")';
+ ok not defined $args->param_class("APR::Request::Param");
ok t_cmp $_->tainted, 1, "is tainted: $_" for values %$args;
$_->tainted(0) for values %$args;
ok t_cmp $_->tainted, 0, "not tainted: $_" for values %$args;
@@ -54,7 +55,7 @@
eval { $args->param_class("APR::Request::Cookie") };
ok t_cmp qr/^Usage/, $@, "Bad class name";
- $args->param_class(__PACKAGE__);
+ ok t_cmp $args->param_class(__PACKAGE__), "APR::Request::Param", "class
upgrade";
ok $args->{foo}->isa(__PACKAGE__);
return 0;
Modified:
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Apache2/APR__Request__Apache2.h
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Apache2/APR__Request__Apache2.h?view=diff&r1=155077&r2=155078
==============================================================================
---
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Apache2/APR__Request__Apache2.h
(original)
+++
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Apache2/APR__Request__Apache2.h
Wed Feb 23 13:47:52 2005
@@ -1,6 +1,80 @@
#include "mod_perl.h"
#include "apreq_xs_tables.h"
-#define TABLE_CLASS "APR::Request::Param"
+#define TABLE_CLASS "APR::Request::Param::Table"
+
+
+
+#if (PERL_VERSION >= 8) /* MAGIC ITERATOR REQUIRES 5.8 */
+
+/* Requires perl 5.8 or better.
+ * A custom MGVTBL with its "copy" slot filled allows
+ * us to FETCH a table entry immediately during iteration.
+ * For multivalued keys this is essential in order to get
+ * the value corresponding to the current key, otherwise
+ * values() will always report the first value repeatedly.
+ * With this MGVTBL the keys() list always matches up with
+ * the values() list, even in the multivalued case.
+ * We only prefetch the value during iteration, because the
+ * prefetch adds overhead to EXISTS and STORE operations.
+ * They are only "penalized" when the perl program is iterating
+ * via each(), which seems to be a reasonable tradeoff.
+ */
+
+static int apreq_xs_table_magic_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv,
+ const char *name, int namelen)
+{
+ /* Prefetch the value whenever the table iterator is > 0 */
+ MAGIC *tie_magic = mg_find(nsv, PERL_MAGIC_tiedelem);
+ SV *obj = SvRV(tie_magic->mg_obj);
+ IV idx = SvIVX(obj);
+ const apr_table_t *t = INT2PTR(apr_table_t *, idx);
+ const apr_array_header_t *arr = apr_table_elts(t);
+
+ idx = SvCUR(obj);
+
+ if (idx > 0 && idx <= arr->nelts) {
+ const apr_table_entry_t *te = (const apr_table_entry_t *)arr->elts;
+ const char *param_class = mg_find(obj, PERL_MAGIC_ext)->mg_ptr;
+ apreq_param_t *p = apreq_value_to_param(te[idx-1].val);
+
+ SvMAGICAL_off(nsv);
+ sv_setsv(nsv, sv_2mortal(apreq_xs_param2sv(aTHX_ p, param_class,
obj)));
+ }
+
+ return 0;
+}
+
+static const MGVTBL apreq_xs_table_magic = {0, 0, 0, 0, 0,
+ apreq_xs_table_magic_copy};
+
+#endif
+
+static APR_INLINE
+SV *apreq_xs_table2sv(pTHX_ const apr_table_t *t, const char *class, SV
*parent,
+ const char *value_class, I32 vclen)
+{
+ SV *sv = (SV *)newHV();
+ SV *rv = sv_setref_pv(newSV(0), class, (void *)t);
+ sv_magic(SvRV(rv), parent, PERL_MAGIC_ext, value_class, vclen);
+
+#if (PERL_VERSION >= 8) /* MAGIC ITERATOR requires 5.8 */
+
+ sv_magic(sv, NULL, PERL_MAGIC_ext, Nullch, -1);
+ SvMAGIC(sv)->mg_virtual = (MGVTBL *)&apreq_xs_table_magic;
+ SvMAGIC(sv)->mg_flags |= MGf_COPY;
+
+#endif
+
+ sv_magic(sv, rv, PERL_MAGIC_tied, Nullch, 0);
+ SvREFCNT_dec(rv); /* corrects SvREFCNT_inc(rv) implicit in sv_magic */
+
+ return sv_bless(newRV_noinc(sv), SvSTASH(SvRV(rv)));
+}
+
+
+
+
+
static int apreq_xs_table_keys(void *data, const char *key, const char *val)
{
@@ -8,7 +82,7 @@
dTHXa(d->perl);
dSP;
apreq_param_t *p = apreq_value_to_param(val);
- SV *sv = newSVpv(key, 0);
+ SV *sv = newSVpvn(key, apreq_param_nlen(p));
if (apreq_param_is_tainted(p))
SvTAINTED_on(sv);
@@ -64,10 +138,6 @@
const apr_table_t *t;
r = modperl_xs_sv2request_rec(aTHX_ sv, "Apache::RequestRec", cv);
- t = apreq_params(req, r->pool);
-
- if (t == NULL)
- XSRETURN_EMPTY;
d.pkg = NULL;
d.parent = obj;
@@ -77,21 +147,38 @@
case G_ARRAY:
XSprePUSH;
PUTBACK;
- if (items == 1)
- apr_table_do(apreq_xs_table_keys, &d, t, NULL);
- else
- apr_table_do(apreq_xs_table_values, &d, t,
- SvPV_nolen(ST(1)), NULL);
+ if (items == 1) {
+ apreq_args(req, &t);
+ if (t != NULL)
+ apr_table_do(apreq_xs_table_keys, &d, t, NULL);
+ apreq_body(req, &t);
+ if (t != NULL)
+ apr_table_do(apreq_xs_table_keys, &d, t, NULL);
+
+ }
+ else {
+ char *val = SvPV_nolen(ST(1));
+ apreq_args(req, &t);
+ if (t != NULL)
+ apr_table_do(apreq_xs_table_values, &d, t, val, NULL);
+ apreq_body(req, &t);
+ if (t != NULL)
+ apr_table_do(apreq_xs_table_values, &d, t, val, NULL);
+ }
return;
case G_SCALAR:
+ t = apreq_params(req, r->pool);
+ if (t == NULL)
+ XSRETURN_UNDEF;
+
ST(0) = apreq_xs_table2sv(aTHX_ t, TABLE_CLASS, obj,
- PARAM_CLASS, sizeof(PARAM_CLASS) -1);
+ NULL, 0);
sv_2mortal(ST(0));
XSRETURN(1);
default:
- XSRETURN(0);
+ XSRETURN(0);
}
}
}
Added:
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Cookie/APR__Request__Cookie.h
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Cookie/APR__Request__Cookie.h?view=auto&rev=155078
==============================================================================
---
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Cookie/APR__Request__Cookie.h
(added)
+++
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Cookie/APR__Request__Cookie.h
Wed Feb 23 13:47:52 2005
@@ -0,0 +1,68 @@
+
+#if (PERL_VERSION >= 8) /* MAGIC ITERATOR REQUIRES 5.8 */
+
+/* Requires perl 5.8 or better.
+ * A custom MGVTBL with its "copy" slot filled allows
+ * us to FETCH a table entry immediately during iteration.
+ * For multivalued keys this is essential in order to get
+ * the value corresponding to the current key, otherwise
+ * values() will always report the first value repeatedly.
+ * With this MGVTBL the keys() list always matches up with
+ * the values() list, even in the multivalued case.
+ * We only prefetch the value during iteration, because the
+ * prefetch adds overhead to EXISTS and STORE operations.
+ * They are only "penalized" when the perl program is iterating
+ * via each(), which seems to be a reasonable tradeoff.
+ */
+
+static int apreq_xs_table_magic_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv,
+ const char *name, int namelen)
+{
+ /* Prefetch the value whenever the table iterator is > 0 */
+ MAGIC *tie_magic = mg_find(nsv, PERL_MAGIC_tiedelem);
+ SV *obj = SvRV(tie_magic->mg_obj);
+ IV idx = SvIVX(obj);
+ const apr_table_t *t = INT2PTR(apr_table_t *, idx);
+ const apr_array_header_t *arr = apr_table_elts(t);
+
+ idx = SvCUR(obj);
+
+ if (idx > 0 && idx <= arr->nelts) {
+ const apr_table_entry_t *te = (const apr_table_entry_t *)arr->elts;
+ const char *cookie_class = mg_find(obj, PERL_MAGIC_ext)->mg_ptr;
+ apreq_cookie_t *c = apreq_value_to_cookie(te[idx-1].val);
+ SV *parent = mg_find(obj, PERL_MAGIC_ext)->mg_obj;
+
+ SvMAGICAL_off(nsv);
+ sv_setsv(nsv, sv_2mortal(apreq_xs_cookie2sv(aTHX_ c, cookie_class,
parent)));
+ }
+
+ return 0;
+}
+
+static const MGVTBL apreq_xs_table_magic = {0, 0, 0, 0, 0,
+ apreq_xs_table_magic_copy};
+
+#endif
+
+static APR_INLINE
+SV *apreq_xs_table2sv(pTHX_ const apr_table_t *t, const char *class, SV
*parent,
+ const char *value_class, I32 vclen)
+{
+ SV *sv = (SV *)newHV();
+ SV *rv = sv_setref_pv(newSV(0), class, (void *)t);
+ sv_magic(SvRV(rv), parent, PERL_MAGIC_ext, value_class, vclen);
+
+#if (PERL_VERSION >= 8) /* MAGIC ITERATOR requires 5.8 */
+
+ sv_magic(sv, NULL, PERL_MAGIC_ext, Nullch, -1);
+ SvMAGIC(sv)->mg_virtual = (MGVTBL *)&apreq_xs_table_magic;
+ SvMAGIC(sv)->mg_flags |= MGf_COPY;
+
+#endif
+
+ sv_magic(sv, rv, PERL_MAGIC_tied, Nullch, 0);
+ SvREFCNT_dec(rv); /* corrects SvREFCNT_inc(rv) implicit in sv_magic */
+
+ return sv_bless(newRV_noinc(sv), SvSTASH(SvRV(rv)));
+}
Modified:
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Cookie/Cookie.xs
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Cookie/Cookie.xs?view=diff&r1=155077&r2=155078
==============================================================================
---
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Cookie/Cookie.xs
(original)
+++
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Cookie/Cookie.xs
Wed Feb 23 13:47:52 2005
@@ -92,8 +92,7 @@
return;
case G_SCALAR:
- ST(0) = apreq_xs_table2sv(aTHX_ t, TABLE_CLASS, obj,
- COOKIE_CLASS, sizeof(COOKIE_CLASS)-1);
+ ST(0) = apreq_xs_table2sv(aTHX_ t, TABLE_CLASS, obj, NULL, 0);
sv_2mortal(ST(0));
XSRETURN(1);
@@ -159,8 +158,7 @@
d.parent = parent;
XSprePUSH;
PUTBACK;
- apr_table_do(apreq_xs_table_values, &d, t,
- SvPV_nolen(ST(1)), NULL);
+ apr_table_do(apreq_xs_table_values, &d, t, SvPV_nolen(ST(1)), NULL);
}
else
XSRETURN(0);
@@ -219,7 +217,7 @@
/*nada*/
CODE:
- RETVAL = newSVpvn(obj->v.data, obj->v.size);
+ RETVAL = newSVpvn(obj->v.data, apreq_cookie_vlen(obj));
if (apreq_cookie_is_tainted(obj))
SvTAINTED_on(RETVAL);
@@ -249,7 +247,7 @@
APR::Request::Cookie obj
CODE:
- RETVAL = newSVpv(obj->v.name, 0);
+ RETVAL = newSVpvn(obj->v.name, apreq_cookie_nlen(obj));
if (apreq_cookie_is_tainted(obj))
SvTAINTED_on(RETVAL);
@@ -367,20 +365,26 @@
cookie_class(t, newclass=NULL)
APR::Request::Cookie::Table t
char *newclass
+
PREINIT:
SV *obj = apreq_xs_sv2object(aTHX_ ST(0), TABLE_CLASS, 't');
MAGIC *mg = mg_find(obj, PERL_MAGIC_ext);
char *curclass = mg->mg_ptr;
CODE:
- RETVAL = newSVpv(curclass, 0);
- if (items == 2) {
- if (!sv_derived_from(ST(1), curclass))
+ RETVAL = (curclass == NULL) ? &PL_sv_undef : newSVpv(curclass, 0);
+
+ if (newclass != NULL) {
+ if (!sv_derived_from(ST(1), COOKIE_CLASS))
Perl_croak(aTHX_ "Usage: " TABLE_CLASS "::cookie_class($table,
$class): "
- "class %s is not derived from %s", newclass,
curclass);
- Safefree(curclass);
+ "class %s is not derived from " COOKIE_CLASS,
newclass);
mg->mg_ptr = savepv(newclass);
+ mg->mg_len = strlen(newclass);
+
+ if (curclass != NULL)
+ Safefree(curclass);
}
OUTPUT:
RETVAL
+
Added:
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Param/APR__Request__Param.h
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Param/APR__Request__Param.h?view=auto&rev=155078
==============================================================================
---
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Param/APR__Request__Param.h
(added)
+++
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Param/APR__Request__Param.h
Wed Feb 23 13:47:52 2005
@@ -0,0 +1,67 @@
+
+#if (PERL_VERSION >= 8) /* MAGIC ITERATOR REQUIRES 5.8 */
+
+/* Requires perl 5.8 or better.
+ * A custom MGVTBL with its "copy" slot filled allows
+ * us to FETCH a table entry immediately during iteration.
+ * For multivalued keys this is essential in order to get
+ * the value corresponding to the current key, otherwise
+ * values() will always report the first value repeatedly.
+ * With this MGVTBL the keys() list always matches up with
+ * the values() list, even in the multivalued case.
+ * We only prefetch the value during iteration, because the
+ * prefetch adds overhead to EXISTS and STORE operations.
+ * They are only "penalized" when the perl program is iterating
+ * via each(), which seems to be a reasonable tradeoff.
+ */
+
+static int apreq_xs_table_magic_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv,
+ const char *name, int namelen)
+{
+ /* Prefetch the value whenever the table iterator is > 0 */
+ MAGIC *tie_magic = mg_find(nsv, PERL_MAGIC_tiedelem);
+ SV *obj = SvRV(tie_magic->mg_obj);
+ IV idx = SvIVX(obj);
+ const apr_table_t *t = INT2PTR(apr_table_t *, idx);
+ const apr_array_header_t *arr = apr_table_elts(t);
+
+ idx = SvCUR(obj);
+
+ if (idx > 0 && idx <= arr->nelts) {
+ const apr_table_entry_t *te = (const apr_table_entry_t *)arr->elts;
+ const char *param_class = mg_find(obj, PERL_MAGIC_ext)->mg_ptr;
+ apreq_param_t *p = apreq_value_to_param(te[idx-1].val);
+
+ SvMAGICAL_off(nsv);
+ sv_setsv(nsv, sv_2mortal(apreq_xs_param2sv(aTHX_ p, param_class,
obj)));
+ }
+
+ return 0;
+}
+
+static const MGVTBL apreq_xs_table_magic = {0, 0, 0, 0, 0,
+ apreq_xs_table_magic_copy};
+
+#endif
+
+static APR_INLINE
+SV *apreq_xs_table2sv(pTHX_ const apr_table_t *t, const char *class, SV
*parent,
+ const char *value_class, I32 vclen)
+{
+ SV *sv = (SV *)newHV();
+ SV *rv = sv_setref_pv(newSV(0), class, (void *)t);
+ sv_magic(SvRV(rv), parent, PERL_MAGIC_ext, value_class, vclen);
+
+#if (PERL_VERSION >= 8) /* MAGIC ITERATOR requires 5.8 */
+
+ sv_magic(sv, NULL, PERL_MAGIC_ext, Nullch, -1);
+ SvMAGIC(sv)->mg_virtual = (MGVTBL *)&apreq_xs_table_magic;
+ SvMAGIC(sv)->mg_flags |= MGf_COPY;
+
+#endif
+
+ sv_magic(sv, rv, PERL_MAGIC_tied, Nullch, 0);
+ SvREFCNT_dec(rv); /* corrects SvREFCNT_inc(rv) implicit in sv_magic */
+
+ return sv_bless(newRV_noinc(sv), SvSTASH(SvRV(rv)));
+}
Modified:
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Param/Param.xs
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Param/Param.xs?view=diff&r1=155077&r2=155078
==============================================================================
---
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Param/Param.xs
(original)
+++
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/APR/Request/Param/Param.xs
Wed Feb 23 13:47:52 2005
@@ -7,7 +7,7 @@
dTHXa(d->perl);
dSP;
apreq_param_t *p = apreq_value_to_param(val);
- SV *sv = newSVpv(key, 0);
+ SV *sv = newSVpvn(key, apreq_param_nlen(p));
if (apreq_param_is_tainted(p))
SvTAINTED_on(sv);
@@ -94,8 +94,7 @@
return;
case G_SCALAR:
- ST(0) = apreq_xs_table2sv(aTHX_ t, TABLE_CLASS, obj,
- PARAM_CLASS, sizeof(PARAM_CLASS) -1);
+ ST(0) = apreq_xs_table2sv(aTHX_ t, TABLE_CLASS, obj, NULL, 0);
sv_2mortal(ST(0));
XSRETURN(1);
@@ -170,8 +169,7 @@
return;
case G_SCALAR:
- ST(0) = apreq_xs_table2sv(aTHX_ t, TABLE_CLASS, obj,
- PARAM_CLASS, sizeof(PARAM_CLASS)-1);
+ ST(0) = apreq_xs_table2sv(aTHX_ t, TABLE_CLASS, obj, NULL, 0);
sv_2mortal(ST(0));
XSRETURN(1);
@@ -239,8 +237,7 @@
d.parent = parent;
XSprePUSH;
PUTBACK;
- apr_table_do(apreq_xs_table_values, &d, t,
- SvPV_nolen(ST(1)), NULL);
+ apr_table_do(apreq_xs_table_values, &d, t, SvPV_nolen(ST(1)), NULL);
}
else
XSRETURN(0);
@@ -299,7 +296,7 @@
/*nada*/
CODE:
- RETVAL = newSVpvn(obj->v.data, obj->v.size);
+ RETVAL = newSVpvn(obj->v.data, apreq_param_vlen(obj));
if (apreq_param_is_tainted(obj))
SvTAINTED_on(RETVAL);
@@ -329,7 +326,7 @@
APR::Request::Param obj
CODE:
- RETVAL = newSVpv(obj->v.name, 0);
+ RETVAL = newSVpvn(obj->v.name, apreq_param_nlen(obj));
if (apreq_param_is_tainted(obj))
SvTAINTED_on(RETVAL);
@@ -385,19 +382,24 @@
param_class(t, newclass=NULL)
APR::Request::Param::Table t
char *newclass
+
PREINIT:
SV *obj = apreq_xs_sv2object(aTHX_ ST(0), TABLE_CLASS, 't');
MAGIC *mg = mg_find(obj, PERL_MAGIC_ext);
char *curclass = mg->mg_ptr;
CODE:
- RETVAL = newSVpv(curclass, 0);
- if (items == 2) {
- if (!sv_derived_from(ST(1), curclass))
+ RETVAL = (curclass == NULL) ? &PL_sv_undef : newSVpv(curclass, 0);
+
+ if (newclass != NULL) {
+ if (!sv_derived_from(ST(1), PARAM_CLASS))
Perl_croak(aTHX_ "Usage: " TABLE_CLASS "::param_class($table,
$class): "
- "class %s is not derived from %s", newclass,
curclass);
- Safefree(curclass);
+ "class %s is not derived from " PARAM_CLASS,
newclass);
mg->mg_ptr = savepv(newclass);
+ mg->mg_len = strlen(newclass);
+
+ if (curclass != NULL)
+ Safefree(curclass);
}
OUTPUT:
@@ -445,8 +447,7 @@
iv = SvIVX(obj);
req = INT2PTR(apreq_handle_t *, iv);
t = apreq_params(req, pool);
- RETVAL = apreq_xs_table2sv(aTHX_ t, TABLE_CLASS, obj,
- PARAM_CLASS, sizeof(PARAM_CLASS)-1);
+ RETVAL = apreq_xs_table2sv(aTHX_ t, TABLE_CLASS, obj, NULL, 0);
OUTPUT:
RETVAL
Modified:
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/apreq_xs_postperl.h
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/apreq_xs_postperl.h?view=diff&r1=155077&r2=155078
==============================================================================
---
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/apreq_xs_postperl.h
(original)
+++
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/apreq_xs_postperl.h
Wed Feb 23 13:47:52 2005
@@ -142,7 +142,7 @@
const char *class, SV *parent)
{
if (class == NULL) {
- SV *rv = newSVpvn(p->v.data, p->v.size);
+ SV *rv = newSVpvn(p->v.data, apreq_param_vlen(p));
if (apreq_param_is_tainted(p))
SvTAINTED_on(rv);
/*XXX add charset fixups */
@@ -157,7 +157,7 @@
const char *class, SV *parent)
{
if (class == NULL) {
- SV *rv = newSVpvn(c->v.data, c->v.size);
+ SV *rv = newSVpvn(c->v.data, apreq_cookie_vlen(c));
if (apreq_cookie_is_tainted(c))
SvTAINTED_on(rv);
/*XXX add charset fixups? */
Modified:
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/apreq_xs_tables.h
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/apreq_xs_tables.h?view=diff&r1=155077&r2=155078
==============================================================================
---
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/apreq_xs_tables.h
(original)
+++
httpd/apreq/branches/multi-env-unstable/glue/perl/xsbuilder/apreq_xs_tables.h
Wed Feb 23 13:47:52 2005
@@ -21,40 +21,6 @@
#include "ppport.h"
-
-#if (PERL_VERSION >= 8) /* MAGIC ITERATOR REQUIRES 5.8 */
-
-/* Requires perl 5.8 or better.
- * A custom MGVTBL with its "copy" slot filled allows
- * us to FETCH a table entry immediately during iteration.
- * For multivalued keys this is essential in order to get
- * the value corresponding to the current key, otherwise
- * values() will always report the first value repeatedly.
- * With this MGVTBL the keys() list always matches up with
- * the values() list, even in the multivalued case.
- * We only prefetch the value during iteration, because the
- * prefetch adds overhead to EXISTS and STORE operations.
- * They are only "penalized" when the perl program is iterating
- * via each(), which seems to be a reasonable tradeoff.
- */
-
-
-static int apreq_xs_table_magic_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv,
- const char *name, int namelen)
-{
- /* Prefetch the value whenever the table iterator is > 0 */
- MAGIC *tie_magic = mg_find(nsv, PERL_MAGIC_tiedelem);
- SV *obj = SvRV(tie_magic->mg_obj);
- if (SvCUR(obj))
- SvGETMAGIC(nsv);
- return 0;
-}
-
-static const MGVTBL apreq_xs_table_magic = {0, 0, 0, 0, 0,
- apreq_xs_table_magic_copy};
-
-#endif
-
/**
* Converts a C object, with environment, to a TIEHASH object.
* @param obj C object.
@@ -63,27 +29,6 @@
* @return Reference to a new TIEHASH object in class.
*/
-static APR_INLINE
-SV *apreq_xs_table2sv(pTHX_ const apr_table_t *t, const char *class, SV
*parent,
- const char *value_class, I32 vclen)
-{
- SV *sv = (SV *)newHV();
- SV *rv = sv_setref_pv(newSV(0), class, (void *)t);
- sv_magic(SvRV(rv), parent, PERL_MAGIC_ext, value_class, vclen);
-
-#if (PERL_VERSION >= 8) /* MAGIC ITERATOR requires 5.8 */
-
- sv_magic(sv, NULL, PERL_MAGIC_ext, Nullch, -1);
- SvMAGIC(sv)->mg_virtual = (MGVTBL *)&apreq_xs_table_magic;
- SvMAGIC(sv)->mg_flags |= MGf_COPY;
-
-#endif
-
- sv_magic(sv, rv, PERL_MAGIC_tied, Nullch, 0);
- SvREFCNT_dec(rv); /* corrects SvREFCNT_inc(rv) implicit in sv_magic */
-
- return sv_bless(newRV_noinc(sv), SvSTASH(SvRV(rv)));
-}
/*#define apreq_xs_sv2table(sv) ((apr_table_t *) SvIVX(SvRV(sv)))
Modified: httpd/apreq/branches/multi-env-unstable/include/apreq.h
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/include/apreq.h?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/include/apreq.h (original)
+++ httpd/apreq/branches/multi-env-unstable/include/apreq.h Wed Feb 23 13:47:52
2005
@@ -17,6 +17,10 @@
#ifndef APREQ_H
#define APREQ_H
+#ifdef APREQ_DEBUG
+#include <assert.h>
+#endif
+
#include "apr_tables.h"
#include <stddef.h>
@@ -88,9 +92,17 @@
/** @brief libapreq's pre-extensible string type */
typedef struct apreq_value_t {
char *name; /**< value name */
- apr_size_t size; /**< value length (in bytes) */
+ apr_size_t size; /**< total size (nlen + dlen + 1) */
char data[1]; /**< value data */
} apreq_value_t;
+
+static APR_INLINE
+void apreq_value_table_add(const apreq_value_t *v, apr_table_t *t) {
+#ifdef APREQ_DEBUG
+ assert(v->size == (v->name - v->data) + strlen(v->name));
+#endif
+ apr_table_addn(t, v->name, v->data);
+}
#define apreq_attr_to_type(T,A,P) ( (T*) ((char*)(P)-offsetof(T,A)) )
Modified: httpd/apreq/branches/multi-env-unstable/include/apreq_cookie.h
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/include/apreq_cookie.h?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/include/apreq_cookie.h (original)
+++ httpd/apreq/branches/multi-env-unstable/include/apreq_cookie.h Wed Feb 23
13:47:52 2005
@@ -60,6 +60,8 @@
} apreq_cookie_t;
+APREQ_DECLARE(apr_size_t)apreq_cookie_size(const apreq_cookie_t *c);
+
/** Upgrades cookie jar table values to apreq_cookie_t structs. */
static APR_INLINE
@@ -71,6 +73,17 @@
return apreq_attr_to_type(apreq_cookie_t, v,
apreq_attr_to_type(apreq_value_t, data, deconst.out));
}
+
+static APR_INLINE
+apr_size_t apreq_cookie_nlen(const apreq_cookie_t *c) {
+ return c->v.size - (c->v.name - c->v.data);
+}
+
+static APR_INLINE
+apr_size_t apreq_cookie_vlen(const apreq_cookie_t *c) {
+ return (c->v.name - c->v.data) - 1;
+}
+
/[EMAIL PROTECTED] 1 if this is an RFC cookie, 0 if its a Netscape cookie. */
static APR_INLINE
Modified: httpd/apreq/branches/multi-env-unstable/include/apreq_param.h
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/include/apreq_param.h?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/include/apreq_param.h (original)
+++ httpd/apreq/branches/multi-env-unstable/include/apreq_param.h Wed Feb 23
13:47:52 2005
@@ -37,9 +37,21 @@
apr_table_t *info; /**< header table associated with the param */
apr_bucket_brigade *upload; /**< brigade used to spool upload files */
unsigned flags; /**< charsets, taint marks, app-specific bits
*/
- const apreq_value_t v; /**< underlying name/value/status info */
+ const apreq_value_t v; /**< underlying name/value info */
} apreq_param_t;
+static APR_INLINE
+apr_size_t apreq_param_nlen(const apreq_param_t *p) {
+ return p->v.size - (p->v.name - p->v.data);
+}
+
+static APR_INLINE
+apr_size_t apreq_param_vlen(const apreq_param_t *p) {
+ return (p->v.name - p->v.data) - 1;
+}
+
+APREQ_DECLARE(apr_size_t)apreq_param_size(const apreq_param_t *p);
+
/** @return 1 if the taint flag is set, 0 otherwise. */
static APR_INLINE
@@ -72,6 +84,7 @@
}
+
/** creates a param from name/value information */
APREQ_DECLARE(apreq_param_t *) apreq_param_make(apr_pool_t *p,
const char *name,
@@ -92,8 +105,8 @@
APREQ_DECLARE(apr_status_t) apreq_param_decode(apreq_param_t **param,
apr_pool_t *pool,
const char *word,
- const apr_size_t nlen,
- const apr_size_t vlen);
+ apr_size_t nlen,
+ apr_size_t vlen);
/**
* Url-encodes the param into a name-value pair.
Modified: httpd/apreq/branches/multi-env-unstable/include/apreq_parser.h
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/include/apreq_parser.h?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/include/apreq_parser.h (original)
+++ httpd/apreq/branches/multi-env-unstable/include/apreq_parser.h Wed Feb 23
13:47:52 2005
@@ -79,8 +79,6 @@
};
-
-
/**
* Parse the incoming brigade into a table. Parsers normally
* consume all the buckets of the brigade during parsing. However
Modified: httpd/apreq/branches/multi-env-unstable/library/cookie.c
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/library/cookie.c?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/library/cookie.c (original)
+++ httpd/apreq/branches/multi-env-unstable/library/cookie.c Wed Feb 23
13:47:52 2005
@@ -21,11 +21,30 @@
#include "apr_lib.h"
#include "apr_date.h"
+
#define RFC 1
#define NETSCAPE 0
-#define ADD_COOKIE(j,c) apr_table_addn(j, c->v.name, c->v.data)
+#define ADD_COOKIE(j,c) apreq_value_table_add(&c->v, j)
+
+APREQ_DECLARE(apr_size_t)apreq_cookie_size(const apreq_cookie_t *c)
+{
+ apr_size_t alen = 0;
+
+ if (c->path != NULL)
+ alen += strlen(c->path);
+ if (c->domain != NULL)
+ alen += strlen(c->domain);
+ if (c->port != NULL)
+ alen += strlen(c->port);
+ if (c->comment != NULL)
+ alen += strlen(c->comment);
+ if (c->commentURL != NULL)
+ alen += strlen(c->commentURL);
+ return (apr_size_t)alen + c->v.size + sizeof *c;
+
+}
APREQ_DECLARE(void) apreq_cookie_expires(apreq_cookie_t *c,
const char *time_str)
@@ -138,14 +157,15 @@
return NULL;
*(const apreq_value_t **)&v = &c->v;
+ v->size = nlen + vlen + 1;
- v->size = vlen;
-
- memcpy(v->data, value, vlen);
+ if (vlen > 0 && value != NULL)
+ memcpy(v->data, value, vlen);
v->data[vlen] = 0;
v->name = v->data + vlen + 1;
- memcpy (v->name, name, nlen);
+ if (name != NULL)
+ memcpy (v->name, name, nlen);
v->name[nlen] = 0;
/* session cookie is the default */
Modified: httpd/apreq/branches/multi-env-unstable/library/param.c
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/library/param.c?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/library/param.c (original)
+++ httpd/apreq/branches/multi-env-unstable/library/param.c Wed Feb 23 13:47:52
2005
@@ -24,23 +24,32 @@
#define MAX_BRIGADE_LEN (1024 * 256)
#define MAX_READ_AHEAD (1024 * 64)
+
APREQ_DECLARE(apreq_param_t *) apreq_param_make(apr_pool_t *p,
const char *name,
const apr_size_t nlen,
const char *val,
const apr_size_t vlen)
{
- apreq_param_t *param = apr_palloc(p, nlen + vlen + 1 + sizeof *param);
+ apreq_param_t *param;
apreq_value_t *v;
+
+ param = apr_palloc(p, nlen + vlen + 1 + sizeof *param);
+
+ if (param == NULL || nlen == 0)
+ return NULL;
+
param->info = NULL;
param->upload = NULL;
param->flags = 0;
*(const apreq_value_t **)&v = ¶m->v;
- v->size = vlen;
+ v->size = vlen + nlen + 1;
+
if (vlen && val != NULL)
memcpy(v->data, val, vlen);
v->data[vlen] = 0;
+
v->name = v->data + vlen + 1;
if (nlen && name != NULL)
memcpy(v->name, name, nlen);
@@ -49,20 +58,42 @@
return param;
}
+static int elt_size(void *data, const char *key, const char *val)
+{
+ apr_size_t *s = data;
+ *s = strlen(key) + strlen(val);
+ return 1; /* keep searching */
+}
+
+APREQ_DECLARE(apr_size_t)apreq_param_size(const apreq_param_t *p)
+{
+ apr_size_t tlen = 0;
+ apr_off_t blen = 0;
+
+ if (p->info != NULL)
+ apr_table_do(elt_size, &tlen, p->info, NULL);
+ if (p->upload != NULL)
+ apr_brigade_length(p->upload, 0, &blen);
+
+ return (apr_size_t)blen + tlen + p->v.size + sizeof *p;
+
+}
+
APREQ_DECLARE(apr_status_t) apreq_param_decode(apreq_param_t **param,
apr_pool_t *pool,
const char *word,
- const apr_size_t nlen,
- const apr_size_t vlen)
+ apr_size_t nlen,
+ apr_size_t vlen)
{
apr_status_t status;
apreq_value_t *v;
apreq_param_t *p;
- apr_size_t size;
- if (nlen == 0)
+ if (nlen == 0) {
+ *param = NULL;
return APR_EBADARG;
+ }
p = apr_palloc(pool, nlen + vlen + 1 + sizeof *p);
p->info = NULL;
@@ -70,7 +101,7 @@
*(const apreq_value_t **)&v = &p->v;
if (vlen > 0) {
- status = apreq_decode(v->data, &v->size, word + nlen + 1, vlen);
+ status = apreq_decode(v->data, &vlen, word + nlen + 1, vlen);
if (status != APR_SUCCESS) {
*param = NULL;
return status;
@@ -78,33 +109,36 @@
}
else {
v->data[0] = 0;
- v->size = 0;
}
- v->name = v->data + v->size + 1;
+ v->name = v->data + vlen + 1;
+
+ status = apreq_decode(v->name, &nlen, word, nlen);
+ if (status != APR_SUCCESS) {
+ *param = NULL;
+ return status;
+ }
+ v->size = nlen + vlen + 1;
*param = p;
- return apreq_decode(v->name, &size, word, nlen);
+ return APR_SUCCESS;
}
APREQ_DECLARE(char *) apreq_param_encode(apr_pool_t *pool,
const apreq_param_t *param)
{
- apreq_value_t *v;
- apr_size_t nlen;
-
- if (param->v.name == NULL)
- return NULL;
+ apr_size_t dlen, nlen, vlen;
+ char *data;
- nlen = strlen(param->v.name);
+ nlen = apreq_param_nlen(param);
+ vlen = apreq_param_vlen(param);
- v = apr_palloc(pool, 3 * (nlen + param->v.size) + 2 + sizeof *v);
- v->name = param->v.name;
- v->size = apreq_encode(v->data, param->v.name, nlen);
- v->data[v->size++] = '=';
- v->size += apreq_encode(v->data + v->size, param->v.data, param->v.size);
+ data = apr_palloc(pool, 3 * (nlen + vlen) + 2);
+ dlen = apreq_encode(data, param->v.name, nlen);
+ data[dlen++] = '=';
+ dlen += apreq_encode(data + dlen, param->v.data, vlen);
- return v->data;
+ return data;
}
APREQ_DECLARE(apr_status_t) apreq_parse_query_string(apr_pool_t *pool,
@@ -140,7 +174,7 @@
return s;
APREQ_FLAGS_ON(param->flags, APREQ_TAINT);
- apr_table_addn(t, param->v.name, param->v.data);
+ apreq_value_table_add(¶m->v, t);
}
if (*qs == 0)
@@ -205,7 +239,7 @@
apreq_param_t *p = apreq_value_to_param(val);
if (p->upload != NULL)
- apr_table_addn(t, key, val);
+ apreq_value_table_add(&p->v, t);
return 1; /* keep going */
}
Modified: httpd/apreq/branches/multi-env-unstable/library/parser_header.c
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/library/parser_header.c?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/library/parser_header.c (original)
+++ httpd/apreq/branches/multi-env-unstable/library/parser_header.c Wed Feb 23
13:47:52 2005
@@ -13,7 +13,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-
+#include <assert.h>
#include "apreq_parser.h"
#include "apreq_error.h"
#include "apreq_util.h"
@@ -47,91 +47,101 @@
static apr_status_t split_header_line(apreq_param_t **p,
apr_pool_t *pool,
apr_bucket_brigade *bb,
- const apr_size_t nlen,
- const apr_size_t glen,
- const apr_size_t vlen)
+ apr_size_t nlen,
+ apr_size_t glen,
+ apr_size_t vlen)
{
apreq_param_t *param;
apreq_value_t *v;
- apr_size_t off;
+ apr_bucket *e, *f;
+ apr_status_t s;
+ struct iovec vec[APREQ_DEFAULT_NELTS], *iov, *end;
+ apr_array_header_t arr;
+ char *dest;
+ const char *data;
+ apr_size_t dlen;
if (nlen == 0)
return APR_EBADARG;
- param = apreq_param_make(pool, NULL, nlen, NULL, vlen);
+ param = apreq_param_make(pool, NULL, nlen, NULL, vlen - 1); /*drop (CR)LF
*/
*(const apreq_value_t **)&v = ¶m->v;
- off = 0;
- while (off < nlen) {
- apr_size_t dlen;
- const char *data;
- apr_bucket *f = APR_BRIGADE_FIRST(bb);
- apr_status_t s = apr_bucket_read(f, &data, &dlen, APR_BLOCK_READ);
-
- if ( s != APR_SUCCESS )
+ arr.pool = pool;
+ arr.elt_size = sizeof(struct iovec);
+ arr.nelts = 0;
+ arr.nalloc = APREQ_DEFAULT_NELTS;
+ arr.elts = (char *)vec;
+
+ e = APR_BRIGADE_FIRST(bb);
+
+ /* store name in a temporary iovec array */
+
+ while (nlen > 0) {
+ apr_size_t len;
+ end = apr_array_push(&arr);
+ s = apr_bucket_read(e, (const char **)&end->iov_base,
+ &len, APR_BLOCK_READ);
+ if (s != APR_SUCCESS)
return s;
- if (dlen > nlen - off) {
- apr_bucket_split(f, nlen - off);
- dlen = nlen - off;
- }
+ assert(nlen >= len);
+ end->iov_len = len;
+ nlen -= len;
- memcpy(v->name + off, data, dlen);
- off += dlen;
- apr_bucket_delete(f);
+ e = APR_BUCKET_NEXT(e);
}
/* skip gap */
- off = 0;
- while (off < glen) {
- apr_size_t dlen;
- const char *data;
- apr_bucket *f = APR_BRIGADE_FIRST(bb);
- apr_status_t s = apr_bucket_read(f, &data, &dlen, APR_BLOCK_READ);
-
- if ( s != APR_SUCCESS )
+ while (glen > 0) {
+ s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
+ if (s != APR_SUCCESS)
return s;
- if (dlen > glen - off) {
- apr_bucket_split(f, glen - off);
- dlen = glen - off;
- }
-
- off += dlen;
- apr_bucket_delete(f);
+ assert(glen >= dlen);
+ glen -= dlen;
+ e = APR_BUCKET_NEXT(e);
}
/* copy value */
+ assert(vlen > 0);
+ dest = v->data;
+ while (vlen > 0) {
- off = 0;
- while (off < vlen) {
- apr_size_t dlen;
- const char *data;
- apr_bucket *f = APR_BRIGADE_FIRST(bb);
- apr_status_t s = apr_bucket_read(f, &data, &dlen, APR_BLOCK_READ);
-
- if ( s != APR_SUCCESS )
+ s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
+ if (s != APR_SUCCESS)
return s;
- if (dlen > vlen - off) {
- apr_bucket_split(f, vlen - off);
- dlen = vlen - off;
- }
-
- memcpy(v->data + off, data, dlen);
- off += dlen;
- apr_bucket_delete(f);
+ memcpy(dest, data, dlen);
+ dest += dlen;
+ assert(vlen >= dlen);
+ vlen -= dlen;
+ e = APR_BUCKET_NEXT(e);
}
- v->name[nlen] = 0;
+ assert(dest[-1] == '\n');
+
+ if (dest[-2] == '\r')
+ --dest;
+
+ dest[-1] = 0;
- /* remove trailing (CR)LF from value */
- v->size = vlen - 1;
- if ( v->size > 0 && v->data[v->size-1] == '\r')
- v->size--;
+ /* write name */
+ v->name = dest;
+ iov = (struct iovec *)arr.elts;
+
+ while (iov <= end) {
+ memcpy(dest, iov->iov_base, iov->iov_len);
+ dest += iov->iov_len;
+ ++iov;
+ }
+ *dest = 0;
+ v->size = dest - v->data;
+
+ while ((f = APR_BRIGADE_FIRST(bb)) != e)
+ apr_bucket_delete(f);
- v->data[v->size] = 0;
APREQ_FLAGS_ON(param->flags, APREQ_TAINT);
*p = param;
return APR_SUCCESS;
@@ -216,7 +226,14 @@
return APR_SUCCESS;
case ':':
- ++glen;
+ if (off > 1) {
+ apr_bucket_split(e, off - 1);
+ dlen -= off - 1;
+ data += off - 1;
+ off = 1;
+ e = APR_BUCKET_NEXT(e);
+ }
+ ++glen;
ctx->status = HDR_GAP;
goto parse_hdr_bucket;
@@ -244,6 +261,13 @@
default:
ctx->status = HDR_VALUE;
+ if (off > 1) {
+ apr_bucket_split(e, off - 1);
+ dlen -= off - 1;
+ data += off - 1;
+ off = 1;
+ e = APR_BUCKET_NEXT(e);
+ }
++vlen;
goto parse_hdr_bucket;
}
@@ -290,7 +314,7 @@
return s;
}
- apr_table_addn(t, param->v.name, param->v.data);
+ apreq_value_table_add(¶m->v, t);
goto parse_hdr_brigade;
}
Modified: httpd/apreq/branches/multi-env-unstable/library/parser_multipart.c
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/library/parser_multipart.c?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/library/parser_multipart.c
(original)
+++ httpd/apreq/branches/multi-env-unstable/library/parser_multipart.c Wed Feb
23 13:47:52 2005
@@ -500,15 +500,14 @@
return s;
}
len = off;
- param = apreq_param_make(pool, NULL, 0, NULL, len);
+ param = apreq_param_make(pool, ctx->param_name,
+ strlen(ctx->param_name), NULL, len);
APREQ_FLAGS_ON(param->flags, APREQ_TAINT);
param->info = ctx->info;
*(const apreq_value_t **)&v = ¶m->v;
- v->name = ctx->param_name;
apr_brigade_flatten(ctx->bb, v->data, &len);
- v->size = len;
- v->data[v->size] = 0;
+ v->data[len] = 0;
if (parser->hook != NULL) {
s = apreq_hook_run(parser->hook, param, NULL);
@@ -518,7 +517,7 @@
}
}
- apr_table_addn(t, v->name, v->data);
+ apreq_value_table_add(v, t);
ctx->status = MFD_NEXTLINE;
ctx->param_name = NULL;
apr_brigade_cleanup(ctx->bb);
@@ -564,7 +563,7 @@
return s;
}
}
- apr_table_addn(t, param->v.name, param->v.data);
+ apreq_value_table_add(¶m->v, t);
apreq_brigade_setaside(ctx->bb, pool);
s = apreq_brigade_concat(pool, parser->temp_dir,
parser->brigade_limit,
param->upload, ctx->bb);
Modified: httpd/apreq/branches/multi-env-unstable/library/parser_urlencoded.c
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/library/parser_urlencoded.c?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/library/parser_urlencoded.c
(original)
+++ httpd/apreq/branches/multi-env-unstable/library/parser_urlencoded.c Wed Feb
23 13:47:52 2005
@@ -13,10 +13,12 @@
** See the License for the specific language governing permissions and
** limitations under the License.
*/
+
#include "apreq_parser.h"
#include "apreq_util.h"
#include "apreq_error.h"
+
#define PARSER_STATUS_CHECK(PREFIX) do { \
if (ctx->status == PREFIX##_ERROR) \
return APR_EGENERAL; \
@@ -48,10 +50,12 @@
{
apreq_param_t *param;
apreq_value_t *v;
- apr_bucket *e, *end;
+ apr_bucket *e, *f;
apr_status_t s;
struct iovec vec[APREQ_DEFAULT_NELTS];
apr_array_header_t arr;
+ apr_size_t mark;
+
if (nlen == 0)
return APR_EBADARG;
@@ -65,52 +69,65 @@
arr.nalloc = APREQ_DEFAULT_NELTS;
arr.elts = (char *)vec;
- apr_brigade_partition(bb, nlen+1, &end);
+ ++nlen, ++vlen;
+ e = APR_BRIGADE_FIRST(bb);
- for (e = APR_BRIGADE_FIRST(bb); e != end; e = APR_BUCKET_NEXT(e)) {
+ while (!APR_BUCKET_IS_EOS(e)) {
struct iovec *iov = apr_array_push(&arr);
apr_size_t len;
s = apr_bucket_read(e, (const char **)&iov->iov_base,
&len, APR_BLOCK_READ);
if (s != APR_SUCCESS)
return s;
- iov->iov_len = len;
- }
- ((struct iovec *)arr.elts)[arr.nelts - 1].iov_len--; /* drop '=' sign */
+ iov->iov_len = len;
+ nlen -= len;
- s = apreq_decodev(v->name, &nlen,
- (struct iovec *)arr.elts, arr.nelts);
- if (s != APR_SUCCESS)
- return s;
+ e = APR_BUCKET_NEXT(e);
- while ((e = APR_BRIGADE_FIRST(bb)) != end)
- apr_bucket_delete(e);
+ if (nlen == 0) {
+ iov->iov_len--;
+ break;
+ }
+ }
- arr.nelts = 0;
- apr_brigade_partition(bb, vlen + 1, &end);
+ mark = arr.nelts;
- for (e = APR_BRIGADE_FIRST(bb); e != end; e = APR_BUCKET_NEXT(e)) {
+ while (!APR_BUCKET_IS_EOS(e)) {
struct iovec *iov = apr_array_push(&arr);
apr_size_t len;
- s = apr_bucket_read(e, (const char **)&iov->iov_base,
+ s = apr_bucket_read(e, (const char **)&iov->iov_base,
&len, APR_BLOCK_READ);
if (s != APR_SUCCESS)
return s;
+
iov->iov_len = len;
- }
+ vlen -= len;
+
+ e = APR_BUCKET_NEXT(e);
- if (end != APR_BRIGADE_SENTINEL(bb))
- ((struct iovec *)arr.elts)[arr.nelts - 1].iov_len--; /* drop [&;] */
+ if (vlen == 0) {
+ iov->iov_len--;
+ break;
+ }
+
+ }
s = apreq_decodev(v->data, &vlen,
- (struct iovec *)arr.elts, arr.nelts);
+ (struct iovec *)arr.elts + mark, arr.nelts - mark);
+ if (s != APR_SUCCESS)
+ return s;
+ v->name = v->data + vlen + 1;
+
+ s = apreq_decodev(v->name, &nlen, (struct iovec *)arr.elts, mark);
if (s != APR_SUCCESS)
return s;
- while ((e = APR_BRIGADE_FIRST(bb)) != end)
- apr_bucket_delete(e);
+ v->size = nlen + vlen + 1;
+
+ while ((f = APR_BRIGADE_FIRST(bb)) != e)
+ apr_bucket_delete(f);
APREQ_FLAGS_ON(param->flags, APREQ_TAINT);
*p = param;
@@ -159,7 +176,7 @@
s = apreq_hook_run(parser->hook, param, NULL);
if (s == APR_SUCCESS) {
- apr_table_addn(t, param->v.name, param->v.data);
+ apreq_value_table_add(¶m->v, t);
ctx->status = URL_COMPLETE;
}
else {
@@ -185,6 +202,11 @@
while (off < dlen) {
switch (data[off++]) {
case '=':
+ apr_bucket_split(e, off);
+ dlen -= off;
+ data += off;
+ off = 0;
+ e = APR_BUCKET_NEXT(e);
ctx->status = URL_VALUE;
goto parse_url_bucket;
default:
@@ -199,6 +221,7 @@
switch (data[off++]) {
case '&':
case ';':
+ apr_bucket_split(e, off);
s = split_urlword(¶m, pool, ctx->bb, nlen, vlen);
if (parser->hook != NULL && s == APR_SUCCESS)
s = apreq_hook_run(parser->hook, param, NULL);
@@ -208,7 +231,7 @@
return s;
}
- apr_table_addn(t, param->v.name, param->v.data);
+ apreq_value_table_add(¶m->v, t);
goto parse_url_brigade;
default:
Modified: httpd/apreq/branches/multi-env-unstable/library/t/params.c
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/library/t/params.c?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/library/t/params.c (original)
+++ httpd/apreq/branches/multi-env-unstable/library/t/params.c Wed Feb 23
13:47:52 2005
@@ -27,8 +27,6 @@
static apr_table_t *args;
static apr_pool_t *p;
-#define strtoval(s) \
- ((const apreq_value_t *)(s - offsetof(apreq_value_t, data)))
static void request_make(dAT)
{
@@ -44,14 +42,14 @@
static void request_args_get(dAT)
{
const char *val;
- const apreq_value_t *v;
+ const apreq_param_t *param;
AT_str_eq(apr_table_get(args,"a"), "1");
val = apr_table_get(args,"quux");
AT_str_eq(val, "foo bar");
- v = strtoval(val);
- AT_int_eq(v->size, 7);
+ param = apreq_value_to_param(val);
+ AT_int_eq(apreq_param_vlen(param), 7);
AT_str_eq(apr_table_get(args,"plus"), "+");
AT_str_eq(apr_table_get(args,"uplus"), "+");
@@ -148,7 +146,7 @@
param = apreq_param_make(p, name, nlen, val, vlen);
AT_str_eq(param->v.name, name);
- AT_int_eq(param->v.size, vlen);
+ AT_int_eq(apreq_param_vlen(param), vlen);
AT_str_eq(param->v.data, val);
encode = apreq_param_encode(p, param);
@@ -157,7 +155,7 @@
s = apreq_param_decode(&decode, p, encode, nlen, vlen+2);
AT_int_eq(s, APR_SUCCESS);
AT_str_eq(decode->v.name, name);
- AT_int_eq(decode->v.size, vlen);
+ AT_int_eq(apreq_param_vlen(decode), vlen);
AT_str_eq(decode->v.data, val);
}
Modified: httpd/apreq/branches/multi-env-unstable/library/util.c
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/library/util.c?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/library/util.c (original)
+++ httpd/apreq/branches/multi-env-unstable/library/util.c Wed Feb 23 13:47:52
2005
@@ -23,7 +23,6 @@
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
#define MAX(a,b) ( (a) > (b) ? (a) : (b) )
-
/* used for specifying file sizes */
APREQ_DECLARE(apr_int64_t) apreq_atoi64f(const char *s)
@@ -394,13 +393,16 @@
}
+#define apreq_value_nlen(v) (v->size - (v->name - v->data))
+#define apreq_value_vlen(v) ((v->name - v->data) - 1)
+
APREQ_DECLARE(char *) apreq_join(apr_pool_t *p,
const char *sep,
const apr_array_header_t *arr,
apreq_join_t mode)
{
apr_ssize_t len, slen;
- apreq_value_t *rv;
+ char *rv;
const apreq_value_t **a = (const apreq_value_t **)arr->elts;
char *d;
const int n = arr->nelts;
@@ -412,7 +414,7 @@
return NULL;
for (j=0, len=0; j < n; ++j)
- len += a[j]->size + slen;
+ len += apreq_value_vlen(a[j]) + slen;
/* Allocated the required space */
@@ -428,32 +430,29 @@
break;
}
- rv = apr_palloc(p, len + sizeof *rv);
- rv->name = 0;
- rv->size = 0;
- rv->data[0] = 0;
+ rv = apr_palloc(p, len);
if (n == 0)
- return rv->data;
+ return rv;
/* Pass two --- copy the argument strings into the result space */
- d = rv->data;
+ d = rv;
switch (mode) {
case APREQ_JOIN_ENCODE:
- d += apreq_encode(d, a[0]->data, a[0]->size);
+ d += apreq_encode(d, a[0]->data, apreq_value_vlen(a[0]));
for (j = 1; j < n; ++j) {
memcpy(d, sep, slen);
d += slen;
- d += apreq_encode(d, a[j]->data, a[j]->size);
+ d += apreq_encode(d, a[j]->data, apreq_value_vlen(a[j]));
}
break;
case APREQ_JOIN_DECODE:
- if (apreq_decode(d, &len, a[0]->data, a[0]->size))
+ if (apreq_decode(d, &len, a[0]->data, apreq_value_vlen(a[0])))
return NULL;
else
d += len;
@@ -462,7 +461,7 @@
memcpy(d, sep, slen);
d += slen;
- if (apreq_decode(d, &len, a[j]->data, a[j]->size))
+ if (apreq_decode(d, &len, a[j]->data, apreq_value_vlen(a[j])))
return NULL;
else
d += len;
@@ -472,25 +471,25 @@
case APREQ_JOIN_QUOTE:
- d += apreq_quote_once(d, a[0]->data, a[0]->size);
+ d += apreq_quote_once(d, a[0]->data, apreq_value_vlen(a[0]));
for (j = 1; j < n; ++j) {
memcpy(d, sep, slen);
d += slen;
- d += apreq_quote_once(d, a[j]->data, a[j]->size);
+ d += apreq_quote_once(d, a[j]->data, apreq_value_vlen(a[j]));
}
break;
case APREQ_JOIN_AS_IS:
- memcpy(d,a[0]->data,a[0]->size);
- d += a[0]->size;
+ memcpy(d,a[0]->data,apreq_value_vlen(a[0]));
+ d += apreq_value_vlen(a[0]);
for (j = 1; j < n ; ++j) {
memcpy(d, sep, slen);
d += slen;
- memcpy(d, a[j]->data, a[j]->size);
- d += a[j]->size;
+ memcpy(d, a[j]->data, apreq_value_vlen(a[j]));
+ d += apreq_value_vlen(a[j]);
}
break;
@@ -499,8 +498,7 @@
}
*d = 0;
- rv->size = d - rv->data;
- return rv->data;
+ return rv;
}
APR_INLINE
Modified: httpd/apreq/branches/multi-env-unstable/module/test_cgi.c
URL:
http://svn.apache.org/viewcvs/httpd/apreq/branches/multi-env-unstable/module/test_cgi.c?view=diff&r1=155077&r2=155078
==============================================================================
--- httpd/apreq/branches/multi-env-unstable/module/test_cgi.c (original)
+++ httpd/apreq/branches/multi-env-unstable/module/test_cgi.c Wed Feb 23
13:47:52 2005
@@ -24,7 +24,7 @@
static int dump_table(void *count, const char *key, const char *value)
{
int *c = (int *) count;
- int value_len = apreq_value_to_param(value)->v.size;
+ int value_len = key - value - 1; /* == strlen(value) by construction */
if (value_len)
*c += strlen(key) + value_len;
return 1;
@@ -105,7 +105,8 @@
apr_file_printf(out, "%s", "Content-Type: text/plain\n\n");
dest = apr_pcalloc(pool, cookie->v.size + 1);
- if (apreq_decode(dest, &dlen, cookie->v.data, cookie->v.size) ==
APR_SUCCESS)
+ if (apreq_decode(dest, &dlen, cookie->v.data,
+ apreq_cookie_vlen(cookie)) == APR_SUCCESS)
apr_file_printf(out, "%s", dest);
else {
// apreq_log(APREQ_ERROR APR_EGENERAL, env,