谈谈在WebServer中如何实现CGI技术
来源:互联网 发布:福利彩票 知乎 编辑:程序博客网 时间:2024/05/01 04:43
谈谈在WebServer中如何实现CGI技术
在WebServer中,cgi技术的实现相信许多人很感兴趣,不过在一些开源软件如Apache中,由于软件规模大,相关模块多,直接去读懂是如何实现的比较费劲,下面就来谈谈CGI技术的实现方法。
要实现CGI技术,关键是要实现执行其他应用程序时,将应用程序的输出从屏幕重定向到SOCKET中去,实现了应用程序的输出重定向后,CGI实现就很简单了。
下面以windows平台为例来实现cgi技术。以下的cgi_writeclient()函数便实现了将CGI程序的输出结果重定向到socket的功能。
HANDLE cgi_exec( HANDLE hPipeWrite, char *exefile, char *cmdline, char *lpszCurrentPath )
{
BOOL bSucceed;
STARTUPINFO sui;
PROCESS_INFORMATION pi;
BOOL bTest;
memset(&sui,0,sizeof(STARTUPINFO));
sui.cb=sizeof(STARTUPINFO);
sui.dwXSize = 0;
sui.dwXSize = 0;
sui.wShowWindow = SW_HIDE;
sui.dwFlags= STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
sui.hStdInput=NULL;
sui.hStdOutput=hPipeWrite;
sui.hStdError=hPipeWrite;
bSucceed = CreateProcess(exefile,
cmdline,
NULL,
NULL,
TRUE,
0,//CREATE_NEW_PROCESS_GROUP ,
NULL,
lpszCurrentPath,//lpszPath,//"//Rose//c//",//NULL,//"d:/ip_progs/namepipe/child",
&sui,
&pi);
if ( bSucceed )
{
CloseHandle( pi.hThread );
return pi.hProcess;
}
// ShowErrorMessage( "CreateProcess()" );
return FALSE;
}
int cgi_writeclient( HTTPRequest *hr )
{
char *pszPath;
HANDLE hProcess;
BOOL bProcessDead = FALSE;
HANDLE hPipeRead, hPipeWrite;
SECURITY_ATTRIBUTES SecAttrib;
int ret;
int BytesInPipe;
char *buf;
DWORD dwRead;
SecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES);
SecAttrib.lpSecurityDescriptor = NULL;
SecAttrib.bInheritHandle = TRUE;
if ( hr->http_mod != HTTP_GET )
{
return MODULE_RUN_CONTINUE;
}
if ( hr->mod != MOD_LOCAL )
{
return MODULE_RUN_CONTINUE;
}
pszPath = MemAlloc( hr->hMem, strlen( pszCgiRoot ) + strlen(hr->http_url) + 10 );
if ( !pszPath )
{
return MODULE_RUN_CONTINUE;
}
/* decide if it is the cgi path */
strcpy( pszPath, hr->http_url );
if ( pszPath[strlen(pszPath)-1] == '/' )
{
if ( *(hr->http_url) == '/' )
{
strcat( pszPath, hr->http_url+1 );
}
else
{
strcat( pszPath, hr->http_url );
}
}
else
{
strcpy( pszPath, pszRoot );
strcat( pszPath, hr->http_url );
ReplaceChar( pszPath, '//', '/' );
}
if ( strnicmp( pszPath, pszCgiRoot, strlen(pszCgiRoot) ) != 0 )
{
return MODULE_RUN_CONTINUE;
}
ret = CreatePipe( &hPipeRead, &hPipeWrite, &SecAttrib, 65536 );
buf = MemAlloc( hr->hMem, 1024 );
hProcess = cgi_exec( hPipeWrite, NULL, pszPath, NULL );
while ( !bProcessDead )
{
int dwRet;
dwRet = WaitForSingleObject( hProcess, 1 );
if ( dwRet != WAIT_TIMEOUT )
{
bProcessDead = TRUE;
}
if (!PeekNamedPipe(hPipeRead, NULL, 0, NULL, &BytesInPipe, NULL))
{
break;
}
if ( BytesInPipe != 0 )
{
memset( buf, 0, sizeof(buf) );
dwRead = 0;
if ( ReadFile( hPipeRead, buf, 1024, &dwRead, NULL ) )
{
if ( dwRead > 0 )
{
send( hr->s, buf, dwRead, 0 );
}
}
}
}
do
{
if (!PeekNamedPipe(hPipeRead, NULL, 0, NULL, &BytesInPipe, NULL))
{
break;
}
if ( BytesInPipe != 0 )
{
memset( buf, 0, sizeof(buf) );
dwRead = 0;
if ( ReadFile( hPipeRead, buf, 1024, &dwRead, NULL ) )
{
if ( dwRead > 0 )
{
send( hr->s, buf, dwRead, 0 );
}
}
}
} while ( BytesInPipe != 0);
MemFree( hr->hMem, buf );
CloseHandle( hProcess );
CloseHandle( hPipeRead );
CloseHandle( hPipeWrite );
return MODULE_RUN_ENDSESSION;
}
在以上代码中,cgi_exec是实现创建进程,并将进程的输出定向到管道中,然后在cgi_writeclient()函数中,先创建管道,然后调用cgi_exec()函数创建cgi进程并将其输出定向到刚创建的管道中, 然后调用WaitForSingleObject()函数来等待CGI进程运行,注意不是等到进程结束后才从管道读数据。
在cgi进程的运行过程中,每等一段时间,就从管道中读取一部分数据,调用send()函数发送到socket中去。当等到cgi进程结束后,再从管道中将剩余的数据全部读出发送到socket中去。这样就实现了cgi的功能。
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 谈谈在WebServer中如何实现CGI技术
- 在WebServer中如何实现CGI技术
- 关于hook设置函数如何支持多核CPU的一个说明
- 双核CPU上的快速排序效率
- 《多任务下的数据结构与算法》一书中的红黑树的测试代码,供读者参考!
- 《多任务下的数据结构与算法》一书的勘误
- 关于goto语句能不能从复杂的嵌套循环判断中跳出去的问题讨论
- 谈谈在WebServer中如何实现CGI技术
- 关于栈的弹出函数设计是否应该有两个返回值,一个表示数据,一个表示是否栈为空
- 大家对《多任务下的数据结构与算法》如有建议,请发表到这里
- 《多任务下的数据结构与算法》主要新特色及新内容介绍
- 《多任务下的数据结构与算法》一书的目录
- ASP.NET 2.0当中的Call back技术与ASP.NET AJAX
- 关于笔记本电脑执行速度的瓶颈
- 台湾微软网站上的Silverlight教学影片
- 2007软件开发2.0大会课程之一:ASP.NET AJAX 与 Silverlight 的完美结合