进入课程网页的时候意外发现这个 Project 的代码已经被填完了。所以没什么好做的。

# Overview

多线程网络服务器大致功能:简单的搜索和文件浏览

  • Part A: 实现服务器读取文件,统计文件中的单词个数
  • Part B: 实现网络连接和 HTTP 请求响应
  • Part C: 将 A 和 B 两部分结合起来

# Part A

# FileReader.cc

  • 简单的文件阅读器
  • 在构建时读入文件名, read_file 将整个文件读入一个 string
  • 可以使用 POSIX , C 接口或者 C++ 文件流实现

# WordIndex.h & WordIndex.cc

实现一个数据结构,用于存储各个文件中的单词及其出现次数

# CrawlFileTree.cc

实现 HandleFile 函数,其获取一个文件名和一个 WordIndex ,这个函数读取对应文件,并且将每个单词及其对应的个数存储在 WordIndex

# Part B

# ServerSocket.cc

实现一个类,这个类包含:

  • 创建一个服务器端的监听 socket
  • 从客户端接受新的连接请求
  • ServerSocket.h 中提供了头文件,需要在 ServerSocket.cc 中实现

# HttpConnection.cc

  • HttpConnection 处理 HTTP 连接请求,将该请求转化为一个对象,并且负责将响应写回去
  • 该函数中主要实现 HTTP 请求的读取和解析 (string 操作)

# HttpUtils.cc

主要负责一些其他功能,尤其是安全方面:

  • escape_html
    • 用于防止 cross-site scripting ,参考 Cross-site scripting
  • in_path_safe
    • 保证使用该服务器的人只能获取到对应目录下的文件,其他目录下对他不开放权限
    • 否则可能会有攻击者使用 directory traverse attack

# Part C

  • HttpServer_ThrFn 函数实现
    • 每个线程可以获取到一个连接
  • 两个 helper_function
    • 分别处理两种类型的请求
      • 对查看文件的请求 ( ProcessFileRequest )
      • 执行查询的请求 ( ProcessQueryRequest )
  • 使用 htttp 测试 Http Server 。输入命令 ./httpd 3000 ./test_tree/ ,在显示 accepting connections... 后,点击下方的 Open Server on port 3000

# 实现步骤

  1. FileReader::read_file
  2. WordIndex.cc & WordIndex.h
  3. CrawlFileTree.cc handle_file函数
  4. ServerSocket.cc
  5. get_request & parse_request from HttpConnection.cc
  6. write_response in HttpConnection.cc
  7. HttpUtils.cc 两个函数实现
  8. test_suite 通过
  9. valgrind 通过
  10. HttpServer.cc 实现并测试

# 实现提示

  • boost 库中的 split()/trim()/replace_all() 函数可以使用,使用 split() 时可以使用 is_any_of()/isalpha()/
  • 实现 ServerSocket.cc 时,留意 server_accept_rw_close
  • 有个小函数可以让 is_path_safe 的实现更简单 (留意 HttpUtils.cc 中的注释,自己上网学习它的用法)
  • FileReader 需要处理只含有 0 个字节的 binary_files ,这里可以使用传入 2 个参数的 string 构造函数

# 测试

make
./test_suite
valgrind ./test_suite