谈谈在WebServer中如何实现CGI技术
在WebServer中,cgi技术的实现相信许多人很感兴趣,不过在一些开源软件如Apache中,由于软件规模大,相关模块多,直接去读懂是如何实现的比较费劲,下面就来谈谈CGI技术的实现方法。
要实现CGI技术,关键是要实现执行其他应用程序时,将应用程序的输出从屏幕重定向到SOCKET中去,实现了应用程序的输出重定向后,CGI实现就很简单了。
下面以windows平台为例来实现cgi技术。以下的cgi_writeclient()函数便实现了将CGI程序的输出结果重定向到socket的功能。
HANDLEcgi_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技术相关推荐

  1. 关于.NET中的Server push技术

    关于.NET中的Server push技术 一般来说方法有2种,一种就是客户端用JS异步定时轮询服务器端,这种是大部分人采用的方法,但是我在想到底可以不可以实现服务器端有改变时才会主动推送到客户端呢? ...

  2. usb禁止重定向_远程桌面中的USB重定向技术解析(功能篇)

    在运行远程和虚拟桌面的数据中心内,网络管理员可以对计算环境的各个方面进行控制.只有一点除外,就是本地外围设备. 本地外围设备包括所有连接到终端上的设备,例如USB驱动器.鼠标或打印机.它们逐渐成为终端 ...

  3. Maya 2022中的硬表面建模技术学习视频教程

    Maya 2022中的硬表面建模 信息: 使用正确的拓扑和边流在Maya中建模硬曲面对象. 你会学到什么 硬质表面工具和技术 细分工作流程 边缘流动控制 正确拓扑 材料设置 Studio Lightn ...

  4. freemarker中运算符_如何在Web应用系统表示层开发中应用Velocity模板技术

    软件项目实训及课程设计指导--如何在Web应用系统表示层开发实现中应用Velocity模板技术 1.分离Web表示层的数据处理和展现逻辑的常见的应用技术 分离Web表示层的数据处理和展现逻辑是目前企业 ...

  5. 游戏中应用强化学习技术,目的就是要打败人类玩家?

    来源:AI前线 作者:凌敏 采访嘉宾:黄鸿波 2016 年,DeepMind 公司开发的 AlphaGo 4:1 大胜韩国著名棋手李世石,成为第一个战胜围棋世界冠军的人工智能机器人,一时风头无两.Al ...

  6. EBS R12中如何使用CGI登录Form

    虽然听说在R12中没有CGI这个说法,但是搜了半天都是这么用的(CGI),姑且用这个词吧. 默认情况下R12中$CONTEXT_FILE中的 s_appserverid_authentication ...

  7. 29个月过去了,CSDN排名前200了:排名不断靠前的过程中,自己的技术水平和竞争力一定会不断向上...

    2019独角兽企业重金招聘Python工程师标准>>> 刚刚在csdn博客又发表了一篇,工作问题总结,突然发现,我的博客排名终于进入前200了. 这又是一个伟大的里程碑啊. 在过去2 ...

  8. DotNET企业架构应用实践-系统架构与性能-缓存技术与ORM中的缓存查询技术

    系列回顾 在前面的文章DotNET企业架构应用实践-系统架构与性能-理论依据及相关做法一文中我介绍了系统性能优化的理论做了一个概括的介绍,也简单的介绍了性能优化的过程及相关的技术关注点或者说是做法. ...

  9. 服务总线yali测试_中国信登加快技术测试体系建设支撑系统高质量运行

    ↑ 点击上方蓝字关注我们 为支撑中国信登信息系统高质量运行,提升服务我国信托行业综合能力,中国信登加快技术测试体系建设,从信息系统建设的事前.事中和事后入手,在信息系统的功能测试.非功能测试及软件全生 ...

  10. 计算机网络技术在农业中的应用,计算机网络技术在农业节水灌溉系统中的运用——评《计算机网络技术与应用实践》...

    计算机网络技术在农业节水灌溉系统中的运用--评<计算机网络技术与应用实践> 计算机网络技术日臻成熟,在农业领域的应用也更加普及,尤其是节水灌溉系统与计算机网络技术的整合,大大提升了农业节水 ...

最新文章

  1. POJ3270 Cow Sorting ——置换群
  2. xml布局显示需要预判断,可是还没有show出来,怎么办?
  3. 福田车载无线充电器方案开发设计_过年自驾回家,带上优胜仕车载无线充电器,一放即充导航无忧...
  4. 中南大学c语言程序设计2013年下学期期末考试,2013级计算机专业本科生C语言程序设计期末考试资料.doc...
  5. python tempfile 创建临时目录
  6. java swing刷新_Swing界面刷新问题(转)
  7. 陪孩子看完这几部高分纪录片,胜过出国亲子游!
  8. 在laravel5.8中集成swoole组件----初步测试
  9. Redis缓存持久化:RDB持久化和AOF持久化
  10. 使用vSAN RVC进一步了解vSAN环境
  11. 集合数组集合ArrayList
  12. 在TPU上运行PyTorch的技巧总结
  13. 幽默感也有套路:可用数学模型量化
  14. 批量解压多个zip压缩包并将解压出来的文件以该压缩包的名称重命名
  15. word调整标题编号
  16. python金融量化书籍_超强干货 | Python金融数据量化分析教程+机器学习电子书
  17. SAP中采购订单中的汇率是如何确定的
  18. html励志素材,名人励志故事素材
  19. 中国保健品市场供需规模与投资前景预测分析报告2022-2027年版
  20. 大学实验室文献检索方法

热门文章

  1. linux命令中tar什么意思,Linux中tar命令起什么作用呢?
  2. Amaze UI貌似挂了。。。附上amaze UI框架的图标
  3. 想找一款读书笔记软件?快来试试BookxNote
  4. 任意多边形的最大内切圆算法
  5. Java 文件上传同时携带参数
  6. Speex的安装使用
  7. 学海无涯——人工智能应用实例之写作软件的基本概念
  8. JavaEE:MySQL主从配置
  9. 为什么快捷指令无法将媒体转换为文本_刘星文:快捷指令这个神器,让你的 iPhone 好用到飞起...
  10. 基于matlab的最小二乘法曲线拟合实现,最小二乘法曲线拟合MATLAB实现