When I first looked at this Sunday night I promised myself I'd spend no more than an hour or two on it. Well that went right out of the window :/
My initial aim was to get it working on Vista and run as CGI on IIS. This didn't work. I've spent the last 3 days playing about with it and testing out a load of things to find out why. Eventually with the help of the good people on IRC #perl6 and #parrot we found the problem and came up with a fix. Here are some of the details...
Following on from my last post, the people of the firstname.lastname@example.org mailing list pointed me to a Rakudo build fix so I was able to build perl.exe by running mingw32-make. This has now been patched into Rakudo on github so if you are following this you shouldn't have the issue I had.
Playing with Rakudo on the command prompt I made my first hello world script 'saved as hello.p6':-
say( 'hello' );
And ran it with 'perl6 hello.p6'.
Following that I prepared a version for CGI that included the content-type header:-
say( "Content-Type: text/html\r\n\r" ); # say adds the last \n
say( 'hello' );
I checked this on the command prompt to make sure it was outputting properly and it was. Now to setup with IIS.
Open up IIS7 services manager. Then select the website from the left panel (for my it's under COMPNAME->Sites->Default Website). In the center panel there is a link for 'handler mappings', double click.
Top right click on 'Add script map' and fill in:-
Request Path: *.p6
Executable: C:\temp\rakudo\perl6.exe "%s" %s
When I clicked OK a message popped up asking "Do you want to allow this ISAPI extention?" I clicked Yes.
Now we *should* be able to run Rakudo cgi scripts through IIS. But copying my test script to c:\inetput\wwwroot\cgi-bin and trying to run through the browser localhost/cgi-bin/hello.p6 gave me a 502 error. At this point I tried a lot of different scripts such as:-
$*ERR = open("C:/inetpub/wwwroot/cgi-bin/err.txt", :w);
my $crlf = "\x[0D]\x[0A]";
$*OUT.say( "Content-Type: text/html$crlf$crlf" );
$*OUT.say( 'hello it works' );
$*ERR.say( 'got to end' );
Which still gave me the error, but when I check err.txt it was having 'got to end' written to it, so the script was actually running... To convince myself I wasn't going mad I installed Apache and tested through that as well:-
Setting up Rakudo with Apache
I know they are working on a mod_perl6, but right now I just want it to work through cgi. I installed Apache 2.2 on port 8080 and updated my httpd.conf with the line:-
AddHandler cgi-script .cgi .pl .pl6 .p6
I also updated my htdocs and cgi-bin folders to be at c:\htdocs and c:\htdocs\cgi-bin. I restarted Apache, put my hello.p6 script in c:\htdocs\cgi-bin and ran it through the browser http://localhost:8080/cgi-bin/hello.p6. Bingo! That worked as expected. So at least I'm not going crazy, the hello.p6 test script is working, so why isn't IIS displaying it's output?
At this point I was thinking maybe it was worth trying a more detailed cgi script to see what happened. I grabbed a copy of november from github. It didn't look like anyone had tried installing november on Vista, so I joined the email@example.com mailling list and kept them updated as to my progress. I ended up submitting 4 patches and 1 new script to get it running on Vista command prompt. But still IIS and Apache weren't working :(
I was going round in circles and not getting any further. I contacted the ActiveState mailing list thinking Jan might be able to shed some light, but unfortunately he was away for the week. Seemed a cautious pestering of the people on the #perl6 IRC channel was in order.
I said hi and spoke to PerlJam, Moritz_, jnthn and Masak. I felt a bit more compfortable when Moritz_ said "Lyle: ah, that was you... does Rakudo build on vista without modifications now?". TimToady was on there as well, but I'll have to build up a bit of courage before I speak to him...
I told them the things I'd tried and they suggested trying some more. Nothing worked. One error that kept coming out was "src\io\api.c:233: failed assertion 'pmc'". jnthn suggested writing a parrot PIR hello world cgi script and seeing if that failed as well. Then we'd know if it was a Rakudo or Parrot issue. (looking back at the IRC logs jnthn had an incling it was something to do with IO and STDIN which proved almost spot on in the end).
I managed to get november working on Apache when I finally realized it wasn't picking up the libraries. Still no further with IIS. Masak also suggested writing a PIR hello world script...
Parrot PIR hello world script
I searched online and found a deceptively simple script (saved as hi.pir):-
.sub main :main
print "Hello world!\n"
I updated it for CGI:-
.sub main :main
print "Content-Type: text/html\r\n\r\n"
print "Hello world!\n"
Setting up Apache and IIS for parrot in exactly the same way I did for Rakudo except for .pir files and the c:/temp/rakudo/parrot/parrot.exe executable. I found similarly this worked for Apache and not IIS. This told me it was definitly a parrot issue. Time for more help...
I joined this channel and updated them as to the problem and the things I'd tried. They suggested trying a few more things. I ended up with a PIR script that tried to write out to a file but kept failing with "src\io\api.c:455: failed assertion 'pmc'". I tried getting IIS to run parrot with trace enabled -t1 but that just changed the error slightly "src\io\api.c:603: failed assertion 'pmc'". I also tried a few hacky things to try and get the parrot output but they didn't work. Infinoid offered his assistance, and guided me through using MinGW's gdb program to attach to the running parrot process and add a breakpoint. This was all well above my head by Infinoid was very patient and told me exactly what i needed to do.
The basic process was:-
- Update hi.pir with a sleep 30 command near the top
- Run through IIS
- As it hangs use Task manager to grab the PID
- Run gdb parrot.exe <PID>
- Type "break Parrot_io_putps" from within gdb
- Type "cont" until we got to a break point that had the null value we were looking for
- Then type "bt" to dump some info about it
As soon as this was done Infinoid saw what the problem was in win32.c. Parrot was trying to open STDIN and failing. When IIS invokes a CGI script it doesn't allow STDIN unless there is POST data. Infinoid wrote a patch and I even got to edit a little bit of C code myself :)
After much torment parrot worked on IIS through cgi. I was able to rebuild Rakudo (had to do a 'mingw32-make clean', then 'mingw32-make') and get Perl 6 working as well. Much happiness :)
I couldn't help but feel like I'd made a different (albeit very small). The problem in parrot meant none of the parrot based languages were working on IIS through CGI, not just Perl 6. Now it's all sorted. Thanks again to everyone.