树莓派Pico 2W中lwIP的fs_open_custom获取HTTP GET键值对问题
在Pico SDK lwIP中获取HTTP GET查询参数的解决方法
一、正确使用CGI Handler处理请求(推荐)
你之前遇到的“incorrect response”错误,大概率是CGI handler返回的内容不符合HTTP规范。按以下方式编写即可解决:
- 编写CGI处理函数,直接获取完整URI并解析参数:
#include <lwip/apps/httpd.h> #include <string.h> #include <stdlib.h> err_t cgi_sum_handler(struct httpd_state *hs) { char value1_buf[16] = {0}; char value2_buf[16] = {0}; int val1 = 0, val2 = 0, sum = 0; // 用lwIP自带函数解析查询参数 httpd_query_parse(hs->uri, "value1", value1_buf, sizeof(value1_buf)); httpd_query_parse(hs->uri, "value2", value2_buf, sizeof(value2_buf)); // 转换为整数并计算 val1 = atoi(value1_buf); val2 = atoi(value2_buf); sum = val1 + val2; // 发送符合规范的HTTP响应头 const char *response_header = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n"; httpd_send(hs, response_header, strlen(response_header)); // 发送计算结果 char result_buf[32] = {0}; snprintf(result_buf, sizeof(result_buf), "计算结果:%d", sum); httpd_send(hs, result_buf, strlen(result_buf)); return ERR_OK; }
- 将CGI handler注册到HTTP服务器:
void setup_http_server(void) { struct httpd_server *server = httpd_start(NULL); if (server == NULL) { // 处理服务器启动失败逻辑 return; } httpd_uri_t cgi_handler = { .uri = "/cgi-bin/handler.cgi", // 匹配请求路径 .method = HTTP_GET, // 仅处理GET请求 .handler = cgi_sum_handler, .user_data = NULL }; httpd_register_uri_handler(server, &cgi_handler); }
按此方式处理后,浏览器即可正常接收响应,不会再报错。
二、如果一定要用fs_open_custom获取查询字符串
lwIP没有直接提供全局变量存储原始查询字符串,但可以通过fs_file的private_data字段获取当前请求上下文:
在fs_open_custom实现中,file->private_data指向当前的struct httpd_state结构体,其中的uri成员保存了完整的请求路径(包含?及后续键值对):
#include <lwip/apps/httpd.h> #include <lwip/apps/fs.h> err_t custom_fs_open(struct fs_file *file, const char *name, struct fs_dirent *dirent) { // 将private_data转换为httpd_state指针 struct httpd_state *hs = (struct httpd_state*)file->private_data; if (hs != NULL) { // hs->uri 即为完整请求URI,例如 "/cgi-bin/handler.cgi?value1=5&value2=3" char value1_buf[16] = {0}; httpd_query_parse(hs->uri, "value1", value1_buf, sizeof(value1_buf)); // 解析value2及计算逻辑同上... } // 后续实现文件打开、响应构建等逻辑 return ERR_OK; } // 定义自定义文件系统操作集合 static const struct fs_operations custom_fs = { .open = custom_fs_open, // 需实现其他必要的文件系统操作函数(如read、close等) }; void setup_custom_fs(void) { httpd_fs_set_custom(&custom_fs); }
注意:这种方式需要实现完整的文件系统操作接口,动态生成响应的复杂度远高于CGI handler,更推荐使用第一种方案。
内容的提问来源于stack exchange,提问作者user32048100
相关产品推荐
相关产品推荐

