You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@httpd.apache.org by Andrus <ee...@online.ee> on 2003/07/10 17:42:25 UTC
[users@httpd] Premature end of script headers using CGI appl in Linux
I have a CGI app which interfaces with my application. I use Apache 2
In Windows it works OK.
I re-compiled this CGI app using Windowsis Dev-C++ 4.9.8.0 using Linux
modules.
After that I got the following error from Apache:
Premature end of script headers: eva.exe
Any idea how to fix this ?
My CGI app code is as follows:
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winbase.h>
#include <time.h>
#include <direct.h>
#include <sys/timeb.h>
#include <fcntl.h>
#include <io.h>
#define TEMP_PREFIX_LENGTH 8 // Length of temporary file prefix excluding
null terminator
#define DATA_BUFFER_LENGTH 1000 // Length of data buffer.
#define MAX_FILE_ATTEMPTS 10 // Number of times to attempt creating temp
file.
#define ACK_RETRY_MILLISECONDS 250 // Number of milliseconds for each retry
attempt to read ACK file.
#define ACK_TIMEOUT_SECONDS 60 // Number of seconds until attempts to
read ACK file time out.
#define SERVER_INACCESSIBLE_TITLE_LOC "Server Inaccessible"
#define SERVER_INACCESSIBLE_TEXT_LOC "Communication with the server is not
possible at this time."
#define SERVER_TIMEOUT_TITLE_LOC "Server Timeout"
#define SERVER_TIMEOUT_TEXT_LOC "The server timed out. It is probably too
busy to fulfill your request."
#define SERVER_NODATA_TITLE_LOC "Server Error"
#define SERVER_NODATA_TEXT_LOC "A server error occurred. No return data was
sent."
void errorform( char *errorstring, char *errortitle );
void main( int argc, char *argv[] )
{
char tmpPrefix[TEMP_PREFIX_LENGTH+1];
char tmpFolder[] = "\\temp";
char tmpName[_MAX_PATH];
char *t1 = NULL;
char *tempbuffer = NULL;
char datFileName[_MAX_PATH];
char ackFileName[_MAX_PATH];
char atnFileName[_MAX_PATH];
FILE *datFile = NULL;
FILE *atnFile = NULL;
FILE *tempFile = NULL;
struct _timeb timebuffer;
char buffer[DATA_BUFFER_LENGTH];
int cont_len, bytesread, fileattempts;
time_t begintout, chktout;
char **envptr;
fpos_t pos;
// Turn stdin buffering off
setvbuf( stdin, NULL, _IONBF, 0 );
setmode( fileno(stdout), O_BINARY );
// Create server.app compatible temporary folder.
// Note: Server.app is looking for files in <current drive>:\temp,
// not in the actual system temporary folder.
_mkdir( tmpFolder );
// Seed random number generator and zero fileattempts counter.
_ftime( &timebuffer );
srand( ((timebuffer.time & 0xFF)<<10) | timebuffer.millitm );
fileattempts = 0;
for (;;)
{
fileattempts++;
// If we've tried MAX_FILE_ATTEMPTS times, give error message.
if ( fileattempts > MAX_FILE_ATTEMPTS )
{
errorform( SERVER_INACCESSIBLE_TEXT_LOC, SERVER_INACCESSIBLE_TITLE_LOC );
goto CleanupAndExit;
}
// Create random file name. Format is "VF" plus unique 4 digit hex number
// representing the processid, plus 2 digit random number (in case
multiple
// machines are running the CGI scripts).
sprintf( tmpPrefix, "VF%04X%02X", (DWORD) GetCurrentProcessId(), rand() &
0xFF);
// Build temporary file name.
sprintf( tmpName, "%s\\%s", tmpFolder, tmpPrefix );
// Create the names for the three files.
sprintf( datFileName, "%s.dat", tmpName );
sprintf( ackFileName, "%s.ack", tmpName );
sprintf( atnFileName, "%s.atn", tmpName );
// Create data file.
datFile = fopen( datFileName, "a" );
// Make sure data file didn't already exist.
if ( NULL != datFile )
{
// Seek to the end of the file.
fseek( datFile, 0, SEEK_END );
if( 0 == fgetpos( datFile, &pos ) )
{
// We know fgetpos was successful, now check position.
// If pos is zero, we know we have a new file and can break out of loop.
if ( 0 == pos ) break;
}
fclose( datFile );
}
}
// We could check REQUEST_METHOD here, but what would be the point?
// If CONTENT_LENGTH is NULL, we won't read the stdin, otherwise we will.
// This is entirely for POST method requests.
t1 = getenv( "CONTENT_LENGTH" );
if ( NULL != t1 )
{
cont_len = atoi( t1 );
tempbuffer = (char *) malloc( sizeof(char) * cont_len );
if ( NULL == tempbuffer )
{
goto CleanupAndExit;
}
bytesread = fread( tempbuffer, sizeof(char), cont_len, stdin );
if ( 0 != bytesread )
fwrite( tempbuffer, sizeof(char), bytesread, datFile );
free( tempbuffer );
}
// This part reads all of the environment variables and sends
// them along in the DAT file as well. All ampersand delimited.
envptr = environ;
while ( NULL != *envptr )
{
fputs( "&", datFile );
fputs( *envptr, datFile );
envptr++;
}
fclose( datFile );
// Create ATN File
atnFile = fopen( atnFileName,"w" );
if ( NULL == atnFile )
{
errorform( SERVER_INACCESSIBLE_TEXT_LOC , SERVER_INACCESSIBLE_TITLE_LOC );
goto CleanupAndExit;
}
fclose( atnFile );
_flushall();
// Wait for Server to ACK
time( &begintout );
do
{
tempFile = fopen( ackFileName, "r" );
if ( NULL != tempFile ) break; // Break before sleep if successful.
time( &chktout );
Sleep( ACK_RETRY_MILLISECONDS );
//if _access() can't find the file, then the query is currently being
processed.
//Keep looping for another ACK_TIMEOUT_SECONDS.
} while ( ( NULL == tempFile ) && (( difftime( chktout, begintout ) <
ACK_TIMEOUT_SECONDS )
|| ((_access(atnFileName,0) == -1) && ( difftime( chktout, begintout ) <
(2*ACK_TIMEOUT_SECONDS) ))));
if ( NULL != tempFile )
{
fclose( tempFile );
}
else
{
errorform( SERVER_TIMEOUT_TEXT_LOC , SERVER_TIMEOUT_TITLE_LOC);
goto CleanupAndExit;
}
// Send the Data file to stdout.
datFile = fopen( datFileName, "rb" );
if ( NULL == datFile )
{
errorform( SERVER_NODATA_TEXT_LOC , SERVER_NODATA_TITLE_LOC);
goto CleanupAndExit;
}
else
{
// Return results to web server.
while ( !feof( datFile ) )
{
// prb: kas stdout on binaarne
int len;
len = fread( buffer, 1, DATA_BUFFER_LENGTH, datFile );
if (len==0) break;
fwrite( buffer, 1, len, stdout );
}
fclose( datFile );
}
CleanupAndExit:
// Close all file handles.
_fcloseall();
// Remove temporary files.
remove( ackFileName );
remove( datFileName );
remove( atnFileName );
return;
}
void errorform( char *errorstring, char *errortitle )
{
printf( "Content-Type: text/html\n\n" );
printf( "<head><title>%s</title></head>\n", errortitle );
printf( "<body>\n<h1>%s</h1>\n", errortitle );
printf( "%s<hr>\n</body>", errorstring );
}
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Premature end of script headers using CGI appl in Linux
Posted by Robert Andersson <ro...@profundis.nu>.
Andrus wrote:
> goto CleanupAndExit;
Oh, dear ;-)
> // Return results to web server.
> while ( !feof( datFile ) )
> {
> // prb: kas stdout on binaarne
> int len;
> len = fread( buffer, 1, DATA_BUFFER_LENGTH, datFile );
> if (len==0) break;
> fwrite( buffer, 1, len, stdout );
I cannot see that the Content-Type header is written before this statement
is executed.
> void errorform( char *errorstring, char *errortitle )
> {
> printf( "Content-Type: text/html\n\n" );
At least on Windows, I have noted, <CRLF> must be written "\r\n", like:
printf("Content-Type: text/html\r\n\r\n");
Regards,
Robert Andersson
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: [users@httpd] Premature end of script headers using CGI appl
in Linux
Posted by Lee Fellows <lf...@4lane.com>.
On Thu, 2003-07-10 at 11:42, Andrus wrote:
> I have a CGI app which interfaces with my application. I use Apache 2
> In Windows it works OK.
>
> I re-compiled this CGI app using Windowsis Dev-C++ 4.9.8.0 using Linux
> modules.
> After that I got the following error from Apache:
>
> Premature end of script headers: eva.exe
>
> Any idea how to fix this ?
Aside from your errorform routine, it does not appear to send the needed
Content headers prior to dumping the file contents.
---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
" from the digest: users-digest-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org