![]() |
#2
sam_jiang2025-05-17 09:16
|
今天我们来探索IIS服务器是如何把请求的路径和参数发给我们cgi程序的。
当我们向浏览器发送请求:http://localhost/sample.fpx?name=samjiang时,我设想此时IIS收到请求,会把网址以参数的形式发回给我们的cgi程序,于是我为control.prg设置了2个参数,lcpath 和lcqureystring,编译试试~

parameters lcpath,lcqureystring
if parameters()=0
lcoutput="没有参数被传递!"
else
。。。
endif
很显然,这条路行不通,IIS并没有向我们的CGI程序control传递任何参数

那就说明IIS把我们的请求以环境变量的形式保存在服务器上了。
我虽不知道保存的环境变量名是什么,但这难不倒我,嘿嘿,写个foxweb脚本,看看当我们发出一个请求时,服务器会自动生成哪些环境变量。
foxweb代码:

<%
*本脚本showvars.fwx用来显示所有环境变量
dime aServerVars[1] &&定义一个服务器变量数组
nTotVars = Request.ServerVariablesArray(@aServerVars)
for i=1 to ntotvars
response.write(aServerVars[i]) &&在浏览器中显示所有环境变量
response.write("<br>")
endfor
%>
浏览器显示如下:
只有本站会员才能查看附件,请 登录
发现2个有用的环境变量PATH_TRANSLATED和QUERY_STRING,我们的CGI程序要执行自定义脚本sample.fpx时,必须知道我们的脚本保存的物理路径,以及它的请求参数(当然可以没有参数)
在这篇文章里,我们依然没有对sample.fpx脚本进行解释执行,只是为了了解IIS如何将请求传递给我们的CGI程序control。
现在我们可以对control做出更改,编译后执行试试看~~~
control.prg代码如下:

* CGI处理示例
* 定义 Windows API 常量
#DEFINE STD_INPUT_HANDLE -10
#DEFINE STD_OUTPUT_HANDLE -11
* 声明 Windows API
DECLARE Sleep IN kernel32 INTEGER dwMilliseconds
DECLARE INTEGER GetStdHandle IN kernel32 INTEGER nStdHandle
DECLARE INTEGER ReadFile IN kernel32 ;
INTEGER hFile, ;
STRING @lpBuffer, ;
INTEGER nNumberOfBytesToRead, ;
INTEGER @lpNumberOfBytesRead, ;
INTEGER lpOverlapped
DECLARE INTEGER WriteFile IN kernel32 ;
INTEGER hFile, ;
STRING lpBuffer, ;
INTEGER nNumberOfBytesToWrite, ;
INTEGER @lpNumberOfBytesWritten, ;
INTEGER lpOverlapped
* CGI 环境变量常量
CGI_CONTENT_LENGTH = "CONTENT_LENGTH"
* 主程序
CLEAR
SET TALK OFF
SET CONSOLE OFF
* 获取标准输入输出句柄
hStdIn = GetStdHandle(STD_INPUT_HANDLE)
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)
* 调试用暂停(如果需要)
=Sleep(6000) && 暂停60秒等待调试器附加
* 读取POST内容
lcContentLength = GETENV(CGI_CONTENT_LENGTH)
lnContentLength = VAL(lcContentLength)
IF lnContentLength > 0
* 准备缓冲区
lcReadBuffer = REPLICATE(CHR(0), lnContentLength)
lnBytesRead = 0
* 读取输入
=ReadFile(hStdIn, @lcReadBuffer, lnContentLength, @lnBytesRead, 0)
lcReadBuffer = LEFT(lcReadBuffer, lnBytesRead)
* 解析参数
lnPos = AT("=", lcReadBuffer)
IF lnPos > 0
lcValue = SUBSTR(lcReadBuffer, lnPos + 1)
ELSE
lcValue = lcReadBuffer
ENDIF
ELSE
lcValue = ""
ENDIF
cpath=GETENV("PATH_TRANSLATED")
cqureystr=GETENV("QUERY_STRING")
* 构建响应
lcResponse = "HTTP/1.0 200 OK" + CHR(13) + CHR(10) + ;
"Content-Type: text/html" + CHR(13) + CHR(10) + ;
CHR(13) + CHR(10) + ;
"请求路径为: " + cpath+"<br>"+;
"请求参数为:" +IIF(EMPTY(cqureystr),"没有参数!",cqureystr)
* lcResponse [color=#808080]= "HTTP/1.0 200 OK" + CHR(13) + CHR(10) + ;[/color]
"Content-Type: text/html" + CHR(13) + CHR(10) + ;
CHR(13) + CHR(10) + ;
"Hello " + lcValue
* 发送响应
lnBytesWritten = 0
=WriteFile(hStdOut, lcResponse, LEN(lcResponse), @lnBytesWritten, 0)
* 清理
CLEAR DLLS
QUIT
在浏览器中运行效果如下:
1,没有参数的情况:
只有本站会员才能查看附件,请 登录
2,有参数的情况:
只有本站会员才能查看附件,请 登录
完美。。。
预告一下~~~ 下一篇,我们就可以执行我们自己的脚本了