第1章 使用Apache进行应用程序开发 1
1.1 Apache Web服务器简史 1
1.1.1 Apache 1 1
1.1.2 Apache 2 2
1.2 Apache软件基金会 3
1.2.1 功绩组织模式(Meritocracy) 4
1.2.2 角色 4
1.2.3 哲学理念 6
1.3 Apache开发流程 6
1.3.1 Apache代码仓库 7
1.3.2 开发者论坛 9
1.3.3 开发人员 10
1.3.4 参与Apache工作 11
1.4 Apache和知识产权 12
1.4.1 Apache许可证 12
1.4.2 第三方知识产权 15
1.5 进一步阅读资料 16
1.5.1 交互式在线论坛 16
1.5.2 会议 17
1.5.3 网站 17
1.6 小结 19
第2章 Apache平台和架构 21
2.1 纵览 21
2.2 Apache运行的两个阶段 22
2.2.1 启动阶段 23
2.2.2 运行阶段 25
2.2.3 停止阶段 26
2.3 多处理模块MPM 26
2.3.1 为什么需要MPM 26
2.3.2 UNIX类的MPM模块 27
2.3.3 MPM模块和操作系统 28
2.4 基本概念和数据结构 29
2.4.1 request_rec 30
2.4.2 server_rec 35
2.4.3 conn_rec 37
2.4.4 process_rec 39
2.5 其他的关键API组件 39
2.6 Apache配置基础 41
2.7 Apache的请求处理 42
2.7.1 内容生成 42
2.7.2 请求处理阶段 43
2.7.3 处理钩子 44
2.7.4 数据轴和过滤器 46
2.7.5 处理的顺序 49
2.7.6 处理钩子 50
2.8 小结 51
第3章 Apache可移植运行时库 53
3.1 APR 54
3.2 APR实用库 56
3.3 基本的约定 57
3.3.1 参考手册:API文档和Doxygen 57
3.3.2 命名空间 57
3.3.3 声明的宏 58
3.3.4 apr_status_t和返回值 58
3.3.5 条件编译 59
3.4 资源管理:APR池 59
3.4.1 资源管理的问题 60
3.4.2 APR池 61
3.4.3 资源的生命周期 65
3.4.4 池的局限性 68
3.5 精选的APR主题 68
3.5.1 字符串和格式 69
3.5.2 国际化 69
3.5.3 时间和日期 70
3.5.4 数据结构 70
3.5.5 Bucket和Brigade 74
3.5.6 文件系统 76
3.5.7 网络 76
3.5.8 编码和密码 76
3.5.9 URI处理 77
3.5.10 进程和线程 78
3.5.11 资源池 78
3.5.12 API扩展 79
3.6 APR/Apache中的数据库 79
3.6.1 DMB和apr_dbm模块 80
3.6.2 SQL数据库和apr_dbd 82
3.7 小结 83
第4章 编程技巧和忠告 85
4.1 Apache编程约定 85
4.1.1 代码行 86
4.1.2 函数 86
4.1.3 代码块 86
4.1.4 流控制 87
4.1.5 声明 87
4.1.6 注释 87
4.2 管理模块数据 88
4.2.1 配置向量 88
4.2.2 生命周期域 88
4.3 模块之间的通讯 90
4.4 线程安全的编程问题 92
4.5 管理持久数据 93
4.5.1 线程安全 93
4.5.2 内存/资源管理 96
4.6 跨平台编程的问题 99
4.6.1 示例:创建一个临时文件 100
4.7 跨MPM编程问题 101
4.7.1 进程和全局锁 102
4.7.2 内存共享 104
4.8 安全编程问题 106
4.8.1 预防性原则:不要相信任何事情 107
4.8.2 拒绝服务攻击:限制破坏 109
4.8.3 采用操作系统来帮助你 111
4.9 外部的依赖和库 114
4.9.1 第三方的库 114
4.9.2 库的最佳实践 114
4.9.3 使用库构建模块 118
4.10 使用其他语言编写和编译模块 120
4.11 小结 122
第5章 开发内容生成器 123
5.1 HelloWorld模块 124
5.1.1 模块构架 124
5.1.2 返回值 126
5.1.3 处理器的字段 127
5.1.4 完整的模块 127
5.1.5 使用request_rec对象 129
5.2 请求、响应和环境 130
5.2.1 I/O模块 132
5.2.2 读取表单数据 138
5.3 默认的处理器 144
5.4 小结 148
第6章 请求处理周期和元数据处理器 151
6.1 HTTP超文本传输协议 152
6.1.1 HTTP协议 152
6.1.2 解构HTTP请求 153
6.2 Apache的请求处理过程 155
6.2.1 映射至文件系统 156
6.2.2 内容协商 158
6.2.3 安全性 160
6.2.4 操作缓存 160
6.2.5 私有元数据 160
6.2.6 记录日志 161
6.3 转移请求:内部重定向 161
6.3.1 错误文档 162
6.3.2 处理格式错误的请求和恶意请求 163
6.4 采集信息:子请求 163
6.4.1 示例 165
6.5 开发模块 168
6.5.1 选择文档中不同的变量 168
6.5.2 错误处理和复用性 172
6.6 小结 174
第7章 AAA:访问、认证和授权 177
7.1 安全 177
7.1.1 认证:安全的层次 178
7.1.2 登录Web 180
7.2 AAA的概览 180
7.3 Apache1.x和2.0中的AAA 182
7.4 Apache2.1/2.2中的AAA 182
7.4.1 基于主机的访问控制 183
7.4.2 认证:check_user_id 183
7.4.3 密码查询(password lookup) 184
7.4.4 授权 184
7.5 AAA逻辑 185
7.5.1 认证和Require指令 186
7.5.2 拒绝访问 186
7.5.3 认证方法 187
7.6 编写AAA模块 187
7.6.1 一个基本认证提供者 188
7.6.2 一个授权函数 190
7.6.3 配置 193
7.6.4 基本认证提供者和摘要认证提供者 193
7.7 实现一个定制的登录机制 195
7.7.1 使用SQL进行会话管理 196
7.7.2 在没有浏览器认证对话框时进行认证 197
7.8 小结 199
第8章 过滤模块 201
8.1 输入过滤器和输出过滤器 202
8.2 内容过滤器、协议过滤器和连接过滤器 202
8.3 剖析过滤器 205
8.3.1 回调函数 205
8.3.2 流水线 205
8.4 过滤器API和对象 207
8.4.1 输出过滤器 207
8.4.2 输入过滤器 207
8.5 过滤器对象 208
8.6 过滤器输入/输出 210
8.7 巧妙的Apache 2.2过滤机制 211
8.7.1 预处理和后处理 212
8.7.2 mod_filter 213
8.7.3 过滤器的自配置 213
8.7.4 协议处理 215
8.8 示例:通过直接操作Bucket来过滤文本 217
8.8.1 Bucket函数 217
8.8.2 过滤器 218
8.9 复杂解析 221
8.10 使用现有的解析器进行过滤 225
8.11 类似stdio的过滤器输入/输出 227
8.12 输入过滤器和Pull API 230
8.12.1 模式 231
8.12.2 阻塞(Block) 231
8.12.3 readbytes 231
8.12.4 输入过滤器示例 232
8.13 小结 235
第9章 模块配置 237
9.1 配置基础 237
9.2 配置数据结构 239
9.3 管理模块配置 239
9.3.1 模块配置 239
9.3.2 服务器配置和目录配置 240
9.4 实现配置指令 242
9.4.1 配置函数 242
9.4.2 示例 244
9.4.3 配置函数中的用户数据 244
9.4.4 封装配置函数 245
9.4.5 配置的作用域 246
9.4.6 配置函数类型 246
9.5 配置层次结构 250
9.6 配置函数中的上下文 255
9.6.1 上下文检查 255
9.6.2 方法和 256
9.7 定制配置容器 257
9.8 可选的配置方法 261
9.9 小结 262
第10章 扩展API 263
10.1 在Apache中实现新的函数 264
10.1.1 导出函数 264
10.1.2 可选函数 265
10.2 钩子与可选钩子 267
10.2.1 进一步研究钩子程序 267
10.2.2 执行顺序 269
10.2.3 可选钩子示例:mod_authz_dbd 270
10.3 提供者API 272
10.3.1 实现 274
10.3.2 实现提供者 275
10.4 以服务方式提供API扩展 277
10.4.1 例子:mod_dbd 277
10.4.2 实现reslist 278
10.5 跨平台API构建 284
10.5.1 使用预处理指令 285
10.5.2 声明模块API 286
10.6 小结 288
第11章 Apache数据库框架 289
11.1 对新框架的需求 290
11.1.1 Apache 1.x/2.0和Apache 2.2 290
11.1.2 连接池 290
11.2 DBD架构 292
11.3 apr_dbd API 292
11.3.1 数据库操作 294
11.3.2 API函数 298
11.4 使用ap_dbd API 302
11.5 一个示例应用模块:mod_authn_dbd 303
11.6 开发一个新的DBD驱动 306
11.6.1 apr_dbd_internal.h头文件 307
11.6.2 输出驱动 307
11.6.3 驱动函数 309
11.7 小结 320
第12章 模块调试 323
12.1 调试日志 324
12.1.1 错误日志 324
12.1.2 调试 326
12.2 在调试器中运行Apache 327
12.2.1 服务器的启动和调试 329
12.2.2 调试和多道处理模块MPM 331
12.2.3 追踪冲突 331
12.2.4 调试核心Dump 332
12.3 特殊用途的Hook和模块 333
12.3.1 标准模块 333
12.3.2 重大异常模块 336
12.3.3 处理反常运行的模块 337
12.4 过滤器调试 338
12.4.1 mod_diagnostics 338
12.5 小结 341
附录A Apache许可证 343
附录B 贡献者许可证协议 349
附录C 超文本传送协议:HTTP/1.1 357
本备忘录状态 357
摘要 358
1 概述 358
1.1 目的 358
1.2 要求 359
1.3 术语 359
1.4 操作概述 364
2 符号惯例和一般语法 366
2.1 扩充BNF 366
2.2 基本规则 368
3 协议参数 370
3.1 HTTP版本 370
3.2 统一资源标识符 371
3.3 日期/时间格式 373
3.4 字符集 374
3.5 内容编码 375
3.6 传送编码 376
3.7 媒体类型 379
3.8 产品记号 381
3.9 质量值 381
3.10 语言标签 382
3.11 实体标签 382
3.12 范围单位 383
4 HTTP消息 383
4.1 消息类型 383
4.2 消息报头 384
4.3 消息主体 385
4.4 消息长度 386
4.5 通用报头字段 387
5 请求 388
5.1 请求行(Request-Line) 388
5.2 请求所标识的资源 390
5.3 请求报头字段 391
6 应答 392
6.1 状态行 392
6.2 应答报头字段 394
7 实体 394
7.1 实体报头字段 395
7.2 实体主体 395
8 连接 396
8.1 持久连接 396
8.2 消息传送需求 400
9 方法定义 403
9.1 安全和幂等的方法 403
9.2 OPTIONS 404
9.3 GET 405
9.4 HEAD 406
9.5 POST 407
9.6 PUT 408
9.7 DELETE 409
9.8 TRACE 409
9.9 CONNECT 410
10 状态码定义 410
10.1 用于报告的1xx 410
10.2 成功的2xx 411
10.3 重定向的3xx 414
10.4 客户端错误的4xx 418
10.5 服务器错误的5xx 423
11 访问认证 424
12 内容协商 424
12.1 服务器驱动协商 425
12.2 代理驱动协商 426
12.3 透明协商 427
13 HTTP中的缓存 427
13.1 HTTP中缓存的基本设计理念 428
13.2 过期模型 433
13.3 验证模型 438
13.4 应答缓存能力 444
13.5 从缓存构造应答 445
13.6 缓存协商的应答 449
13.7 共享和非共享缓存 450
13.8 错误和不完全应答缓存行为 450
13.9 GET和HEAD的副作用 451
13.10 刷新或删除后的无效性 451
13.11 强制写通过 452
13.12 缓存替换 452
13.13 历史列表 452
14 报头字段定义 453
14.1 Accept(接受) 453
14.2 Accept-Charset(接受字符集) 455
14.3 Accept-Encoding(接受编码) 456
14.4 Accept-Language(接受语言) 457
14.5 Accept-Range(接受范围) 459
14.6 Age(年龄) 459
14.7 Allow(允许) 459
14.8 Authorization(授权) 460
14.9 Cache-control(缓存控制) 461
14.10 Connection(连接) 470
14.11 Content-Encoding(内容编码) 471
14.12 Content-Language(内容语言) 472
14.13 Content-Length(内容长度) 473
14.14 Content-Location(内容位置) 473
14.15 Content-MD5(内容的MD5值) 474
14.16 Content-Range(内容范围) 476
14.17 Content-Type(内容类型) 478
14.18 Date(日期) 478
14.19 ETag(实体标签) 480
14.20 Expect(期望) 480
14.21 Expire(过期) 481
14.22 From(来自于) 482
14.23 Host(主机) 482
14.24 If-Match(如果匹配) 483
14.25 If-Modified-Since(如果自从……被改变) 484
14.26 If-None-Match(如果没有一个匹配) 486
14.27 If-Range(如果有范围) 487
14.28 If-Unmodified-Since(如果自从……未修改) 488
14.29 Last-Modified(最后一次修改) 488
14.30 Location(位置) 489
14.31 Max-Forwards(最大化向前传送) 489
14.32 Pragma(特殊指令) 490
14.33 Proxy-Authenticate(代理认证) 491
14.34 Proxy-Authorization(代理授权) 491
14.35 Range(范围) 492
14.36 Referer(参考者) 494
14.37 Retry-After(稍后重试) 494
14.38 Server(服务器) 495
14.39 TE(传送编码) 495
14.40 Trailer(跟踪器) 497
14.41 Transfer-Encoding(传送编码) 497
14.42 Upgrade(升级) 498
14.43 User-Agent(用户代理) 499
14.44 Vary(验证) 499
14.45 Via(路由) 500
14.46 Warning(警告) 501
14.47 WWW-Authenticate(WWW-认证) 504
15 安全考虑 504
15.1 个人信息 505
15.2 基于文件和路径名称的攻击 507
15.3 DNS欺骗 508
15.4 Location报头和欺骗 508
15.5 Content-Disposition问题 509
15.6 认证证书和空闲的客户端 509
15.7 代理服务器和缓存 509
16 致谢 510
17 参考文献 512
18 作者地址 516
19 附录 518
19.1 互联网媒体类型message/http和application/http 518
19.2 互联网媒体类型multipart/byteranges 519
19.3 可容忍的应用程序 520
19.4 HTTP实体和RFC 2045实体之间的区别 521
19.5 附加特性 524
19.6 和以前版本的兼容 525
20 索引 529
21 全部版权声明 530
致谢 530
索引 531
自从Web诞生以来,整个世界人与人之间的距离就被迅速地拉近。作为Web应用的核心和基础设施,Web服务器一直都被笼罩着一层神秘的面纱。作为Web服务器中的旗舰产品,Apache不仅功能强大,而且是开源社区贡献的开源产品,能够让我们从每一个角度透视Apache的内部构造和功能实现。
然而,面对Apache日益庞大的结构和纷繁的代码,无论是开发者还是研究者都感觉无法入手。如果有经验丰富的Apache导游能够带领我们提纲挈领地游览一下Apache的美丽风光,让我们站在巨人的肩膀上居高临下地审视Apache的结构,并对相关的细节进行讲解,那将对我们掌握Apache的架构和实现具有非常大的帮助。本书作者Nick Kew就是这样一名经验丰富而且善于表达的导游,他精通Apache的设计和实现,是Apache的很多非常著名的模块的开发者,同时也是Apache参考文档的撰写者。
本书详细介绍了Apache的架构和模块,并对Apache的发展历史、平台和架构、MPM、APR、编程技巧和规范、模块的配置、模块的扩展、模块的调试等方面进行了介绍,使读者能够详细了解Apache模块开发的所有细节,并根据HTTP消息处理的流程介绍了请求处理过程和相关函数、内容生成器和过滤器的工作机理和模块,并且针对目前被广泛关注的Web安全问题介绍了访问控制模块,针对目前数据库的广泛应用介绍了DBD模块。本书对Apache模块的介绍不仅深入浅出,而且内容翔实,涵盖了模块开发的全部相关细节,并有大量的示例代码,对于理解和进一步开发Apache模块具有非常大的帮助。
我们很荣幸能够有机会承担本书的翻译工作,将这本优秀的作品带给中国的读者。在翻译过程中,我们经常为一句话、一个术语、一个注释进行反复的讨论和斟酌,力求能够正确而严格地体现原文的含义,同时注意让语言逻辑符合国人的语言习惯。我们真挚地希望读者能够从本书中有所收获。Apache2的相关资料非常少,希望本书对国内进行Apache开发的相关人员和对Apache进行研究的相关人员有所帮助。同时,本书对HTTP 1.1协议进行了系统地翻译,对于Web开发者和研究者来说,是一个不可多得的参考资料。
本书由张立强和徐建明进行翻译。其中张立强负责翻译前言、序、内容介绍、第1章、第2章、第3章、第4章、第7章、第8章、附录A、附录B和附录C,并邀请原作者Nick Kew为本书的中文版本写序。徐建明负责翻译第5章、第6章、第9章、第10章、第11章和第12章。感谢本书原作者Nick Kew为中文版撰写序。感谢博文视点的周筠、杨福川和晓菲编辑对本书的配合和支持,并对该书进行了全面、细致的审校,提出了大量的宝贵意见,在此表示衷心的感谢。
在此特别感谢IBM武汉分公司软件部各位同事、武汉竟升弘业信息系统工程有限公司总经理孙涛、湖南省电力公司信息中心眭建新、华中电网科技有限公司高澜、南方航空武汉分公司李静和我们的朋友耿安立、李志刚、张琪、任鑫平。我们的成长与进步离不开你们的支持与帮助,在此深表感谢。
在翻译过程中,译者尽量采用已被业界广泛接受的技术术语。由于译者的经验和水平有限,译文难免有疏漏和不妥之处,恳请读者批评指正。
张立强
徐建明
本书的介绍
Apache Web服务器(通常简称为“Apache”)在很多测试中都是Web服务器中的领军者。近10年来Apache都毫不费力的成为市场领头羊,世界上的站点中接近70%运行着Apache。Apache由Apache软件基金会(Apache Software Foundation)控制下的一个活跃的开发社区作为后援,同时它也广泛地受到各种组织和人们的支持,大到像IBM这样的巨头公司,小到个人顾问。
Apache的主要特点在于它的开放性和多样性。Apache源代码是完全开放的:不仅仅是当前版本,早期版本和处于开发阶段中的测试版本可以从apache.org网站上下载。除了项目管理相关的一些内容之外,Apache的开发过程也是开放的。Apache的多样性可以从它的用户社区和开发者社区体现出来:不管是每秒钟接收成千上万点击的高负载站点,还是复杂的、高度动态的网络应用,以及接入单独应用服务器的桥接器,甚至是简单的Web服务器,Apache都可以胜任。因此Apache融合了多种应用环境下的开发人员,这使得其可以成功的适用于广泛的应用环境。
但是这不意味着Apache采用了大而全的方法。Apache高度模块化的架构建立在一个很小的内核上,每一个用户都可以裁减这个内核来适应他自己的特殊需求。Apache可以作为一个单独的服务器,也可是作为其它系统的一个组件。最重要的是:它是一个灵活的、可扩展的应用平台。
本书面向的读者
本书是为使用Apache Web服务器的软件开发人员所写的。本书是自1999年三月之后第一本关于介绍Apache模块开发的书籍,也是目前为止第一本关于Apache 2开发的书籍。
本书的主要意图是成为一本深入介绍Apache模块开发的教科书。本书以C语言描述和示例,因此需要读者具有C语言的开发经验。但是Apache的架构和API由多种主流脚本环境共享:如mod_perl,mod_python以及C语言。除了第三章(介绍Apache可移植运行时库)之外,本书的绝大部分都适合使用比标准CGI更高级脚本语言的开发人员。
本书主要关注目前Apache的发行版本——Apache 2.2。Apache 2.2.0在2005年12月份发布,根据Apache的开发周期,它将会保留一段时间(之前的稳定版本2.0在2002年4月发布)。本书也非常适合依然使用Apache 2.0版本的开发人员(Apache架构和API将在所有的Apache2.x版本中保持不变),并期望在不久的将来依然有用。
本书的结构与涵盖的范围
本书包括12个章节和3个附录。
本书的第一章是非技术的概述,介绍了Apache的社会背景、文化背景以及法律背景。接下来的三章(第二章、第三章、第四章)从技术上对Apache进行展开的概述和介绍。第二章对Apache的架构和API进行技术上的概述。第三章介绍了Apache可移植运行时库(Apache Portable Runtime, APR)。Apache可移植运行时库是Apache非常重要的组件,它是一个半自治的库,用来把开发人员从C编程中的很多常规负担中解放出来。第四章讨论了适合Apache开发的一些通用编程技巧,以保证你开发的Apache模块在各种平台和环境下正常工作,保持安全,同时不给系统管理员带来麻烦。
本书的中间部分从总体介绍转向专题介绍。第五章到第八章详细介绍了网页服务器核心功能的各种方面——也就是处理HTTP请求。大量现实存在的模块在这些章节内被开发出来。第五章以一个“Hello World”示例开始,让你可以了解如何把一个CGI的函数或者一个PHP的脚本改成一个Apache的模块。第六章介绍了HTTP请求处理流程,以及如何处理HTTP元数据。第七章深入介绍了如何标识用户并实施访问控制。第八章介绍了过滤链,以及如何转换内进(incoming)和外出(outgoing)数据;本章还包含一个深度的理论解释以及一些示例。第九章介绍了如何处理配置数据,并结束了对内核问题的探讨。
第十章和第十一章讨论了更高级的话题,这两章对于一些应用程序开发人员来说仍然是比较基础的。第十章着眼于API的实现机制,介绍了一个模块如何拓展API,或者为其它模块引入一个全新的API。第十一章介绍了DBD框架来支持SQL数据库应用程序。第十二章主要介绍了如何发现和解决故障以及一些调试技巧。
附录包括从网上复制过来的Apache法律文档。这些文档和本书密切相关,不过并不是作者写的。附录A是Apache许可。附录B包括一些贡献者许可协议(Contributor License Agreements,CLA),涵盖了知识产权的一些因素。附录C是权威的超文本传输协议(Hypertext Transfer Protocol, HTTP/1.1)标准,也就是RFC2616文档的全文,作为网络应用程序开发人员的参考文档。
本书没有涵盖的内容
本书主要关注应用程序开发,因此本书并没有大量介绍有关Apache的系统编程技术。特别指出的是,如果你的目的是想将Apache移植到一个目前还不支持的平台上,本书也仅仅指出了你需要更改的代码区域。
除此之外,我还要再说明一下:本书限定为只考虑Apache作为Web协议HTTP或者HTTPS的解析服务器。尽管Apache还可以支持其它协议,如支持FTP,SMTP协议的实现已经存在了,本书并没有对这些进行介绍。不过如果你想研究如何实现或者如何解析其它协议,那么本书对HTTP协议如何处理的介绍和概述会对你有所帮助。
本书相关资源
为本书特意编写的一些作为示例的模块以及一些类似的介绍性材料:
第五章:mod_helloworld
第六章:mod_choice(源自一个非开放源代码的模块)
第七章:mod_authnz_day
第八章:mod_txt(最初写与www.apachetutor.org)
这些模块可以从www.apachetutor.org下载。
所有的这些模块都是从Apache的源代码中摘取出来的。除了一些参考的URL之外,所有的模块都是从Apache的标准发布版(httpd.apache.org)或者作者的公司站点(apache.webthing.com)中获取的。要注意的是本书中的任何源代码的使用不需要许可,你可以拷贝这些代码或作为私人用途。不过你要参考这些模块的最初代码的许可条例。
关于本书的勘误、请访问http://blog.csdn.net/bvbook
无封面