You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axkit-dev@xml.apache.org by ma...@sergeant.org on 2006/08/02 22:42:06 UTC

[SVN] [31] Querystring parsing

Revision: 31
Author:   matt
Date:     2006-08-02 20:41:47 +0000 (Wed, 02 Aug 2006)

Log Message:
-----------
Querystring parsing

Modified Paths:
--------------
    trunk/demo/xsp/test.xsp
    trunk/lib/AxKit2/HTTPHeaders.pm
    trunk/lib/AxKit2/Transformer/XSP.pm
    trunk/lib/AxKit2/Utils.pm

Modified: trunk/demo/xsp/test.xsp
===================================================================
--- trunk/demo/xsp/test.xsp	2006-08-02 19:50:37 UTC (rev 30)
+++ trunk/demo/xsp/test.xsp	2006-08-02 20:41:47 UTC (rev 31)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<xsp:page xmlns:xsp="http://apache.org/xsp/core/v1">
+<xsp:page xmlns:xsp="http://apache.org/xsp/core/v1" indent-result="yes">
     <output>
         Hello World. The time of request is:
         <xsp:expr>scalar localtime</xsp:expr>
@@ -8,5 +8,13 @@
                 { abc => 42, xyz => { goofy => "yes", ugly => "no" } };
             </xsp:expr>
         </structure>
+        <querystring>
+            <xsp:expr>
+                [
+                    map { {key => $_, value => [ $cgi->headers_in->param($_) ] } }
+                        $cgi->headers_in->param
+                ]
+            </xsp:expr>
+        </querystring>
     </output>
 </xsp:page>

Modified: trunk/lib/AxKit2/HTTPHeaders.pm
===================================================================
--- trunk/lib/AxKit2/HTTPHeaders.pm	2006-08-02 19:50:37 UTC (rev 30)
+++ trunk/lib/AxKit2/HTTPHeaders.pm	2006-08-02 20:41:47 UTC (rev 31)
@@ -9,17 +9,20 @@
 use AxKit2::Utils qw(uri_decode);
 
 use fields (
-            'headers',   # href; lowercase header -> comma-sep list of values
-            'origcase',  # href; lowercase header -> provided case
-            'hdorder',   # aref; order headers were received (canonical order)
-            'method',    # scalar; request method (if GET request)
-            'uri',       # scalar; request URI (if GET request)
-            'file',      # scalar; request File
-            'type',      # 'res' or 'req'
-            'code',      # HTTP response status code
-            'codetext',  # status text that for response code
-            'ver',       # version (string) "1.1"
-            'vernum',    # version (number: major*1000+minor): "1.1" => 1001
+            'headers',      # href; lowercase header -> comma-sep list of values
+            'origcase',     # href; lowercase header -> provided case
+            'hdorder',      # aref; order headers were received (canonical order)
+            'method',       # scalar; request method (if GET request)
+            'uri',          # scalar; request URI (if GET request)
+            'file',         # scalar; request File
+            'querystring',  # scalar: request querystring
+            'params',       # parsed params
+            'paramkeys',    # all parsed param keys
+            'type',         # 'res' or 'req'
+            'code',         # HTTP response status code
+            'codetext',     # status text that for response code
+            'ver',          # version (string) "1.1"
+            'vernum',       # version (number: major*1000+minor): "1.1" => 1001
             'responseLine', # first line of HTTP response (if response)
             'requestLine',  # first line of HTTP request (if request)
             );
@@ -49,12 +52,14 @@
 
     my @lines = split(/\r?\n/, $$hstr_ref);
 
-    $self->{headers} = {};
-    $self->{origcase} = {};
-    $self->{hdorder} = [];
-    $self->{method} = undef;
-    $self->{uri} = undef;
-    $self->{type} = ($is_response ? "res" : "req");
+    $self->{headers}    = {};
+    $self->{origcase}   = {};
+    $self->{hdorder}    = [];
+    $self->{paramkeys}  = [];
+    $self->{params}     = {};
+    $self->{method}     = undef;
+    $self->{uri}        = undef;
+    $self->{type}       = ($is_response ? "res" : "req");
 
     # check request line
     if ($is_response) {
@@ -90,8 +95,8 @@
         if ($self->{uri} =~ m!^http://([^/:]+?)(?::\d+)?(/.*)?$!) {
             $absoluteURIHost = lc($1);
             $self->{uri} = $2 || "/"; # "http://www.foo.com" yields no path, so default to "/"
-            $self->parse_uri;
         }
+        $self->parse_uri;
     
         # default to HTTP/0.9
         unless (defined $ver_ma) {
@@ -170,8 +175,37 @@
 
 sub parse_uri {
     my AxKit2::HTTPHeaders $self = shift;
+    my ($path, $qs) = split(/\?/, $self->{uri});
+    $qs = "" if !defined $qs;
+    my (@item) = split(/[&;]/, $qs);
+    foreach (@item) {
+        my ($key, $value) = split('=',$_,2);
+        next unless defined $key;
+        $value  = '' unless defined $value; # what I wouldn't give for //=
+        $key    = uri_decode($key);
+        $value  = uri_decode($value);
+        push @{$self->{paramkeys}}, $key unless exists $self->{params}{$key};
+        push @{$self->{params}{$key}}, $value;
+    }
 }
 
+sub add_param {
+    my AxKit2::HTTPHeaders $self = shift;
+    my ($key, $value) = @_;
+    $value = '' unless defined $value;
+    push @{$self->{paramkeys}}, $key unless exists $self->{params}{$key};
+    push @{ $self->{params}{$key} }, $value;
+}
+
+# returns all params for a key in LIST context, or the last param for a key in SCALAR
+sub param {
+    my AxKit2::HTTPHeaders $self = shift;
+    my $key = shift;
+    return @{$self->{paramkeys}} unless defined $key;
+    return unless exists $self->{params}{$key};
+    return wantarray ? @{ $self->{params}{$key} } : $self->{params}{$key}[-1];
+}
+
 sub http_code_english {
     my AxKit2::HTTPHeaders $self = shift;
     if (@_) {

Modified: trunk/lib/AxKit2/Transformer/XSP.pm
===================================================================
--- trunk/lib/AxKit2/Transformer/XSP.pm	2006-08-02 19:50:37 UTC (rev 30)
+++ trunk/lib/AxKit2/Transformer/XSP.pm	2006-08-02 20:41:47 UTC (rev 31)
@@ -2,6 +2,7 @@
 
 use strict;
 use warnings;
+no warnings 'uninitialized';
 
 use base qw(AxKit2::Transformer);
 

Modified: trunk/lib/AxKit2/Utils.pm
===================================================================
--- trunk/lib/AxKit2/Utils.pm	2006-08-02 19:50:37 UTC (rev 30)
+++ trunk/lib/AxKit2/Utils.pm	2006-08-02 20:41:47 UTC (rev 31)
@@ -11,10 +11,59 @@
 	my $uri = shift;
 	return '' unless defined $uri;
 	$uri =~ s/\+/ /g;
-	$uri =~ s/%([A-F0-9][A-F0-9])/pack("C", hex($1))/eig;
+    $uri =~ s/
+        %                      # encoded data marker
+        (?:                    # followed by either
+            ([0-9a-fA-F]{2})   # 2 hex chars
+            |                  # or
+            u([0-9a-fA-F]{4})  # 'u' then 4 hex chars
+        )
+        /
+        defined($1) ? chr hex($1) : utf8_chr(hex($2))
+        /gex;
 	return $uri;
 }
 
+# borrowed from CGI::Util which I think borrowed it from XML::DOM...
+sub utf8_chr ($) {
+    my $c = shift(@_);
+
+    if ($c < 0x80) {
+        return sprintf("%c", $c);
+    } elsif ($c < 0x800) {
+        return sprintf("%c%c", 0xc0 | ($c >> 6), 0x80 | ($c & 0x3f));
+    } elsif ($c < 0x10000) {
+        return sprintf("%c%c%c",
+                               0xe0 |  ($c >> 12),
+                               0x80 | (($c >>  6) & 0x3f),
+                               0x80 | ( $c          & 0x3f));
+    } elsif ($c < 0x200000) {
+        return sprintf("%c%c%c%c",
+                               0xf0 |  ($c >> 18),
+                               0x80 | (($c >> 12) & 0x3f),
+                               0x80 | (($c >>  6) & 0x3f),
+                               0x80 | ( $c          & 0x3f));
+    } elsif ($c < 0x4000000) {
+        return sprintf("%c%c%c%c%c",
+                               0xf8 |  ($c >> 24),
+                               0x80 | (($c >> 18) & 0x3f),
+                               0x80 | (($c >> 12) & 0x3f),
+                               0x80 | (($c >>  6) & 0x3f),
+                               0x80 | ( $c          & 0x3f));
+
+    } elsif ($c < 0x80000000) {
+        return sprintf("%c%c%c%c%c%c",
+                               0xfe |  ($c >> 30),
+                               0x80 | (($c >> 24) & 0x3f),
+                               0x80 | (($c >> 18) & 0x3f),
+                               0x80 | (($c >> 12) & 0x3f),
+                               0x80 | (($c >> 6)  & 0x3f),
+                               0x80 | ( $c          & 0x3f));
+    } else {
+        return utf8(0xfffd);
+    }
+}
+
 sub http_date {
     my $time = shift;
     $time = time unless defined $time;