CGI/URL mit split in Parameter zerlegen
CGI/URL mit split in Parameter zerlegen
am 11.01.2007 15:13:01 von Helmut Wollmersdorfer
Ich möchte einen String der Form 'key1=value1&key2=value2&key3=value3'
sauber und einfach zerlegen, wobei der Delimiter '&' in value vorkommen
kann. Sonst wäre es mit 'split(/&/,$string)' einfach.
Diese Regex funktioniert einigermassen
print join("\n", split(/&([^&=]+=[^=]+(?=&))/,
'For=foo5&Query=Foo & Bar GmbH&Str=*&Db=*'));
print "\n";
jedoch gibt es dann ein leeres Element im Output
For=foo5
Query=Foo & Bar GmbH
Str=*
&Db=*
und ein '&' als Ãberbleibsel.
Wo hab ich da meine Denkfehler?
Helmut Wollmersdorfer
Re: CGI/URL mit split in Parameter zerlegen
am 11.01.2007 15:21:15 von Frank Seitz
Helmut Wollmersdorfer wrote:
>
> Wo hab ich da meine Denkfehler?
Deine URLs sind nicht sauber encoded.
Eingebettete Zeichen wie & und = sollten als %26
und %3D repräsentiert sein.
GrüÃe
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: CGI/URL mit split in Parameter zerlegen
am 11.01.2007 17:19:42 von ReneeB
Warum nicht die Vars()-Methode von CGI.pm nehmen?
Re: CGI/URL mit split in Parameter zerlegen
am 11.01.2007 18:06:32 von Helmut Wollmersdorfer
Frank Seitz wrote:
> Deine URLs sind nicht sauber encoded.
So kommen sie nun mal daher.
Und das war eigentlich nicht meine Frage.
> Eingebettete Zeichen wie & und = sollten als %26
> und %3D repräsentiert sein.
Ok, wenn wir schon Off Topic sind:
Im von mir erzeugten HTML sind sie sauber encoded,
z.B. als
Das schicke ich dann im Apache 2.2 mittels
RewriteRule ^([^/]*)$
/cgi-bin/Dict?Form=Dict2&Database=*&Query=$1
an mein CGI.
Dort lese ich es mit
$in = $ENV{'QUERY_STRING'};
und da sind die '&' bereits decoded:
Form=Dict2&Database=*&Query=Green & Gold Tanager
Im access.log steht brav drinnen
"GET /Green%20%26%20gold%20tanager HTTP/1.1"
Helmut Wollmersdorfer
Re: CGI/URL mit split in Parameter zerlegen
am 11.01.2007 18:12:15 von Frank Seitz
Helmut Wollmersdorfer wrote:
> Frank Seitz wrote:
>>
>>Deine URLs sind nicht sauber encoded.
>
> So kommen sie nun mal daher.
Das ist schlecht.
> Und das war eigentlich nicht meine Frage.
Weià ich, aber dann kann ich nur sagen:
Die Aufgabe nicht allgemeingültig lösbar.
> Dort lese ich es mit
>
> $in = $ENV{'QUERY_STRING'};
>
> und da sind die '&' bereits decoded:
Das darf und sollte IMO nicht so sein.
Irgendwo ist da ein Bug.
GrüÃe
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: CGI/URL mit split in Parameter zerlegen
am 11.01.2007 18:35:35 von Helmut Wollmersdorfer
ReneeB wrote:
> Warum nicht die Vars()-Methode von CGI.pm nehmen?
Weil die das nicht kann.
Helmut Wollmersdorfer
Re: CGI/URL mit split in Parameter zerlegen
am 11.01.2007 18:42:13 von Helmut Wollmersdorfer
Frank Seitz wrote:
> Helmut Wollmersdorfer wrote:
>> Dort lese ich es mit
>>
>> $in = $ENV{'QUERY_STRING'};
>>
>> und da sind die '&' bereits decoded:
> Das darf und sollte IMO nicht so sein.
> Irgendwo ist da ein Bug.
Jedenfalls nicht in meinem CGI.
Wenn ich die ReWrite Rule nicht triggere, dann kommt es brav encoded an.
Werd mal weiter Apache Doku lesen.
Helmut Wollmersdorfer
Re: CGI/URL mit split in Parameter zerlegen
am 11.01.2007 18:44:30 von Bjoern Hoehrmann
* Helmut Wollmersdorfer wrote in de.comp.lang.perl.misc:
>Das schicke ich dann im Apache 2.2 mittels
>
> RewriteRule ^([^/]*)$
> /cgi-bin/Dict?Form=Dict2&Database=*&Query=$1
>
>an mein CGI.
>
>Dort lese ich es mit
>
> $in = $ENV{'QUERY_STRING'};
>
>und da sind die '&' bereits decoded:
Dann machst entweder du oder mod_rewrite was falsch. Es gibt diverse
Methoden das Maskieren bei mod_rewrite zu kontrollieren, u.a. die
Option NE und die RewriteMap int:escape. Du solltest das Problem an
der Stelle lösen, ansonsten gibt es hier keine allgemeine Lösung, du
müsstest sie schon auf deinen Spezialfall ausrichten, wenn das über-
haupt möglich ist.
--
Björn Höhrmann · mailto:bjoern@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/
Re: CGI/URL mit split in Parameter zerlegen
am 11.01.2007 21:03:36 von Helmut Wollmersdorfer
Bjoern Hoehrmann wrote:
> * Helmut Wollmersdorfer wrote in de.comp.lang.perl.misc:
>> $in = $ENV{'QUERY_STRING'};
>>
>> und da sind die '&' bereits decoded:
> Dann machst entweder du oder mod_rewrite was falsch. Es gibt diverse
> Methoden das Maskieren bei mod_rewrite zu kontrollieren, u.a. die
> Option NE und die RewriteMap int:escape.
Danke für den Hinweis.
Mit int:escape bekomme ich jetzt zwar die Blanks encoded, aber nicht die '&'
Green%20&%20Gold%20Tanager
^
NE oder nicht hat darauf keinen Einfluss.
> Du solltest das Problem an
> der Stelle lösen, ansonsten gibt es hier keine allgemeine Lösung, du
> müsstest sie schon auf deinen Spezialfall ausrichten, wenn das über-
> haupt möglich ist.
Also ich sehe das nicht als Spezialfall, sondern offensichtlich(?) als
Spezifikations- oder Implementierungsfehler von mod_rewrite. Zumindest
ist es sehr schlecht dokumentiert, wenn es irgendwie funktionieren könnte.
Helmut Wollmersdorfer
Workaround für "&" im Suchstring (was: CGI/URL mit split in Parameter zerlegen)
am 12.01.2007 15:25:06 von Helmut Wollmersdorfer
Helmut Wollmersdorfer wrote:
> Das schicke ich dann im Apache 2.2 mittels
> RewriteRule ^([^/]*)$
> /cgi-bin/Dict?Form=Dict2&Database=*&Query=$1
> an mein CGI.
[...]
> und da sind die '&' bereits decoded:
Nachdem das Problem mit diversen Optionen von mod_rewrite nicht lösbar
war, war dann folgendes mein 'dirty hack':
$in = $ENV{'QUERY_STRING'};
$SCRIPT_URL = '';
$SCRIPT_URL = $ENV{'SCRIPT_URL'} if $ENV{'SCRIPT_URL'};
$SCRIPT_URL =~ s|^/||;
$in =~
s|^(.*Query=)($SCRIPT_URL)(.*)$|$1.uri_escape(uri_unescape($ 2)).$3|se;
Was auf der Testmaschine (Debian/Sid) funktionierte, aber dann auf der
Produktionsmaschine nicht (Etch).
Deshalb ein noch schlimmerer Hack, der stabil funktioniert:
$in = $ENV{'QUERY_STRING'};
$in =~ s|^(.*Query=)([^=]*)$|$1.uri_escape(uri_unescape($2))|se;
Ab da kann man die Parameter sauber zerlegen, entweder mit split oder
CGI.pm.
Helmut Wollmersdorfer