第 1 章 - NetX HTTP 简介

超文本传输协议 (Hypertext Transfer Protocol, HTTP) 是设计用于在 Web 上传输内容的协议。 HTTP 是一种简单协议,它利用可靠的传输控制协议 (Transmission Control Protocol, TCP) 服务来执行其内容传输功能。 因此,HTTP 是高度可靠的内容传输协议。 HTTP 是最常用的应用程序协议之一。 Web 上的所有操作都利用 HTTP 协议。

HTTP 要求

若要正常运行,NetX HTTP 包要求安装 NetX(版本 5.2 或更高版本)。 此外,必须已创建一个 IP 实例,且必须在该 IP 实例上启用 TCP。 第 2 章的“小型示例系统”一节中的演示文件将演示如何执行此操作。

NetX HTTP 包的 HTTP 客户端部分没有其他要求。

NetX HTTP 包的 HTTP 服务器部分有几个附加要求。 首先,它需要对众所周知的 TCP 端口 80 的完全访问权限,该端口用于处理所有客户端 HTTP 请求。 HTTP 服务器还设计为与 FileX 嵌入式文件系统一起使用。 如果 FileX 不可用,用户可以将使用的 FileX 部分移植到他们自己的环境中。 本指南后面各节将对此进行讨论。

HTTP 限制

NetX HTTP 协议实现 HTTP 1.0 标准。 但是,存在以下限制:

  1. 不支持持续连接

  2. 不支持请求流水线操作

  3. HTTP 服务器支持基本身份验证和 MD5 摘要式身份验证,但不支持 MD5-sess 身份验证。 目前,HTTP 客户端仅支持基本身份验证。

  4. 不支持内容压缩。

  5. 不支持 TRACE、OPTIONS 和 CONNECT 请求。

  6. 与 HTTP 服务器或客户端关联的数据包池必须足够大以容纳完整的 HTTP 标头。

  7. HTTP 客户端服务仅用于内容传输,此包中未提供任何显示实用工具。

HTTP URL(资源名称)

HTTP 协议设计用于在 Web 上传输内容。 请求的内容由统一资源定位器 (URL) 指定。 这是每个 HTTP 请求的主要组件。 URL 始终以“/”字符开头,通常与 HTTP 服务器上的文件相对应。 常见 HTTP 文件扩展名如下所示:

  • .htm(或 .html):超文本标记语言 (Hypertext Markup Language, HTML)
  • .txt:ASCII 纯文本
  • .gif:二进制 GIF 图像
  • .xbm:二进制 Xbitmap 图像

HTTP 客户端请求

HTTP 采用简单机制来请求 Web 内容。 基本上来说,成功在众所周知的 TCP 端口 80 上建立连接后,客户端会发出一组标准 HTTP 命令。 下面显示了一些基本 HTTP 命令:

  • GET resource HTTP/1.0:获取指定的资源
  • POST resource HTTP/1.0:获取指定的资源并将附加的输入传递到 HTTP 服务器
  • HEAD resource HTTP/1.0:与 GET 类似,但 HTTP 服务器不会返回任何内容
  • PUT resource HTTP/1.0:在 HTTP 服务器上放置资源
  • DELETE resource HTTP/1.0:删除服务器上的资源

这些 ASCII 命令由 Web 浏览器和 NetX HTTP 客户端服务在内部生成,以通过 HTTP 服务器执行 HTTP 操作。

注意

HTTP 客户端应用程序的连接端口默认设置为端口 80。 但是,应用程序可以在运行时使用 nx_http_client_set_connect_port 服务来更改与 HTTP 服务器的连接端口。 有关此服务的更多详细信息,请参阅第 4 章。 此服务适用于偶尔将备用端口用于客户端连接的 Web 服务器。

HTTP 服务器响应

HTTP 服务器还使用众所周知的 TCP 端口 80 来发送客户端命令响应。 HTTP 服务器在处理客户端命令后,会返回 ASCII 响应字符串,其中包含 3 位数状态代码。 HTTP 客户端软件使用数值响应来确定操作是成功还是失败。 下面列出了对客户端命令的各种 HTTP 服务器响应:

  • 200:请求成功
  • 400:请求的格式不正确
  • 401:未经授权的请求,客户端需要发送身份验证
  • 404:找不到在请求中指定的资源
  • 500:内部 HTTP 服务器错误
  • 501:HTTP 服务器未实现该请求
  • 502:服务不可用

例如,当放置文件“test.htm”的客户端请求成功时,响应消息为“HTTP/1.0 200 OK”。

HTTP 通信

如前所述,HTTP 服务器使用众所周知的 TCP 端口 80 来处理客户端请求。 HTTP 客户端可以使用任何可用的 TCP 端口。 HTTP 事件的一般顺序如下:

HTTP GET 请求:

  1. 客户端向服务器端口 80 发起 TCP 连接。

  2. 客户端发送“GET resource HTTP/1.0”请求(以及其他标头信息)。

  3. 服务器生成“HTTP/1.0 200 OK”消息和附加信息,后面紧跟资源内容(如果有)。

  4. 服务器断开连接。

  5. 客户端断开连接。

HTTP PUT 请求:

  1. 客户端向服务器端口 80 发起 TCP 连接。

  2. 客户端发送“PUT resource HTTP/1.0”请求,以及其他标头信息,后跟资源内容。

  3. 服务器生成“HTTP/1.0 200 OK”消息和附加信息,后面紧跟资源内容。

  4. 服务器断开连接。

  5. 客户端断开连接。

注意

如前所述,对于使用备用端口连接到客户端的 Web 服务器,HTTP 客户端可以使用 nx_http_client_set_connect_port 将默认连接端口从 80 更改为其他端口。

HTTP 身份验证

HTTP 身份验证是可选的,并非所有 Web 请求都需要。 身份验证有两种形式,即基本身份验证和摘要式身份验证。 基本身份验证相当于许多协议中的名称和密码身份验证。 在 HTTP 基本身份验证中,名称和密码采用 base64 格式进行连接和编码。 基本身份验证的主要缺点是,名称和密码会在请求中公开传输。 这样,名称和密码容易被盗用。 摘要式身份验证从不在请求中传输名称和密码,因此解决了这个问题。 相反,此身份验证会使用某种算法根据名称、密码和其他信息派生一个 128 位的密钥或摘要。 NetX HTTP 服务器支持标准 MD5 摘要算法。

何时需要身份验证? 基本上来说,请求的资源是否需要身份验证由 HTTP 服务器决定。 如果需要身份验证,并且客户端请求不包含适当的身份验证,则服务器会向客户端发送“HTTP/1.0 401 Unauthorized”响应和所需的身份验证类型。 因此,客户端需要构建具有适当身份验证的新请求。

HTTP 身份验证回调

如前所述,HTTP 身份验证是可选的,并非所有 Web 传输都需要。 此外,身份验证通常与资源相关。 访问服务器上的某些资源需要身份验证,而访问其他资源则不需要。 使用 NetX HTTP 服务器包,应用程序可以指定(通过 nx_http_server_create 调用)身份验证回调例程,以便在开始处理每个 HTTP 客户端请求时进行调用。

回调例程可向 NetX HTTP 服务器提供与资源关联的用户名、密码和领域字符串,并返回所需的身份验证类型。 如果资源不需要身份验证,则身份验证回调应返回 NX_HTTP_DONT_AUTHENTICATE 的值。 如果指定的资源需要基本身份验证,则此例程应返回 NX_HTTP_BASIC_AUTHENTICATE。 最后,如果资源需要 MD5 摘要式身份验证,则回调例程应返回 NX_HTTP_DIGEST_AUTHENTICATE。 如果 HTTP 服务器提供的所有资源都不需要身份验证,则不需要回调,并且可以向 nx_http_server_create 调用提供空指针。

应用程序身份验证回调例程的格式很简单,定义如下:

UINT nx_http_server_authentication_check (NX_HTTP_SERVER *server_ptr,
                                         UINT request_type, CHAR *resource,
                                         CHAR **name, CHAR **password,
                                         CHAR **realm);

输入参数定义如下:

  • request_type - 指定 HTTP 客户端请求,有效请求定义为:
    • NX_HTTP_SERVER_GET_REQUEST
    • NX_HTTP_SERVER_POST_REQUEST
    • NX_HTTP_SERVER_HEAD_REQUEST
    • NX_HTTP_SERVER_PUT_REQUEST
    • NX_HTTP_SERVER_DELETE_REQUEST
  • resource - 请求的特定资源。
  • name - 指向所需用户名的指针。
  • password - 指向所需密码的指针。
  • realm - 指向此身份验证领域的指针。

身份验证例程的返回值指定是否需要身份验证。 如果身份验证回调例程返回 NX_HTTP_DONT_AUTHENTICATE,则不使用 name 指针、password 指针和 realm 指针。 否则,HTTP 服务器开发人员必须确保 nx_http_server.h 中定义的 NX_HTTP_MAX_USERNAME 和 NX_HTTP_MAX_PASSWORD 足够大,以便容纳身份验证回调中指定的用户名和密码。 这两个选项都默认设置为 20 个字符。

HTTP 用户名/密码无效回调

如果 HTTP 服务器收到的客户端请求中的用户名和密码组合无效,则会调用 NetX HTTP 服务器中可选的 HTTP 用户名/密码无效回调。 如果 HTTP 服务器应用程序向 HTTP 服务器中注册了回调,则会在 nx_http_server_get_process、nx_http_server_put_process 或 nx_http_server_delete_process 中的基本身份验证或摘要式身份验证失败时调用该回调。

为了向 HTTP 服务器注册回调,NetX HTTP 服务器中定义了以下服务。

UINT nx_http_server_invalid_userpassword_notify_set (NX_HTTP_SERVER *http_server_ptr,
                                                    UINT *invalid_username_password_callback)
                                                    (CHAR *resource,
                                                    ULONG *client_nx_address,
                                                    UINT request_type));

请求类型定义如下:

  • NX_HTTP_SERVER_GET_REQUEST
  • NX_HTTP_SERVER_POST_REQUEST
  • NX_HTTP_SERVER_HEAD_REQUEST
  • NX_HTTP_SERVER_PUT_REQUEST
  • NX_HTTP_SERVER_DELETE_REQUEST

HTTP 插入 GMT 日期标头回调

NetX HTTP 服务器提供用于在其响应消息中插入日期标头的可选回调。 当 HTTP 服务器响应 put 或 get 请求时,将调用此回调

为了向 HTTP 服务器注册 GMT 日期回调,NetX HTTP 服务器中定义了以下服务。

UINT _nx_http_server_gmt_callback_set(NX_HTTP_SERVER *server_ptr,
                                     VOID (*gmt_get)(NX_HTTP_SERVER_DATE *date);

NX_HTTP_SERVER_DATE 数据类型定义如下:

typedef struct NX_HTTP_SERVER_DATE_STRUCT
{
    USHORT     nx_http_server_year;         /* Year        */
    UCHAR      nx_http_server_month;        /* Month       */
    UCHAR      nx_http_server_day;          /* Day         */
    UCHAR      nx_http_server_hour;         /* Hour        */
    UCHAR      nx_http_server_minute;       /* Minute      */
    UCHAR      nx_http_server_second;       /* Second      */
    UCHAR      nx_http_server_weekday;      /* Weekday     */
} NX_HTTP_SERVER_DATE;

HTTP 缓存信息获取回调

HTTP 服务器提供用于从 HTTP 应用程序请求特定资源的最长期限和日期的回调。 此信息用于确定 HTTP 服务器是否在对客户端 Get 请求的响应中发送整页。 如果在客户端请求中找不到“If-Modified-Since”,或者它与获取缓存回调所返回的“Last-Modified”日期不匹配,则会发送整页。

为了向 HTTP 服务器注册回调,定义了以下服务:

UINT _nx_http_server_cache_info_callback_set(NX_HTTP_SERVER *server_ptr,
                                            UINT (*cache_info_get)
                                            (CHAR *, UINT *, NX_HTTP_SERVER_DATE *));

HTTP 多部分支持

多用途 Internet 邮件扩展 (MIME) 最初适用于 SMTP 协议,但现已适用于 HTTP。 MIME 允许同一消息中包含混合的消息类型(例如,图像/jpg 和文本/纯文本)。 NetX HTTP 服务器添加了一些服务,用于确定来自客户端的包含 MIME 的 HTTP 消息中的内容类型。 若要启用 HTTP 多部分支持并使用这些服务,必须定义配置选项 NX_HTTP_MULTIPART_ENABLE。

UINT nx_http_server_get_entity_header(NX_HTTP_SERVER *server_ptr,
                                     NX_PACKET **packet_pptr,
                                     UCHAR *entity_header_buffer,
                                     ULONG buffer_size);

UINT nx_http_server_get_entity_content(NX_HTTP_SERVER *server_ptr,
                                      NX_PACKET **packet_pptr,
                                      ULONG *available_offset,
                                      ULONG *available_length);

有关使用这些服务的更多详细信息,请参阅第 3 章“HTTP 服务说明”中的说明。

HTTP 多线程支持

用户可以同时从多个线程调用 NetX HTTP 客户端服务。 但在同一个线程中,对特定 HTTP 客户端实例的读取或写入请求应按顺序发出。

HTTP RFC

NetX HTTP 符合 RFC1945“超文本传输协议 1.0”、RFC 2581“TCP 拥塞控制”、RFC 1122“Internet 主机要求”和相关的 RFC。