The HTTP (Web) protocol does not use the same mechanism to send data from server to client, and from client to server. Client to server communication must usually happen over CGI (Common Gateway Interface), by having users submit HTML forms.
Form data submitted usually consists of
pairs. One other option are just values following one another
(key
=value
); those are called
"ISINDEX" queries, and are not generally used with Interchange.
value1
+value2
+value3
...
Form submission can happen in two ways.
The "GET" method is very basic, as it
just embeds form values in the URL being sent to the server. One example of
a GET query is
http://myhost.mydomain.local/cgi-bin/ic/test?mv_arg=1&mv_pc=14
.
I think it's simple enough to notice variables mv_arg
and
mv_pc
being submitted. The GET method is very convenient
because all data is embedded in the URL, making it very easy to copy and
share links with other people.
It is recommended to create these links in Interchange with [area]
.,e.g.:
<a href="[area href="" form="param1=foo param2=bar"]">FOO & BAR</a> </a>
The other method is called POST. This way, the information is sent in a way not visible to the user. POST forms have this disadvantage of not being suitable for copy-pasting HTML links directly, but they do offer greater flexibility, especially if a lot of form data is being sent.
When forms are submitted using the POST method, they can also embed data
in the URL, effectively passing both POST and GET data at once. Interchange ignores
GET data on POST forms, but can be instructed to parse both using the
TolerateGet
directive.
In the end, it turns out you can just use GET in most situations. It's simpler, more convenient, and gets the job done just as well.
CGI variables in Interchange are accessible using the [cgi]
tag, and
only on a page directly following the form
submission. This is logical, of course. A page request reaches the Interchange daemon,
and it either has or doesn't have the accompanying form data; there's no
"history" mechanism included. (However, Interchange does allow you to save values
for future reference, usually in the value or scratch space).
Interchange is, by default, eager to collect user information, at least for the
duration of the session (so the users don't have to retype it again).
During processing, CGI variables are therefore propagated to the values
space, for subsequent requests. The FormIgnore
directive specifies
which CGI variables should not be propagated.
Users have complete control over CGI data they will send. Therefore, this input should never be trusted. It's raw data, and it is a security risk to save it in a database or display in a page before sanitization. The most common security risk is displaying HTML code which allows remote scripting exploits like cookie-stealing.
Never do something like the following:
[cgi VARNAME
]
or
[calc]
my $out = $CGI->{VARNAME
};
return $out;
[/calc]
Fortunately, Interchange offers a number of ways to take care of the data, usually
by filtering it. For more discussion and
help on filtering, see the filter glossary entry.
A safe no-brainer approach is to just use the
encode_entities
filter on the input.
So, to obtain a "safe" value while keeping the original intact, use:
[cgi name=VARNAME
filter=entities]
or:
[filter entities][cgi VARNAME
][/filter]
or:
[calc]
my $out = $Tag->cgi({ name => 'VARNAME
', filter => 'entities' });
return $out;
[/calc]
or:
[calc]
my $out = $Tag->filter($CGI->VARNAME
, 'entities');
return $out;
[/calc]
One interesting feature in Interchange is that you can set CGI values yourself.
This has two common uses. You can set a value and pretend as
if it was sent by the user (so the rest of your code doesn't need to split
in two execution paths, depending on whether the variable was set or not).
Another thing you can do, is set special CGI variables (the
mv_*
ones that affect how Interchange processes the page) and let
Interchange do its magic. Heck, not only you can set them once, but you can change
their value during processing, achieving different
behavior in different parts of the page.
You can set values by providing
set=
attributes
to the VALUE
hide=1[cgi]
tag, or by simple assignment in Perl
($CGI->{
).
VARNAME
} = 'VALUE
'
Here's a complete list of ways to access CGI variables:
In ITL:
Access syntax | Notes |
---|---|
[cgi VARNAME ] | Doesn't prevent users from injecting ITL code; don't use it! |
[cgi name=VARNAME filter=entities] | A safe and correct way to go |
In embedded Perl:
Access syntax | Notes |
---|---|
$CGI->{VARNAME } | Retrieves raw CGI value; don't use before filtering |
$Tag->cgi({ name => 'VARNAME ', filter => 'entities' }); | A safe and correct way to go |
$Tag->filter($CGI->{VARNAME }, 'entities'); | A safe and correct way to go |