gpt4 book ai didi

php - 发送文件 POST C++

转载 作者:太空狗 更新时间:2023-10-29 23:02:57 25 4
gpt4 key购买 nike

我正在尝试使用 C++ 通过 POST 将文本文件发送到我的本地主机网络服务器上的 php upload.php 表单。

这是我的请求的 php 代码:

<?php
$uploaddir = 'upload/';

if (is_uploaded_file(isset($_FILES['file']['tmp_name'])?($_FILES['file'['tmp_name']):0))
{
$uploadfile = $uploaddir . basename($_FILES['file']['name']);
echo "File ". $_FILES['file']['name'] ." uploaded successfully. ";

if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile))
{
echo "File was moved! ";
}
else
{
print_r($_FILES);
}
}
else
{
print_r($_FILES);
}
?>

upload 目录与 upload.php(上面的内容)存在于同一目录中。

这是我用来准备和发送 http 请求的代码:

#include <windows.h>
#include <wininet.h>
#include <iostream>
#include <tchar.h>

#pragma comment(lib,"wininet.lib")
#define ERROR_OPEN_FILE 10
#define ERROR_MEMORY 11
#define ERROR_SIZE 12
#define ERROR_INTERNET_OPEN 13
#define ERROR_INTERNET_CONN 14
#define ERROR_INTERNET_REQ 15
#define ERROR_INTERNET_SEND 16

using namespace std;

int main()
{
// Local variables
static char *filename = "test.txt"; //Filename to be loaded
static char *filepath = "C:\\wamp\\www\\post\\test.txt"; //Filename to be loaded
static char *type = "text/plain";
static char boundary[] = "--BOUNDARY---"; //Header boundary
static char nameForm[] = "file"; //Input form name
static char iaddr[] = "localhost"; //IP address
static char url[] = "/post/upload.php"; //URL

char hdrs[512]={'-'}; //Headers
char * buffer; //Buffer containing file + headers
char * content; //Buffer containing file
FILE * pFile; //File pointer
long lSize; //File size
size_t result;

// Open file
pFile = fopen ( filepath , "rb" );
if (pFile==NULL)
{
printf("ERROR_OPEN_FILE");
getchar();
return ERROR_OPEN_FILE;
}
printf("OPEN_FILE\n");

// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);

// allocate memory to contain the whole file:
content = (char*) malloc (sizeof(char)*(lSize+1));
if (content == NULL)
{
printf("ERROR_MEMORY");
getchar();
return ERROR_OPEN_FILE;
}
printf("MEMORY_ALLOCATED\t \"%d\" \n",&lSize);
// copy the file into the buffer:
result = fread (content,1,lSize,pFile);
if (result != lSize)
{
printf("ERROR_SIZE");
getchar();
return ERROR_OPEN_FILE;
}
printf("SIZE_OK\n");

content[lSize] = '\0';

// terminate
fclose (pFile);
printf("FILE_CLOSE\n");
//allocate memory to contain the whole file + HEADER
buffer = (char*) malloc (sizeof(char)*lSize + 2048);

//print header
sprintf(hdrs,"Content-Type: multipart/form-data; boundary=%s",boundary);
sprintf(buffer,"%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n",boundary,nameForm,filename);
sprintf(buffer,"%sContent-Type: %s\r\n",buffer,type);
sprintf(buffer,"%s\r\n%s",buffer,content);
sprintf(buffer,"%s\r\n--%s--\r\n",buffer,boundary);

printf("%s", buffer);

//Open internet connection
HINTERNET hSession = InternetOpen("WINDOWS",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hSession==NULL)
{
printf("ERROR_INTERNET_OPEN");
getchar();
return ERROR_OPEN_FILE;
}
printf("INTERNET_OPENED\n");

HINTERNET hConnect = InternetConnect(hSession, iaddr,INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if(hConnect==NULL)
{
printf("ERROR_INTERNET_CONN");
getchar();
return ERROR_INTERNET_CONN;
}
printf("INTERNET_CONNECTED\n");

HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",_T(url),NULL, NULL, NULL,INTERNET_FLAG_RELOAD, 1);
if(hRequest==NULL)
{
printf("ERROR_INTERNET_REQ");
getchar();

}
printf("INTERNET_REQ_OPEN\n");

BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));

if(!sent)
{
printf("ERROR_INTERNET_SEND");
getchar();
return ERROR_INTERNET_CONN;
}
printf("INTERNET_SEND_OK\n");

InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);

getchar();
return 0;
}

当我执行 upload.exe(上面的内容)时。我得到以下输出:

OPEN_FILE
MEMORY_ALLOCATED "1832340"
SIZE_OK
FILE_CLOSE
---BOUNDARY---
Content Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain
test
---BOUNDARY---
INTERNET_OPENED
INTERNET_CONNECTED
INTERNET_REQ_OPEN
INTERNET_SEND_OK

这是 PHP 错误日志:

[12-Nov-2014 20:09:58 Europe/Paris] PHP Stack trace:
[12-Nov-2014 20:09:58 Europe/Paris] PHP 1. {main}() C:\wamp\www\post\upload.php:0

我有点不明白这是什么意思。这是一个错误吗?

看起来一切正常(注意:test.txt 的内容是“test”)。虽然当我查看 upload 目录时。 test.txt 文件不在那里。该目录为空。谁能帮我理解问题是什么?谢谢!

BUMP 没有人知道该怎么做还是不可能?因为如果不可能,请告诉我,这样我就可以停止浪费时间搜索。

最佳答案

测试您的 C++ 客户端时,我发现包含文件内容的变量 content 不以 NULL 结尾,因此当您使用 复制它时sprintf 您正在复制随机字节,直到出现 NULL

将分配更改为此:

 content = (char*) malloc (sizeof(char)*(lSize+1));

读取文件内容后执行此操作:

content[lSize] = '\0';

另外,我很确定 BOUNDARY 应该从新的一行开始。因此,也进行此更改:

 sprintf(buffer,"%s\r\n--%s--\r\n",buffer,boundary);

编辑:

通过比较常规的 HTML 表单请求,我可以看到内容应该在两行之后开始,所以也更改一下:

sprintf(buffer,"%s\r\n%s",buffer,content);

编辑2:

用PHP代码测试后,我发现c++代码还有一些问题。(顺便说一句,PHP 代码中有一个拼写错误:if 语句中缺少 ])

边界设置不正确。

mime 的格式应该是这样的:

--BOUNDARY
Content-Disposition: form-data; name="file"; filename="test2.txt"
Content-Type: text/plain

test
--BOUNDARY

HTTP header 应该是这样的: 内容类型:多部分/表单数据;边界=边界

所以 sprintf 应该是这样的:

sprintf(hdrs,"Content-Type: multipart/form-data; boundary=%s",boundary);
sprintf(buffer,"--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n",boundary,nameForm,filename);
sprintf(buffer,"%sContent-Type: %s\r\n",buffer,type);
sprintf(buffer,"%s\r\n%s",buffer,content);
sprintf(buffer,"%s\r\n--%s\r\n",buffer,boundary);

完成本文中的所有修复后,代码应该可以工作了。

总结:

  1. 我建议使用 VM 设置来更轻松地调试此类问题,因为这样您就可以使用 Wireshark\Fidler\Burp。 (您也可以尝试为本地主机配置代理,我自己从未尝试过。您也可以尝试使用您的外部互联网 IP 并配置您的路由器以进行端口转发,但这对于此类任务来说太复杂了)。
  2. 如果这没有帮助,NetCat 可能会有所帮助。不那么轻松和友好,但可以胜任。
  3. 只需将一个工作示例与您的请求输出进行比较,即可准确了解缺少的内容。为此,我使用了 Beyond Compare。始终使用比较软件,因为人眼很容易被欺骗。
  4. 最明显的是阅读 Mime 规范,看看究竟缺少什么。

关于php - 发送文件 POST C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26895159/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com