转自:http://iammr.7.blog.163.com/blog/static/491026992008105113520189/
基本方法如下(只不过我下的是:httpd-2.2.25-win32-src.zip)
1. 目的起因
到处讲的都是Web服务器工作原理,什么URL连接请求->响应;但是想看看到底怎么实现的。此外,配置apache时,生拼硬凑的很多选项,只知道这么做,不知道为什么这样做。最后,还想看看它的模块是如何动态添加,有什么模块的公共接口之类。这就是想看apache源代码的原因,纯属业余爱好。
2. 编译调试
? 安装
从http://httpd.apache.org/download.cgi下载源代码,解压安装。下载的是2.2.10,准备在windows环境,vs2008编译器下测试。
在vs2008中打开解决方案文件“Apache.dsw”,接受提示升级转换。里面几个工程:
l BuildAll : 由此编译所有工程
l Httpd : 对应服务程序 httpd.exe
? 编译
编译[BuildAll]时会发现有很多错误,其中这个错误很多,如下:
1>fatal error RC1107: invalid usage; use RC /? for Help
1>Project : error PRJ0002 : Error result 1 returned from 'C:\...\bin\rc.exe'.
主要原因是各工程文件(*.vcproj)中存在如下:
LONG_NAME="Apache HTTP Server"
LONG_NAME="Apache HTTP Server";ICON_FILE="apache.ico"
只需要去掉引号,改成类似如下即可:
LONG_NAME=Apache HTTP Server
但是工程很多,可以通过正则表达式替换。步骤如下:
先单独将工程[httpd]的在工程属性中修改:
然后关掉解决方案,通过查找替换进行,图示如下:
说明:
l 之所以单独处理[httpd]主工程,是因为正则表达式查找替换的时候唯独它中内容“LONG_NAME=”不是最后一项,导致替换时有点问题。
l 之所以关掉解决方案进行查找替换,是因为打开时,一旦替换某个工程,就会弹出对话框说修改了必须重新装载,很是麻烦。
? 环境配置
编译完成,应该发现代码所在硬盘根目录多了一个 apache22目录。里面的目录组织和打包安装的目录组织一样。在调试新服务时,如果有老服务,先卸掉。
要卸掉已安装的apache服务。在命令行中,进入当时apache的bin目录下。运行:
httpd -k stop #停止服务
httpd -k uninstall #卸载服务
新服务的安装卸载也可以在命令行中进行。在命令行中,新的apache22\bin目录,运行:
ApacheMonitor.exe #建议先打开服务监控程序在托盘中看状态
httpd -k install #安装服务
httpd -k start #启动服务
此时有可能会弹出windows的断言对话框,忽略。
还有可能会有错误。有可能是配置文件不当引起的。新的apache目录中,子目录组织和安装包安装的目录一样,但是里面的文件有的子目录可能缺少。例如:[conf]目录下少了“mime.types”,[logs]目录下没有日志等文件。建议将以前的目录中这两个目录都copy过来,记住有一个地方要修改。Httpd.conf中的:
#原始目录
ServerRoot "F:/PopularSoft/Apache"
#改为当前目录
ServerRoot "E:/ Apache22"
相应的根据实际情况再修改。这样,整个运行环境都弄好了。
? 调试
如果要调试服务的安装卸载、启动停止、配置文件读取、模块动态加载,直接调试httpd工程即可,
对应的int main(int argc, const char * const argv[]) 即可(in “main.c”, Lin 447)。
如果要想调试url的请求分析响应是如何实现的,就必须调试apache服务,通过附加进程的方式来实现。
选中“显示所有用户进程”,一般有两个httpd进程,如何识别到底是哪一个呢?
在任务管理器中通过 view->Select Column…设置成如下界面:
附加那个线程数多的pid进程即可。
进入调试状态,在工程[libhttpd]中打断点(in “child.c”, Lin 776, at ” ap_process_connection(c, context->sock);”)。然后在浏览器输入http://localhost 即可进入调试。此时再根据堆栈在感兴趣地方打断点调试。(http连接的函数ap_process_connection,所有的http请求都会经过这里。)
说明:我在调试过程中时,这一步总是失败,没有反应;在多个工程中打断点都不行。最后清空cookie和所有历史记录,才发现突然好了。建议多准备几个页面,来回切换,避免因为历史记录导致压根没提交到apache服务中。