Re: foreach routine
duke normandin wrote:
>
> Derek Parnell wrote:
> >
> > duke normandin wrote:
> > >
> > > Chris Bensler wrote:
> > > > The getenv() routine will return -1 if the environment variable
> > > > CONTENT_LENGTH
> > > > doesn't exist. If it does exist, a string will be returned.
> > >
> > > Are you sure? I've never proven this to myself, but it has always been my
> > > understanding that with respect the method=POST, the ENV. VAR.
> > > CONTENT_LENGTH
> > > would be set to the amount of bytes sent out. THEREFORE, this is why we
> > > "read"
> > > that many bytes from STDIN, and only that many. So my point is that
> > > CONTENT_LENGTH
> > > will in one case be a positive number or a -1 -- both atoms. No?
> >
> > Yes and no. The Euphoria function getenv() always returns a string if the
> > environment
> > variable exists, and -1 if it doesn't exist. In your case, CONTENT_LENGTH
> > will
> > most likely always be there due to the CGI environment, but when getenv()
> > returns
> > its content, it is a string representation of a number and not the number
> > itself.
> > So if the number of characters to read in from STDIN is 59,
> > getenv("CONTENT_LENGTH")
> > will return "59" and not 59. Thus you have to convert the string "59" to its
> > number form.
>
> I got it! Damn! I've got to watch the data types more carefully. Not used to
> it. ;)
> To recap, getenv returns the atom -1 if the ENV.VAR. is unset OR a string
> containing
> whatever. In the case of CONTENT_LENGTH I was expecting an integer. I now know
> to
> convert CONTENT_LENGTH *to* an integer.
>
> > res = value( "59" )
>
> [snip]
>
> I really don't need to do all that testing.
>
> What the Perl/PHP etc world has done all this time is:
>
> 1. getenv("REQUEST_METHOD")
> 2. if == "POST"
> 2.a value_array = value(getenv("CONTENT_LENGTH")
> 2.b stash get_bytes(0, value_array[2])
> 3. if == "GET"
> 3.a stash getenv("QUERY_STRING")
> 4. if == "some_bogus_method"
> 4.a cgi_die("gracefully")
> 5. amen
>
> That is what I want to reproduce in Euphoria come "hell or high water" ;)
>
> Once I have the above "stash", then we use your "foreach" and "split" code to
> massage the FORM[key]=values
> I love it !! Thanks you all for the mini EU tutorials!!
> --
> duke
Good programming practice is to always trap error conditions whenever you can.
I get the impression though, that you meant that you don't want to have to do
the error testing all the time. Make a routine that takes care of it for you
instead.
I use this routine..
This avoids the error by making it default to an empty string.
This routine will always return a valid string or "".
global function cgi_getenv(string name)
object tmp
tmp = getenv(name)
if atom(tmp) then return "" end if
return tmp
end function
Similarly for value(), I have..
This avoids the error by making it default to 0.
This always returns the converted number, or 0.
global function get_value(object x)
sequence ret
ret = value(x)
if ret[1] = GET_SUCCESS then
return ret[2]
else
return 0
end if
end function
The above routines are not generally a good way to deal with error cases, but
for specific purposes such as this situation, it should be fine.
Using those two routines, I could make a new routine specifically to return the
content_length..
This routine returns the number value of the content length.
global function cgi_content_length()
integer len
len = cgi_getenv("CONTENT_LENGTH")
return get_value(len)
end function
And a routine to handle the request method...
global function cgi_request_method()
return cgi_getenv("REQUEST_METHOD")
end function
For further processing of the POST or QUERY, you will need some code like the
following, to convert url-encoded strings to plain text.
function replace_hex(sequence s)
sequence f,hex
-- find and store the index of all instances of '%' in s
f = {}
for i = 1 to length(s) do
if s[i] = '%' then
f &= i
end if
end for
if length(f) then
for i = length(f) to 1 by -1 do
hex = get_value("#"&s[f[i]+1..f[i]+2]) -- convert the string code to a
character code
s = s[1..f[i]-1] & hex & s[f[i]+3..length(s)]
end for
end if
return s
end function
------------------------------------------------
-- This is the function that you are mostly after
-- cgi_parse_request() will convert a url-encoded string to key/value pairs
-- in the form of {{key1,key2,...},{val1,val2,...}}
-- EG. "firstname=Duke&lastname=Normandin"
-- becomes {{"firstname","lastname"},{"Duke","Normandin"}}
global function cgi_parse_request(sequence s)
s ={ s , {} }
s[1] = join(split(s[1],'+'),' ') -- convert '+' to ' '
s[1] = join(split(s[1],'&'),';') -- convert '&' to ';'
s[1] = split(s[1],';')
if length(s[1]) then s[2] = repeat("",length(s[1])) end if
for i = 1 to length(s[1]) do
s[1][i] = split(s[1][i],'=')
s[1][i][1] = replace_hex(s[1][i][1])
if length(s[1][i]) > 1 then
s[2][i] = replace_hex(s[1][i][2])
end if
s[1][i] = s[1][i][1]
end for
return s
end function
Here is a routine to handle fetching the post data.
It will return a sequence of key/values as described for cgi_parse_request()
global function cgi_get_post()
sequence buf
integer len
len = cgi_content_length()
buf = get_bytes(STDIN,len)
return cgi_parse_request(buf)
end function
Here is the routine to handle QUERY data.
global function cgi_get_query()
sequence buf
buf = cgi_getenv("QUERY_STRING")
return cgi_parse_request(buf)
end function
Now you can make a routine to actually do the whole thing for you..
global function cgi_get_request()
sequence req
req = cgi_request_method()
if equal(req,"POST") then
return cgi_get_post()
elsif equal(req,"GET") then
return cgi_get_query()
else
-- error, invalid request method
end if
end function
Buene?
You may be wondering why the pairs are stored as {key_list,data_list} instead of
{{key1,data1},{key2,data2}}. The reason is because it's easier to search for a
key that way.
EG.
sequence pairs
integer f
pairs = cgi_get_request()
f = find("firstname",pairs[1])
if f then
puts(STDOUT,"Your firstname is: " & pairs[2][f] & "\n")
end if
Chris Bensler
~ The difference between ordinary and extraordinary is that little extra ~
http://empire.iwireweb.com - Empire for Euphoria
|
Not Categorized, Please Help
|
|