You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastCGI Web应用中点击提交按钮后调用指定C函数的问题

预订系统FastCGI表单提交与业务函数整合方案

问题背景

开发预订系统Web应用时,已完成以下功能:

  • 用libcurl实现send_mail()函数发送邮件
  • 用fcgi_stdio.h实现FastCGI服务,可处理GET请求显示表单、POST请求解析表单数据
  • book_for()和send_mail()单独调用功能正常

需求:点击表单Submit按钮后,自动调用book_for(to, name, num_guest, phone, date)和send_mail("addr", "confirmation.mail")完成预订记录与邮件通知。

原代码

#define __USE_XOPEN
#define _GNU_SOURCE

#include <stdio.h>
#include <fcgi_stdio.h>
#include <string.h>
#include <stdlib.h>

#include "mail.h"
#include "booking.h"

int
main()
{
    char to[20], name[20];
    //char *year, *mon, *day, *hour, *min;
    char date[20];
    char num_guest[4], phone[10];

    while (FCGI_Accept() >= 0) {
        printf("Content-type: text/html\n\n");
        printf("<h1>Welcome</h1>");

        char *method = getenv("REQUEST_METHOD");
        char form[2048] = {0};
        char output[2048] = {0};

        if(strcmp(method, "GET") == 0) {
            strcpy(form,
                "<form method='POST' action=''>"
                "<input id='name' name='name' type='text'></input>"
                "<br>"
                "<input id='to' name='to' type='email'></input>"
                "<br>"
                "<input id='date' type='datetime-local' name='date' />"
                "<br>"
                "<input type='tel' "
                    "id='phone' name='phone' size='20' "
                    "minlenght='9' maxlenght='14' required>"
                "<br>"
                "<input type='number' id='num_guest' name='num_guest'" 
                    "min='1' max='18'>"
                "<br>"
                "<input type='submit' value='Submit'>"
                "</form>"
            );
        } else if (strcmp(method, "POST") == 0) {
            int ilen = atoi(getenv("CONTENT_LENGTH"));
            //char *bufp = malloc(ilen);
            char *bufp = (char *) malloc(ilen * sizeof(char));
            fread(bufp, ilen, 1, stdin);
            printf("<h3>Thank you for your reservation!</h3>");
            strcpy(output, bufp);
            free(bufp);

                        /* declare data variables */
            sscanf(output, 
                "name=%[^&]&to=%[^&]&date=%[^&]&phone=%[^&]&num_guest=%[^&]", 
                name, to, date, phone, num_guest);

            replace(date, "%3A", ":"); // makes the date readable
            replace(to, "%40", "@");   // makes the mail readable
        }

        printf(
            "<div>"
            "%s"
            "</div>",
            form
        );
    }

    return 0;
}

解决方案

只需在POST请求的参数解析完成后,直接调用目标函数即可。同时建议增加基础错误检查,避免异常情况影响服务稳定性。

修改后的POST分支代码

else if (strcmp(method, "POST") == 0) {
    int ilen = atoi(getenv("CONTENT_LENGTH"));
    // 检查请求数据长度合法性
    if (ilen <= 0) {
        printf("<h3>Invalid request data!</h3>");
        strcpy(form, "<a href=''>Go back to booking form</a>");
        goto end_post;
    }

    char *bufp = (char *) malloc(ilen * sizeof(char));
    // 检查内存分配是否成功
    if (!bufp) {
        printf("<h3>Server error: failed to allocate memory!</h3>");
        strcpy(form, "<a href=''>Go back to booking form</a>");
        goto end_post;
    }

    fread(bufp, ilen, 1, stdin);
    printf("<h3>Thank you for your reservation!</h3>");
    strcpy(output, bufp);
    free(bufp);

    /* 解析表单数据 */
    int parse_result = sscanf(output, 
        "name=%[^&]&to=%[^&]&date=%[^&]&phone=%[^&]&num_guest=%[^&]", 
        name, to, date, phone, num_guest);
    
    // 确认所有参数解析成功
    if (parse_result != 5) {
        printf("<h3>Invalid form data! Please try again.</h3>");
        strcpy(form, "<a href=''>Go back to booking form</a>");
        goto end_post;
    }

    replace(date, "%3A", ":"); 
    replace(to, "%40", "@");   

    // 调用业务函数并处理返回结果
    if (book_for(to, name, num_guest, phone, date) != 0) {
        printf("<h3>Failed to save your reservation! Please try again later.</h3>");
    } else {
        if (send_mail("addr", "confirmation.mail") != 0) {
            printf("<h3>Reservation saved, but failed to send confirmation email.</h3>");
        } else {
            printf("<h3>Confirmation email sent to %s!</h3>", to);
        }
    }

    // 提供返回表单的入口
    strcpy(form, "<a href=''>Make another reservation</a>");

end_post:
    ;
}

修改说明

  1. 核心功能整合:在参数解析和URL解码完成后,直接调用book_for()和send_mail()完成业务逻辑
  2. 错误防护:
    • 校验请求数据长度,过滤无效请求
    • 检查内存分配结果,避免空指针异常
    • 验证表单参数解析完整性,确保数据有效性
    • 判断业务函数返回值,给用户明确操作反馈
  3. 用户体验优化:操作完成后提供返回表单的链接,方便用户再次预订

内容的提问来源于stack exchange,提问作者Julio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:05:18