使用libcurl从Ubuntu向Apache HTTP服务器上传.txt文件失败
问题分析
你遇到的核心问题是客户端发送的POST数据格式和服务器端期望的不匹配。你的C代码直接将文件内容作为原始POST数据发送(请求头里的Content-Type是application/x-www-form-urlencoded),但PHP的$_FILES数组只处理遵循HTTP标准的multipart/form-data格式文件上传请求,所以服务器找不到名为content的文件字段,才抛出了Undefined index: content的错误。
修正后的C代码(使用libcurl标准文件上传格式)
我们需要用libcurl的表单上传API来构造符合要求的请求,推荐用较新的curl_mime系列函数(替代旧版的curl_formadd),这样能自动生成正确的请求格式:
#include <stdio.h> #include <curl/curl.h> #include <sys/stat.h> int main(void) { CURL *curl; CURLcode res; curl_mime *mime; curl_mimepart *part; curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); if(curl) { // 设置目标上传URL curl_easy_setopt(curl, CURLOPT_URL, "http://x.x.x.x/dashboard/"); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); // 创建multipart/form-data表单 mime = curl_mime_init(curl); // 添加名为"content"的文件字段(对应PHP的$_FILES['content']) part = curl_mime_addpart(mime); curl_mime_name(part, "content"); curl_mime_filedata(part, "/home/shantanu/test.txt"); // 直接传入文件路径,libcurl自动处理读取 // 将表单设置为POST请求的内容 curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); // 执行上传请求 res = curl_easy_perform(curl); if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); // 清理资源 curl_mime_free(mime); curl_easy_cleanup(curl); } curl_global_cleanup(); return 0; }
编译时记得链接libcurl库:
gcc upload.c -o upload -lcurl
修正后的PHP代码(增加错误检查)
你的PHP代码还有两处问题:拼写错误($_FILE应该是$_FILES)、缺少上传状态检查,修改后更健壮:
<?php // 先验证是否有合法的文件上传 if(isset($_FILES['content']) && $_FILES['content']['error'] === UPLOAD_ERR_OK) { $target_file = "./test.txt"; // 移动临时文件到目标路径 if(move_uploaded_file($_FILES['content']['tmp_name'], $target_file)) { echo "文件上传成功!"; } else { echo "移动文件失败,请检查目录权限!"; } } else { // 输出具体错误信息 if(isset($_FILES['content'])) { $error_codes = [ UPLOAD_ERR_INI_SIZE => "文件超过php.ini限制大小", UPLOAD_ERR_FORM_SIZE => "文件超过表单限制大小", UPLOAD_ERR_PARTIAL => "文件仅部分上传", UPLOAD_ERR_NO_FILE => "未选择上传文件", UPLOAD_ERR_NO_TMP_DIR => "服务器缺少临时目录", UPLOAD_ERR_CANT_WRITE => "文件写入失败", UPLOAD_ERR_EXTENSION => "上传被PHP扩展阻止" ]; echo "上传错误:" . $error_codes[$_FILES['content']['error']]; } else { echo "未接收到上传的文件字段!"; } } ?>
额外注意事项
- 确保服务器端
dashboard目录有写入权限,否则move_uploaded_file会执行失败 - 如果你的libcurl版本低于7.56.0,可能需要使用旧版的
curl_formaddAPI,建议升级到新版本使用更简洁的curl_mime
内容的提问来源于stack exchange,提问作者Shantanu
相关产品推荐
相关产品推荐

