通过POST上传文件 [英] Upload file via POST
问题描述
我必须用C ++在Web服务器上实现文件上传,我成功完成了以下代码:
I have the necessity to implements a file upload on a web server in C++, I succeed with the following code:
#include <windows.h>
#include <wininet.h>
#include <iostream>
#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 *type = "image/jpg";
static char boundary[] = "pippo"; //Header boundary
static char nameForm[] = "uploadedfile"; //Input form name
static char iaddr[] = "localhost"; //IP address
static char url[] = "test.php"; //URL
char hdrs[255]; //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 ( filename , "rb" );
if (pFile==NULL) return ERROR_OPEN_FILE;
// 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);
if (content == NULL) return ERROR_MEMORY;
// copy the file into the buffer:
result = fread (content,1,lSize,pFile);
if (result != lSize) return ERROR_SIZE;
// terminate
fclose (pFile);
//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\r\n",buffer,type);
sprintf(buffer,"%s%s\r\n",buffer,content);
sprintf(buffer,"%s--%s--\r\n",buffer,boundary);
//Open internet connection
HINTERNET hSession = InternetOpen("WinSock",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hSession==NULL) return ERROR_INTERNET_OPEN;
HINTERNET hConnect = InternetConnect(hSession, iaddr,INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if(hConnect==NULL) return ERROR_INTERNET_CONN;
HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",url, NULL, NULL, (const char**)"*/*\0", 0, 1);
if(hRequest==NULL) return ERROR_INTERNET_REQ;
BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));
if(!sent) return ERROR_INTERNET_SEND;
//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return 0;
}
从服务器端开始,有一个PHP脚本使用保存在$ _FILES变量中的信息来执行文件保存. 该代码适用于TXT文件,但不适用于JPG(图像)文件:在这种情况下,该文件已正确创建并命名为服务器端,但为空!我认为这与我读取二进制文件并将其写入字符串有关. 有什么建议吗?
From server side there is a PHP script that perform file saving using informations stored in $_FILES variable. The code works well with TXT file, but does not work with JPG (image) files: in this case the file is correctly created and named server side, but it is empty! I think it is related to the fact that I read a binary file and wrote it on a string. Any suggestion?
谢谢
推荐答案
您不应在二进制数据上使用sprintf(buffer,"%s%s\r\n",buffer,content);
.它不是字符串,所以%s
是错误的.
You shouldn't be using sprintf(buffer,"%s%s\r\n",buffer,content);
on binary data. It isn't a string, so %s
is wrong.
您需要使用适当的Content-Transfer-Encoding
对base64进行编码,或者使用具有Content-Length
标头的memcpy.
You either need to base64 encode it with an appropriate Content-Transfer-Encoding
, or use memcpy with a Content-Length
header.
这篇关于通过POST上传文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!