macrumors 6502a

This is my first CGI app and I'm writing it in C. The intent of the C app is basically to echo all the environment variables passed the C CGI app, and any file attached as well.

It works on the Mac as expected, for the most part. I do have a second question about the post method boundary marker that is posed below.

First question:
This CGI setup does not "always" work when I access it from my Windows XP machine on my home network. I have lots of info to illustrate the issue, so please bare with me as I present it.

I'm running Tiger (OS X 1.4.11) on a Mac Pro. I've enabled web sharing and that seems to work fine from my Mac and from my Windows machine. I'm running the default Apache server that comes with Tiger. On Windows, I'm running IE 6 under XP.

I've created a simple html form with various controls to see how data and values are passed to the CGI program. Here is the form.

Running getmethod from the command line in Terminal and under XCode produces the expected output (although the environment variables are different). The piece I focus on is the content-type header. Works great on the command line, works great on the Mac (Safari) and doesn't work the first time for Internet Explorer. Here is what happens. On Windows, I direct the url to the server on my Mac with the formtest.html to bring up the form. Works great. I click "test me" (aka "submit") and I get the very vague "Internal Server Error" screen. See attached screen grab.

Now, interestingly enough, while on this "Internal Server Error" screen, if I click the IE's Refresh button, I get the prompt for "do I want to resend this form", I click RETRY, and VIOLA! The output of the CGI program appears. This is eating my lunch. Why does it fail the first request, but work on the refresh?

The initial request error status code is 500, which seems to be a catch-all error code. If I tail the error_log and access_log, I can see the requests and errors, but I don't know what to do to fix them. Here's the access log:

Why do you think I am getting the premature end of script headers? It obviously works under Safari, the command line output proves this, and is working under IE after the refresh, just not the first time. I've chmod'ed 755 so many times I'm blue in the face. I've tried renaming the getmethod execute to getmethod.cgi and there is no change in behavior. I've tried dozens of combinations of "\n\n" to add a blank line under the content-type header line. I googled and saw one tip for making sure I added fflush(stdout), and I didn't have that, so I added it to my C program.

When the output page is served up, for method="post", one of the environment variables is the boundary separator for the content-type data in stdin. See the attached image with yellow. Notice the 4 hyphens that lead off the start of the boundary separator.

Now, look down at data (white back ground). The boundary marker starts off the 6 hyphens, and the last marker even has two trailing hyphens. Is how this is supposed to work is to simply look at the "line" and if the boundary marker is on the line, then treat that line as a boundary marker? It seems reasonable that this would be the approach to take.

Sorry for the long post. Now that I've spilled my guts, any other advice for best practices would be appreciated too.

thread startermacrumors 6502a

I think I'm getting close to finding the error. While staring at the /var/log folder, I noticed a system.log file. I did a tail system.log and it says there was a crash log (was not aware of this) for my getmethod program.

So.... my cgi is crashing! Line 24 points me to the line where I test if envp is "true". Therefore, the environment variable paradigm must be different when the request is coming in from IE. I took that code out and merely severed up a simple "hi there", and it works EVERY STINKING TIME.

I'll do more research and post back with whatever I figure out. Man, this is an ugly one.

thread startermacrumors 6502a

I thought that perhaps the envp[] array was not getting set up the same for IE as it was for other browsers, so I converted the program over to use getenv() instead of using the global variable.

However, I get the same exact results. The program crashes, as seen above in the crash log, but works after REFRESH is clicked. I think I may head over to the Apache forums. I'm feeling a lot of "deer in headlights" stares here...

macrumors newbie

I have no definite explanation why you program crashes at first and then works upon reload in IE.

What I m seeing is however a badly possible buffer-overflow, which can easily kill your program.

char buffer[256];
strcpy(buffer, envp);

Since there is no guarantee that environment variables stay all the same all the times it is possible that upon some executions some env variable contains a longer string - this will overwrite buffer and kill more local stack variables.

You can defer copying of the envp after the = check, or even better get rid of copying, and use the envp contents directly without modification.

thread startermacrumors 6502a

thread startermacrumors 6502a

I have no definite explanation why you program crashes at first and then works upon reload in IE.

What I m seeing is however a badly possible buffer-overflow, which can easily kill your program.

char buffer[256];
strcpy(buffer, envp);

Since there is no guarantee that environment variables stay all the same all the times it is possible that upon some executions some env variable contains a longer string - this will overwrite buffer and kill more local stack variables.

You can defer copying of the envp after the = check, or even better get rid of copying, and use the envp contents directly without modification.

Regards

Click to expand...

[size=+3]YOU ARE THE MAN!!![/size].

That was exactly it. The HTTP_ACCEPT variable was longer than 256 bytes. Upon refresh, it was 3 bytes. I recoded my table to show the length too, and this confirms it!

MacRumors attracts a broad audience
of both consumers and professionals interested in
the latest technologies and products. We also boast an active community focused on
purchasing decisions and technical aspects of the iPhone, iPod, iPad, and Mac platforms.