ID:               24463
 User updated by:  nospam at kolbly dot com
 Reported By:      nospam at kolbly dot com
 Status:           Open
-Bug Type:         Feature/Change Request
+Bug Type:         IIS related
 Operating System: Win2003 Server
 PHP Version:      4.3.2
 New Comment:

An update and some additional comments :

I have been able to suck out odbc calls from the php source php_odbc.c
and been able to recreate the problem using code I'll post to the end
of this message.

I've successfully opened up a case w/Microsoft and they're in the
process of recreating the problem in their labs.  I'll post their
results here.

One note : php_odbc.c has many calls that are deprecated by Microsoft. 
This may or may not be a contributing factor.  I've been able to
successfully eliminate the problem on my test platform by adding a
Sleep(1) at the end of each of the following functions in php_odbc.c -
SQLFreeStmt(), SQLDisconnect(), SQLFreeConnect(), and SQLFreeEnv().  

Unrelated side note to PHP developers: When PHP is compiled with Cygwin
utils instead of the win32build\bin utils, then php.ini ALWAYS has a
parsing problem at the last line.  An update to the windows install doc
would likely save many a developer some frustration.  


breakiis.c .....

#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <stdlib.h>

#include <time.h>
#include <stdio.h>

#define MYSQLSUCCESS(rc)
((rc==SQL_SUCCESS)||(rc==SQL_SUCCESS_WITH_INFO))
#define MAX_NAMES       100
#define MAX_NAME_SIZE 25

#define DSN     "bug"                                   // ODBC System Data Source, 
points to Northwind
DB
#define DB_USER "buguser"               // Database user with privileges on
Northwind DB
#define DB_PASS "bugpass"               // Database password

#define LOGFILE "d:\\weblogs\\mydebug.log"

void single_page_load();
void auto_reload_page();
void get_data_using_odbc(int *count, char names[][MAX_NAME_SIZE]);

void mydebug(const char *msg);

/**

****************************************************************************
 * main()
 *
 * Try to break IIS using native ODBC funcs

****************************************************************************
 */
int main(int argc, char* argv[])
{
        mydebug("main() start...");

        auto_reload_page();

        mydebug("main() end...");

        return 0;
}


/**

****************************************************************************
 * get_data_using_odbc()
 *
 * Connect to the SQL Server 2000 Database Northwind
 * Setup an ODBC DataSource named DSN, a Database user DB_USER, and 
 * password DB_PASS.

****************************************************************************
 */
void get_data_using_odbc(int *count, char names[][MAX_NAME_SIZE])
{
   RETCODE rc;                                          // ODBC return code
   HENV henv;                                           // Environment   
   HDBC hdbc;                                           // Connection handle
   HSTMT hstmt;                                 // Statement handle
   unsigned char szData[100];   // Returned data storage
   SDWORD cbData;                                       // Output length of data
        int index = 0;
        DWORD zzz = 1;                                  // Sleep period - Set to 1 to 
aleviate problem

        mydebug("get_data_using_odbc() start...");


        // Connect Up
   SQLAllocEnv(&henv);
   SQLAllocConnect(henv,&hdbc);

   rc = SQLConnect(hdbc, (SQLCHAR *)DSN, SQL_NTS, (SQLCHAR *)DB_USER,
SQL_NTS, (SQLCHAR *)DB_PASS, SQL_NTS);
   
        // Exec Stmt
   rc = SQLAllocStmt(hdbc,&hstmt);
  
        rc = SQLExecDirect(hstmt, (SQLCHAR *)"SELECT FirstName FROM
employees", SQL_NTS);

        for (rc = SQLFetch(hstmt); (rc == SQL_SUCCESS) && (index < MAX_NAMES);
rc=SQLFetch(hstmt))
   {
                SQLGetData(hstmt, 1, SQL_C_CHAR, szData, sizeof(szData), &cbData);
                sprintf(names[index], "%s", (const char *) szData);
                index++;
   }
        *count = index;

   SQLFreeStmt(hstmt, SQL_DROP);
                //Sleep(zzz);

   rc = SQLDisconnect(hdbc);
                //Sleep(zzz);

   rc = SQLFreeConnect(hdbc);
                //Sleep(zzz);

        rc = SQLFreeEnv(henv);
                //Sleep(zzz);

        mydebug("get_data_using_odbc() end...");

}// get_data_using_odbc()


/**

****************************************************************************
 * auto_reload_page()
 *
 * Have the web page keep reloading itself while incrementing a
counter

****************************************************************************
*/
void auto_reload_page()
{
        char *data;
        double count;

        int i;
        char names[MAX_NAMES][MAX_NAME_SIZE];
        int num = 0;

        mydebug("auto_reload_page() start...");

        ZeroMemory(names, sizeof(names));

        // Comment out below and this page reloads just fine
        get_data_using_odbc(&num, names);

        data = getenv("QUERY_STRING");
        if(data == NULL) 
                count=1;
        else
                count = atof(data);

        printf("content-type: text/html\n\n");

        printf("<html>");
        printf("<head>");
        printf("<title>BreakIIS</title>");
        printf("<meta http-equiv=\"Content-Type\" content=\"text/html;
charset=iso-8859-1\">");
        printf("</head>");
        printf("<body>");
        printf("Loading page with value %5f<br><br>\n", count);
        count++;

        for (i = 0; i < num; i++) {
                printf("%s<br>\n", names[i]);
        }

        printf("<script>location.href='breakiis.exe?%f'</script>", count);

        printf("</body>");
        printf("</html>");
        
        mydebug("auto_reload_page() end...");

}// auto_reload_page()


/**

****************************************************************************
 * void single_page_load()
 *
 * Have the web page keep reloading itself once the user presses
"submit"

****************************************************************************
*/
void single_page_load()
{
        int i;
        char names[MAX_NAMES][MAX_NAME_SIZE];
        int num = 0;

        ZeroMemory(names, sizeof(names));

        get_data_using_odbc(&num, names);

        printf("content-type: text/html\n\n");

        printf("<html>");
        printf("<head>");
        printf("<title>BreakIIS</title>");
        printf("<meta http-equiv=\"Content-Type\" content=\"text/html;
charset=iso-8859-1\">");
        printf("</head>");
        printf("<body>");

        for (i = 0; i < num; i++) {
                printf("%s<br>\n", names[i]);
        }

        printf("<form name=\"form1\" method=\"post\"
action=\"breakiis.exe\">");
        printf("<p>Click Submit to post back to this page.</p>");
        printf("<input type=\"submit\" name=\"Submit\" value=\"Submit\">");
        printf("</form>");

        printf("</body>");
        printf("</html>");

}// single_page_load()

/**

****************************************************************************
 * mydebug()
 *
 * Simply write a logfile to LOGFILE

****************************************************************************
 */
void mydebug(const char *msg)
{

        char datetime[120];
        FILE *f;
        time_t curtime;
        struct tm *loctime;

        ZeroMemory(datetime, sizeof(datetime));

        curtime = time(NULL);
        loctime = localtime(&curtime);
        strftime(datetime, 119, "%Y-%m-%d %H:%M:%S", loctime);

        f = fopen(LOGFILE, "a");
        if (f) {
                fprintf(f, "%s : %s\n", datetime, msg);
                fclose(f);
        }

}// mydebug()


Previous Comments:
------------------------------------------------------------------------

[2003-07-02 13:19:35] nospam at kolbly dot com

Description:
------------
When redirecting to a .php page that connects to an SQL Server database
via ODBC, IIS produces a 502 error intermittently on slower machines
and 100% on faster machines.

This is admittedly a duplicate of Bug #9852 (Which is currently
closed),  but my tests have pointed that the problem is with PHP, not
IIS.  

I have opened up an Incident with Microsoft and we are at the point
where if I can reproduce the bug using some non-php code, they will
duplicate my setup exactly in their lab and have their developers
tackle it.  But, so far I cannot reproduce the error with any non-php
code.  I traced the php function calls, and wrote a C program that
calls the exact same odbc calls as php, but this does NOT break IIS.  I
can only conclude that the issue is within PHP or Zend or at the very
least it is still very much in doubt as to which code is at fault
here.

I have tried ALL the suggested workarounds from Bug #9852 with no luck.
 I will be forced to rewrite 8 websites in .asp or .net if I can’t fix
this.   

If anybody has a way to reproduce this error using C/C++/C#/ASP or some
other “Microsoft-Approved” language, please send me your source code.
([EMAIL PROTECTED])


Reproduce code:
---------------
<?php
$dbconn = odbc_connect("bug", "buguser", "bugpass");
$rs = odbc_exec($dbconn, "select * from employees");
while(odbc_fetch_row($rs)) {
        $EmployeeID = odbc_result($rs, "EmployeeID");
}
if (isset($_POST['Submit'])) {
        header("Location: test1a.php"); die;
}
?>
<html>
<head>
<title>Bug Test</title>
<meta http-equiv="Content-Type" content="text/plain;
charset=iso-8859-1">
</head>
<body>
<form name="form1" method="post" action="test1a.php">
<p>Click Submit to post back to this page.</p>
<input type="submit" name="Submit" value="Submit">
</form>
</body>
</html>

Expected result:
----------------
Click Submit to post back to this page.

[Submit]

Actual result:
--------------
CGI Error
The specified CGI application misbehaved by not returning a complete
set of HTTP headers.


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=24463&edit=1

Reply via email to