Ubuntu下C语言CGI如何配置运行?

99ANYc3cd6
预计阅读时长 26 分钟
位置: 首页 C语言 正文

目录

  1. 什么是 CGI?
  2. 环境准备
    • 安装 Web 服务器
    • 配置 Web 服务器以支持 CGI
  3. 编写你的第一个 C CGI 程序
  4. 编译和放置程序
  5. 设置执行权限
  6. 测试你的 CGI 程序
  7. 进阶示例:处理表单数据
  8. 排错与调试

什么是 CGI?

CGI (Common Gateway Interface) 是一种标准,它允许 Web 服务器(如 Apache 或 Nginx)执行一个外部程序,并将程序的输出结果返回给客户端的浏览器。

ubuntu c语言 cgi
(图片来源网络,侵删)

工作流程如下:

  1. 浏览器请求: 用户在浏览器中访问一个 URL,http://your-server.com/cgi-bin/hello.cgi
  2. 服务器识别: Web 服务器看到这个 URL 指向了一个可执行程序(在 cgi-bin 目录下)。
  3. 服务器执行: 服务器启动这个 C 程序作为子进程来运行。
  4. 环境变量和标准输入: 服务器设置一系列环境变量(如 REQUEST_METHOD, QUERY_STRING 等),并将客户端的数据(如表单数据)通过标准输入 传递给 C 程序。
  5. 程序处理: C 程序读取环境变量和标准输入,进行计算或处理。
  6. 标准输出: C 程序将 HTML 内容(或其他类型的内容)写入到标准输出。
  7. 服务器响应: Web 服务器捕获 C 程序的标准输出,并将其作为 HTTP 响应发送回浏览器。
  8. 浏览器显示: 浏览器接收到 HTML 内容并渲染显示给用户。

关键点:

  • 环境变量: CGI 程序通过读取环境变量来获取请求信息。
  • 标准输入: 用于接收 POST 请求的表单数据。
  • 标准输出: 用于返回 HTTP 响应体(通常是 HTML)。

环境准备

我们将使用 Ubuntu 最常用的 Web 服务器 Apache

a. 安装 Apache

打开终端,执行以下命令:

ubuntu c语言 cgi
(图片来源网络,侵删)
sudo apt update
sudo apt install apache2

安装完成后,Apache 服务会自动启动,你可以通过访问 http://localhost/http://127.0.0.1/ 来确认安装是否成功(你会看到 Apache 的默认欢迎页面)。

b. 配置 Apache 以支持 CGI

默认情况下,Apache 可能没有启用 CGI 功能,我们需要修改它的配置文件。

  1. 启用 cgi 模块: Apache 使用模块来扩展功能,我们需要启用 cgi 模块。

    sudo a2enmod cgi

    这会创建一个指向 /etc/apache2/mods-enabled/cgi.load 的符号链接。

    ubuntu c语言 cgi
    (图片来源网络,侵删)
  2. 配置 CGI 目录: 最安全的做法是将 CGI 程序存放在一个专门的目录中,通常是 /usr/lib/cgi-bin,Apache 默认配置中已经包含了对此目录的支持。

    让我们检查一下 /etc/apache2/sites-available/000-default.conf 文件,确保其中有类似下面的配置段(通常默认就有):

    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        AddHandler cgi-script .cgi
        Require all granted
    </Directory>
    • Options +ExecCGI: 这是关键,它允许在这个目录中执行 CGI 脚本。
    • AddHandler cgi-script .cgi: 告诉 Apache 所有以 .cgi 结尾的文件都应作为 CGI 程序处理。
  3. 重启 Apache 服务: 让配置生效。

    sudo systemctl restart apache2

编写你的第一个 C CGI 程序

我们来创建一个简单的 CGI 程序,它的功能是在网页上打印 "Hello, World from C CGI!"。

创建一个文件,hello.c

#include <stdio.h>
#include <stdlib.h>
int main() {
    // 1. 打印 HTTP 响应头
    // 这是至关重要的!必须以两个换行符结束。
    // Content-Type 告诉浏览器我们返回的是什么类型的数据。
    // 对于 HTML,它的值是 text/html。
    printf("Content-Type: text/html\n\n");
    // 2. 打印 HTML 内容到标准输出
    // 这部分内容将被浏览器解析并显示。
    printf("<html>\n");
    printf("<head>\n");
    printf("  <title>Hello from C CGI</title>\n");
    printf("</head>\n");
    printf("<body>\n");
    printf("  <h1>Hello, World from C CGI!</h1>\n");
    printf("  <p>This page is generated by a C program.</p>\n");
    printf("</body>\n");
    printf("</html>\n");
    // 3. 正常退出程序
    return 0;
}

代码解释:

  • printf("Content-Type: text/html\n\n"); 这是 最重要 的一行,它告诉浏览器接下来接收到的数据是 HTML 格式。必须有两个换行符 \n\n,第一个结束响应头,第二个开始响应体。
  • 后续的 printf 语句就是标准的 HTML 代码,它们被发送到标准输出,由 Apache 捕获并返回给浏览器。

编译和放置程序

  1. 编译 C 程序: 使用 gcc 编译器将 hello.c 编译成一个可执行文件,我们需要链接一些 Apache 可能需要的库。

    gcc -o hello.cgi hello.c
    • -o hello.cgi: 指定输出的可执行文件名为 hello.cgi.cgi 后缀是一个约定,方便识别。
  2. 放置到 CGI 目录: 将编译好的 hello.cgi 文件复制到 Apache 配置的 CGI 目录中。

    sudo cp hello.cgi /usr/lib/cgi-bin/

    使用 sudo 是因为 /usr/lib/cgi-bin/ 目录通常需要 root 权限才能写入。


设置执行权限

Web 服务器进程(通常是 www-data 用户)需要能够读取和执行你的 CGI 程序,必须给它设置正确的权限。

sudo chmod 755 /usr/lib/cgi-bin/hello.cgi
  • 7 (所有者): 读、写、执行
  • 5 (组): 读、执行
  • 5 (其他): 读、执行 这允许 www-data 用户执行这个脚本。

测试你的 CGI 程序

打开你的 Web 浏览器,访问以下 URL:

http://localhost/cgi-bin/hello.cgi

你应该能看到一个标题为 "Hello from C CGI" 的页面,内容是 "Hello, World from C CGI!"。

恭喜!你已经成功运行了你的第一个 C 语言 CGI 程序!


进阶示例:处理表单数据

CGI 更强大的功能在于处理用户通过表单提交的数据,我们来看一个简单的例子。

a. 创建一个 HTML 表单

创建一个文件 form.html (可以放在 Apache 的默认网站根目录 /var/www/html/ 下):

<!DOCTYPE html>
<html>
<head>CGI Form Example</title>
</head>
<body>
    <h2>Enter your name</h2>
    <form action="/cgi-bin/form_handler.cgi" method="get">
        Name: <input type="text" name="username">
        <input type="submit" value="Submit">
    </form>
</body>
</html>
  • action="/cgi-bin/form_handler.cgi": 指定表单数据将被提交到 form_handler.cgi 这个 CGI 程序。
  • method="get": 使用 GET 方法提交数据,数据会附加在 URL 后面(...?username=John)。

b. 编写处理表单的 C CGI 程序

创建 form_handler.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 一个简单的辅助函数,用于从 QUERY_STRING 中获取变量值
char* get_query_string_value(const char* query, const char* var) {
    char* value = NULL;
    char* pair = strtok((char*)query, "&");
    while (pair != NULL) {
        char* eq = strchr(pair, '=');
        if (eq != NULL) {
            *eq = '\0'; // 分割键和值
            if (strcmp(pair, var) == 0) {
                value = eq + 1;
                break;
            }
        }
        pair = strtok(NULL, "&");
    }
    return value;
}
int main() {
    // 1. 打印 HTTP 响应头
    printf("Content-Type: text/html\n\n");
    // 2. 获取环境变量 QUERY_STRING
    // 对于 GET 请求,表单数据会在这里
    char *query_string = getenv("QUERY_STRING");
    char *username = NULL;
    if (query_string != NULL) {
        username = get_query_string_value(query_string, "username");
    }
    // 3. 根据是否有数据生成不同的 HTML
    printf("<html>\n");
    printf("<head><title>Form Response</title></head>\n");
    printf("<body>\n");
    if (username != NULL && strlen(username) > 0) {
        // URL 解码 (简化版,实际应用中应使用更健壮的库)
        char *decoded_username = username;
        for (int i = 0; decoded_username[i]; i++) {
            if (decoded_username[i] == '+') {
                decoded_username[i] = ' ';
            }
        }
        printf("<h1>Hello, %s!</h1>\n", decoded_username);
    } else {
        printf("<h1>Error: No name provided.</h1>\n");
        printf("<p><a href=\"/form.html\">Go back</a></p>\n");
    }
    printf("</body>\n");
    printf("</html>\n");
    return 0;
}

c. 编译、放置和设置权限

# 编译
gcc -o form_handler.cgi form_handler.c
# 复制
sudo cp form_handler.cgi /usr/lib/cgi-bin/
# 设置权限
sudo chmod 755 /usr/lib/cgi-bin/form_handler.cgi

d. 测试

  1. 在浏览器中访问 http://localhost/form.html
  2. 在输入框中输入你的名字("Alice"),然后点击 "Submit"。
  3. 浏览器会跳转到 http://localhost/cgi-bin/form_handler.cgi?username=Alice,并显示 "Hello, Alice!"。

排错与调试

如果程序没有按预期工作,这里是常见的排查步骤:

  1. 检查权限: 确保文件在 /usr/lib/cgi-bin/ 目录下,并且有 755 权限 (sudo chmod 755 ...)。
  2. 检查编译: 确保程序没有编译错误,运行 ./hello.cgi (在本地测试) 看看是否能正常输出 HTML。
  3. 查看 Apache 错误日志: 这是最有用的工具!CGI 程序的 stderr(标准错误)会被重定向到 Apache 的错误日志中。
    • 查看日志命令:
      tail -f /var/log/apache2/error.log
    • 在浏览器中访问你的 CGI 脚本,然后立即查看这个日志文件,你很可能会看到 C 程序中的 printf 错误信息(比如忘记打印 Content-Type 头),或者程序崩溃的原因(比如段错误)。
  4. 检查 Content-Type 头: 确保第一行响应是 printf("Content-Type: text/html\n\n");,并且有两个换行符。
  5. 简单测试: 先确保最简单的 "Hello, World" CGI 能工作,再逐步添加复杂功能。

希望这份详细的指南能帮助你在 Ubuntu 上成功使用 C 语言进行 CGI 开发!

-- 展开阅读全文 --
头像
织梦后台如何限制栏目访问权限?
« 上一篇 01-22
C语言中else与break能直接连用吗?
下一篇 » 01-22

相关文章

取消
微信二维码
支付宝二维码

目录[+]