CGI help

J

Jeff Leggett

So, I am trying ot read the contents of a file and format the contents
there into a CGI form. At 6PM on A friday hough, I am just not seeing
my errors - appreciate another srt of eyes!

require "cgi"

Filename = 'classification.txt'

EMPTY_STRING = ''
TITLE = 'Vulnerability Classification'
cgi = CGI.new('html4')
output = cgi.html do
cgi.head { cgi.title { TITLE } } +
cgi.body { cgi.h1 { TITLE } } +
cgi.form('post') do
if File.readable?(Filename) then
f = File.open(Filename,"r")
f.each_line { |l| l.chomp
inputs = l.split(',')
puts inputs[0].to_s + ": "
opts = "\"" + inputs[1].to_s + "\""
2.times { inputs.delete_at(0) }
until inputs.empty? do
opts = opts + "[\"" + inputs[1].to_s + "\",\"" +
inputs[0].to_s + "\"]"
2.times { inputs.delete_at(0) }
end
cgi.popup_menu(opts) +
cgi.br +
}
f.close
end
cgi.submit
end
end
cgi.out { output.gsub('><', ">\n<") }
 
J

James Britt

Jeff said:
So, I am trying ot read the contents of a file and format the contents
there into a CGI form. At 6PM on A friday hough, I am just not seeing
my errors - appreciate another srt of eyes!

Your file may need to start with a shebang line:

#!/usr/local/bin/ruby

or whatever the path to ruby on your system is.


Also, print out the correct headers

http://www.ruby-doc.org/docs/ProgrammingRuby/html/web.html


It helps to get the simplest possible CGI script running first, then
adding details, since debugging CGI is a painful.


--
James Britt

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development
 
J

Jeff Leggett

James said:
Your file may need to start with a shebang line:

#!/usr/local/bin/ruby

Yes, it does - I just left that out of the C&P.

The CGI does all that for you... My problem is if I take out the inner
loop (starting with "if File.readable?(Filename) then" it works fine. I
just can't for the life of me see the syntax errors.

[jleggett@binford cgi-bin]$ ./vuln.rb
/vuln.rb:27: syntax error
/vuln.rb:29: syntax error
end
^
/vuln.rb:31: syntax error
end
^
/vuln.rb:37: syntax error
[jleggett@binford cgi-bin]$
 
J

Jeff Leggett

7stud said:
How about getting rid of.........^ ?

I changed it like that, EXACT same errors. I have matched up the 'ends'
and bracket more times than I can count now, even slept on it, thinking
my tired brain would see it right off this morning, but no... Thanks for
your help though guys...

#!/usr/bin/ruby

require "cgi"

Filename = 'classification.txt'

EMPTY_STRING = ''
TITLE = 'Vulnerability Classification'
cgi = CGI.new('html4')
output = cgi.html do
cgi.head { cgi.title { TITLE } } +
cgi.body { cgi.h1 { TITLE } +
cgi.form('post') do
if File.readable?(Filename) then
f = File.open(Filename,"r")
f.each_line { |l| l.chomp
inputs = l.split(',')
puts inputs[0].to_s + ": "
opts = "\"" + inputs[1].to_s + "\""
2.times { inputs.delete_at(0) }
until inputs.empty? do
opts = opts + "[\"" + inputs[1].to_s + "\",\"" +
inputs[0].to_s + "\"]"
2.times { inputs.delete_at(0) }
end
cgi.popup_menu(opts) +
cgi.br +
}
f.close
end
cgi.submit
end
}
end
cgi.out { output.gsub('><', ">\n<") }

[jleggett@binford cgi-bin]$ ./vuln.rb
/vuln.rb:27: syntax error
/vuln.rb:29: syntax error
end
^
/vuln.rb:31: syntax error
end
^
/vuln.rb:38: syntax error
[jleggett@binford cgi-bin]$
 
D

Douglas Seifert

[Note: parts of this message were removed to make it a legal post.]
cgi.popup_menu(opts) +
cgi.br +
You have an extraneous '+' at the end of that last line. Remove it and your
script should start working.

Cheers,
Doug Seifert
 
J

Jeff Leggett

Douglas said:
You have an extraneous '+' at the end of that last line. Remove it and
your
script should start working.

Cheers,
Doug Seifert


*SIGH* Sure enough that fixed the syntax errors... Darn thing still
doesn't work though :( Writes the h1 TITLE, and the submit, nothing in
between...

My own fault trying to learn a new language - done it in perl I'd been
done yesterday at lunch LOL

Thanks for helping the n00b guys.
 
D

Douglas Seifert

[Note: parts of this message were removed to make it a legal post.]
*SIGH* Sure enough that fixed the syntax errors... Darn thing still
doesn't work though :( Writes the h1 TITLE, and the submit, nothing in
between...

Can you post the contents of classification.txt? Some sample data would
help. Is the file readable by the web server process? Are you sure that
the working directory when the cgi is run is such that opening
classification.txt with no other path info will work ( puts Dir.pwd ) ...?

-Doug Seifert
 
J

Jeff Leggett

Douglas said:
Can you post the contents of classification.txt? Some sample data would
help. Is the file readable by the web server process? Are you sure
that
the working directory when the cgi is run is such that opening
classification.txt with no other path info will work ( puts Dir.pwd )
...?

-Doug Seifert

[jleggett@binford cgi-bin]$ cat classification.txt
Access Control,access,High,0,Medium,5,Low,10
Authentication,auth,High,0,Medium,5,Low,10
Confidentiality Impact,confi,High,10,Medium,5,Low,0
Confidentiality modifier,confm,Employee Data,30,Customer
Data,20,System/network Data,10,application metadata,5,N/A,0
integrity impact,integi,High,10,Medium,5,Low,0
integrity modifier,integm,System/Application,30,Customer
Information,20,Employee Info,30,Individual Info,10,N/A,0
Availability Impact,avail,High,10,medium,5,Low,0
[jleggett@binford cgi-bin]$

Yeah I added an else to the File.readable link to make sure it's
there... it's there... the problem seems to be now it's not building the
CGI all up... I get errors again.

1 #!/usr/bin/ruby

2 require "cgi"

3 Filename = 'classification.txt'

4 EMPTY_STRING = ''
5 TITLE = 'Vulnerability Classification'
6 cgi = CGI.new('html4')
7 output = cgi.html do
8 cgi.head { cgi.title { TITLE } } +
9 cgi.body { cgi.h1 { TITLE } +
10 cgi.form('post', 'http://binford.x.com/cgi-bin/vulnclass.rb')
do
11 if File.readable?(Filename) then
12 f = File.open(Filename,"r")
13 f.each_line { |l| l.chomp
14 inputs = l.split(',')
15 cgi.p { inputs[0].to_s + ": " } +
16 #opts = "\"" + inputs[1].to_s + "\""
17 2.times { inputs.delete_at(0) }
18 until inputs.empty? do
19 opts = opts + "[\"" + inputs[1].to_s + "\",\""
+ inputs[0].to_s + "\"]"
20 2.times { inputs.delete_at(0) }
21 end
22 # puts opts
23 cgi.popup_menu(opts) +
24 cgi.br
25 }
26 f.close
27 else
28 puts "File not read-able!\n"
29 end
30 cgi.submit
31 end
32 }
33 end
34 cgi.out { output.gsub('><', ">\n<") }

Produces:

[jleggett@binford cgi-bin]$ ./vuln.rb
(offline mode: enter name=value pairs on standard input)
/vuln.rb:20:in `+': can't convert Fixnum into String (TypeError)
from ./vuln.rb:20
from ./vuln.rb:16:in `each_line'
from ./vuln.rb:16
from /usr/lib/ruby/1.8/cgi.rb:1557:in `form'
from ./vuln.rb:13
from (eval):1022:in `body'
from ./vuln.rb:12
from /usr/lib/ruby/1.8/cgi.rb:1657:in `html'
from (eval):1006:in `html'
from /usr/lib/ruby/1.8/cgi.rb:1657:in `html'
from ./vuln.rb:10
[jleggett@binford cgi-bin]$
 
7

7stud --

Jeff said:
7stud said:
How about getting rid of.........^ ?

I changed it like that, EXACT same errors. I have matched up the 'ends'
and bracket more times than I can count now, even slept on it, thinking
my tired brain would see it right off this morning, but no... Thanks for
your help though guys...

#!/usr/bin/ruby

require "cgi"

Filename = 'classification.txt'

EMPTY_STRING = ''
TITLE = 'Vulnerability Classification'
cgi = CGI.new('html4')
output = cgi.html do
cgi.head { cgi.title { TITLE } } +
cgi.body { cgi.h1 { TITLE } +
cgi.form('post') do
if File.readable?(Filename) then
f = File.open(Filename,"r")
f.each_line { |l| l.chomp
inputs = l.split(',')
puts inputs[0].to_s + ": "
opts = "\"" + inputs[1].to_s + "\""
2.times { inputs.delete_at(0) }
until inputs.empty? do
opts = opts + "[\"" + inputs[1].to_s + "\",\"" +
inputs[0].to_s + "\"]"
2.times { inputs.delete_at(0) }
end
cgi.popup_menu(opts) +
cgi.br +
}
f.close
end
cgi.submit
end
}
end
cgi.out { output.gsub('><', ">\n<") }

[jleggett@binford cgi-bin]$ ./vuln.rb
./vuln.rb:27: syntax error
./vuln.rb:29: syntax error
end
^
./vuln.rb:31: syntax error
end
^
./vuln.rb:38: syntax error
[jleggett@binford cgi-bin]$

Putting these lines:

cgi.popup_menu(opts) +
cgi.br +

inside the if statement doesn't work for me: I get a bunch of kEND
errors. If I move those lines outside the if statement, then no errors:

cgi = CGI.new('html4')
output = cgi.html {
cgi.head { cgi.title { TITLE } } +
cgi.body { cgi.h1 { TITLE } +
cgi.form('post') {
if File.readable?(Filename)
f = File.open(Filename,"r")
opts = ""

f.each_line do |l|
l.chomp #does nothing
inputs = l.split(',')
puts inputs[0].to_s + ": "
opts << "\"" + inputs[1].to_s + "\""
2.times { inputs.delete_at(0) }
until inputs.empty?
opts << "[\"" + inputs[1].to_s + "\",\"" + inputs[0].to_s +
"\"]"
2.times { inputs.delete_at(0) }
end
end #each_line

f.close
end #if

cgi.popup_menu(opts) +
cgi.br +
cgi.submit
} #form

} #cgi.body
} #cgi.html

cgi.out { output.gsub('><', ">\n<") }


I have no idea why that is the case.
 
7

7stud --

7stud said:
I have no idea why that is the case.

Here is a simplification of the issue if anyone wants to offer some
advice. The following code produces no errors:

#!/usr/bin/ruby

require "cgi"

cgi = CGI.new('html4')
output = cgi.html {
cgi.head { cgi.title { "Test" } } +
cgi.body {
cgi.form('post') {
cgi.textarea() +
cgi.submit
} #form
} #cgi.body
} #cgi.html



This code produces kEND errors:

#!/usr/bin/ruby

require "cgi"

cgi = CGI.new('html4')
output = cgi.html {
cgi.head { cgi.title { "Test" } } +
cgi.body {
cgi.form('post') {
if true
cgi.textarea() +
end
cgi.submit
} #form
} #cgi.body
} #cgi.html
 
7

7stud --

7stud said:
This code produces kEND errors:

#!/usr/bin/ruby

require "cgi"

cgi = CGI.new('html4')
output = cgi.html {
cgi.head { cgi.title { "Test" } } +
cgi.body {
cgi.form('post') {
if true
cgi.textarea() +
end
cgi.submit
} #form
} #cgi.body
} #cgi.html


So does this:

#!/usr/bin/ruby

require "cgi"

cgi = CGI.new('html4')
output = cgi.html {
cgi.head { cgi.title { "Test" } } +
cgi.body {
cgi.form('post') {
if true
cgi.textarea() +
else
cgi.textarea() +
end

cgi.submit
} #form
} #cgi.body
} #cgi.html
 
D

Douglas Seifert

[Note: parts of this message were removed to make it a legal post.]
[jleggett@binford cgi-bin]$ cat classification.txt
Access Control,access,High,0,Medium,5,Low,10
Authentication,auth,High,0,Medium,5,Low,10
Confidentiality Impact,confi,High,10,Medium,5,Low,0
Confidentiality modifier,confm,Employee Data,30,Customer
Data,20,System/network Data,10,application metadata,5,N/A,0
integrity impact,integi,High,10,Medium,5,Low,0
integrity modifier,integm,System/Application,30,Customer
Information,20,Employee Info,30,Individual Info,10,N/A,0
Availability Impact,avail,High,10,medium,5,Low,0
[jleggett@binford cgi-bin]$
OK, after figuring out how CGI works in ruby ... there are some problems
with your original code:

1) cgi.body { cgi.h1 { TITLE } }

The above will generate a body tag with a h1 tag and then close the body. I
think you wanted to defer that closing brace until after the form was
generated.

2) The block passed to the form method must evaluate to a string which will
be the form's contents. Your block will evaluate to the return value of
File.close (because this is the last statement executed by the block). close
returns nil, which when coerced to a string would be "" (the empty string).
Thus, your form will have no content.

3) popup_menu takes a String as the first argument which is the name of the
select tag and then an arbitrary number of arguments representing the
options. I think you want to use Arrays as the arguments because you want
to specify an option value and option name. The code you wrote does not do
that. It just passes a big string to popup_menu as a single argument.

4) You are mixing puts with generating strings inside the CGI tag method
blocks. You need to make sure you don't use puts as it will corrupt the
HTML generated by the script by outputting stuff you don't want output.

I took a stab at correcting all these problems, and changed some minor
things, but didn't really try to rubyfy the code:

require "cgi"

Filename = 'classification.txt'

EMPTY_STRING = ''
TITLE = 'Vulnerability Classification'
cgi = CGI.new('html4')
output = cgi.html do
cgi.head { cgi.title { TITLE } } +
cgi.body do
cgi.h1 { TITLE } +
cgi.form('post') do
form_contents = ""
if File.readable?(Filename) then
# Use the version of File#open that takes a block. That
# way you don't have to worry about closing the file after
# you are done with it -- it will happen automatically when
# the block is done executing
File.open(Filename,"r") do |f|
f.each_line do |l|
# Need to use chomp! instead of plain chomp to
# ensure l is actually changed. Otherwise, we just
# create and throw away a new string
l.chomp!
inputs = l.split(',')
form_contents << inputs[0] + ": "
select_name = inputs[1]
select_opts = []
2.times { inputs.delete_at(0) }
until inputs.empty? do
select_opts << [inputs[1], inputs[0]]
2.times { inputs.delete_at(0) }
end
form_contents << cgi.popup_menu(select_name, *select_opts) +
cgi.br
end
end
end
form_contents + cgi.submit
end
end
end
 
D

Douglas Seifert

[Note: parts of this message were removed to make it a legal post.]

You have a trailing + and have not provided the second argument in all the
examples that fail.
 
7

7stud --

Douglas said:
You have a trailing + and have not provided the second argument in all
the
examples that fail.

The second argument to +? What about cgi.submit? This works:

cgi.form('post') {
cgi.textarea() +
cgi.submit
}

This produces kEND errors:

cgi.form('post') {
if true
cgi.textarea() +
else
cgi.textarea() +

cgi.submit
}

You can't do this in plain ruby:

str = "hello" +
" goodbye"


But the cgi syntax allows you to add things together like that.
 
J

Jeff Leggett

Douglas said:
OK, after figuring out how CGI works in ruby ... there are some problems
with your original code:

WOW, thanks Doug! That was it totally... I had read use of the
destructive method (!) but didn't grok till I saw it... And the rest of
the way now makes prefect sense.

I appreciate all of yours help. I decided my perl only skills were
getting long in the tooth and decided I needed to pick up a truly OO
language, and learn it... but seems a lot harder than when learning new
languages did 20+ years ago.
 
D

Douglas Seifert

[Note: parts of this message were removed to make it a legal post.]
cgi.form('post') {
cgi.textarea() +
cgi.submit
}

The above works because the interpreter finds something on the next line to
add to the result of cgi.textarea().
This produces kEND errors:

cgi.form('post') {
if true
cgi.textarea() +
else
cgi.textarea() +

cgi.submit
}


The interpreter sees that + at the end of the line in the first branch of
the if statement and gets confused looking for something to add it to. It
would be nice if it could figure out that you wanted to add it to the result
of the statement that comes after the if statement, but that is not how it
works. You would need to do something like like this to get it to work:

(condition ? cgi.textarea() : cgi.textarea()) +
cgi.submit

You can't do this in plain ruby:

str = "hello" +
" goodbye"

The above works just fine. You end up with str being a reference to "hello
goodby".

But the cgi syntax allows you to add things together like that.

There is nothing magical about the cgi syntax. All that is happening is
that String objects are getting added together. To get it to work, you have
to ensure that the blocks passed to the various cgi methods end up
evaluating to the string you want the tag created by the block's method to
contain. You do that by making the last statement evaluated in the block be
the string you want as content.

-Doug Seifert
 
7

7stud --

Douglas said:
The above works just fine. You end up with str being a reference to
"hello
goodby".

Hmmm...I must have done something wrong when I was testing that--because
now it works. In that case. the op's problem makes perfect sense. His
code was trying to do this:

str = "form element1 " +

if true
"form element2 " +
end

"submit button"

which gives the kEND errors the op was seeing:

r1test.rb:5: syntax error, unexpected kEND
r1test.rb:10: syntax error, unexpected $end, expecting kEND
 
B

Brian Candler

Douglas said:
The interpreter sees that + at the end of the line in the first branch
of
the if statement and gets confused looking for something to add it to.
It
would be nice if it could figure out that you wanted to add it to the
result
of the statement that comes after the if statement, but that is not how
it
works. You would need to do something like like this to get it to work:

(condition ? cgi.textarea() : cgi.textarea()) +
cgi.submit

You can just use 'if' that way too, as it returns a value, although its
low precedence means you'll need brackets:

(
if condition
foo
else
bar
end
) +
baz

Personally I wouldn't try to write it this way; it's too error-prone as
has been demonstrated already. I think it would be clearer to append to
a target string in stages:

str = ""
if condition
str << foo
else
str << baz
end
str << baz

Here, each line stands by itself.

But for any complex output it's probably better to forget about using
CGI methods to generate HTML, and use some sort of template (e.g. ERB or
HAML).

Admittedly, in a one-shot CGI environment, there's a bigger startup
overhead both in reading the template library and parsing the template,
for every request. But if performance is a concern, then you shouldn't
be using CGI anyway.

If you write your app using a simple framework like Sinatra, then you
can run it both as CGI and in a number of other environments, without
changing the app.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,710
Latest member
bernietqt

Latest Threads

Top