Req #24463 [Opn->Csd]: SQL Server Query + Redirect = 502 Error
| From: | cmb@php.net | Date: | Wed, 20 Sep 2017 14:18:19 +0000 |
| Subject: | Req #24463 [Opn->Csd]: SQL Server Query + Redirect = 502 Error | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-211270@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=24463&edit=1
ID: 24463
Updated by: cmb@php.net
Reported by: nospam at kolbly dot com
Summary: SQL Server Query + Redirect = 502 Error
-Status: Open
+Status: Closed
Type: Feature/Change Request
Package: ODBC related
Operating System: Win2003 Server
PHP Version: 4.3.2
-Assigned To:
+Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
> As for the ODBC code, yes it is all based on ODBC v2, [â¦]
This has changed in the meantime, so I'm closing this ticket.
Previous Comments:
------------------------------------------------------------------------
[2005-01-28 09:08:40] jconnolly at eedo dot com
i WROTE breakiis.c. i noticed the stolen code in that breakiis example, ha ha ha, nice though, mine
was specifically designed to be basic but i noticed the cout stuff is my code exactly, anways, YES,
i'm gonna marry a carrot,.... ohhh, she admitted it, she's gonna marry a carrot...
Jeff Connolly
jconnolly@eedo.com
------------------------------------------------------------------------
[2003-08-05 13:50:08] nospam at kolbly dot com
Some progress is being made on Microsoft's end and we seem to have a viable working workaround
now that does NOT involve slowing down page redirects. This appears to work under both Win2000 and
Win2003.
When IIS spits out a 502 error, it appears that our CGI exe does not even get loaded. When IIS
first loads up the CGI exe - it appears to fail during a Loadlibrary() call. Which library fails to
load is still undetermined because so far when any debuggers are attached to the IIS process, the
problem cannot be reproduced. The best working theory at this point is that some ODBC code is
setting up a very fast global lock that IIS can subsequently run into later on if the next call is
fast enough. The workaround involves running the CGI as the "system" account instead of a
"user" account by changing a setting in the IIS metabase. The system account apparently
does not have a problem with our potential global locks not releasing.
To change the IIS metabase setting, create a VBS file called fixiis.vbs and paste the following code
there :
dim oIISObj
Set oIISObj = GetObject("IIS://localhost/W3SVC/1/Root")
oIISObj.CreateProcessAsUser = False
oIISObj.SetInfo
Set oIISObj = nothing
So far this has "Fixed" my problem on every configuration I've tried. If you want to
do this, please do consider the security considerations of running your PHP code under the system
account
------------------------------------------------------------------------
[2003-07-08 15:19:59] kalowsky@php.net
As for the ODBC code, yes it is all based on ODBC v2, a large percentage of which has been
depricated. There is movement to udpate this, but ODBC spec REQUIRES that there be backwards
compatiblity options with newer spec drivers. I don't believe that is the issue at all. Not
sure if this should be marked as IIS or ODBC related...
------------------------------------------------------------------------
[2003-07-08 15:01:58] nospam at kolbly dot com
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()
------------------------------------------------------------------------
[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 cant 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. (nospam@kolbly.com)
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 https://bugs.php.net/bug.php?id=24463&edit=1