Отправить файл, используя POST [Невозможно загрузить] в C ++

У меня проблемы с отправкой файла на мой сервер. Я проверил некоторые другие вопросы, пытался решить большинство проблем, но в конце я не могу загрузить файл
Вот мой код C ++:

   #define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <wininet.h>
#include <iostream>
#include <tchar.h>
#pragma warning(disable : 4996)
#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 = "perf.txt";   //Filename to be loaded
static char *filepath = "C:\\perf.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[] = "2e8cd930.ngrok.io";        //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\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;
}

Вот мой PHP-код [upload.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);
}
?>

Используя Wireshark, мой пост-запрос и ответ: [Я уже пытался заменить две новые строки на 1 строку после строки Content -Type, но это не помогло
После изменения разделителя:

    POST /post/upload.php HTTP/1.1
Content-Type: multipart/form-data; boundary=BOUNDARY
User-Agent: WINDOWS
Host: 2e8cd930.ngrok.io
Content-Length: 130
Cache-Control: no-cache

-BOUNDARY
Content-Disposition: form-data; name="file"; filename="perf.txt"Content-Type: text/plainWhats Up?
-BOUNDARY-
HTTP/1.1 200 OK
Date: Sat, 25 Nov 2017 11:25:16 GMT
Server: Apache/2.4.27 (Debian)
Content-Length: 10
Content-Type: text/html; charset=UTF-8

Array
(
)

Я не знаю, почему мой ответ сервера выходит с Array (). Файл не загружается.

0

Решение

Первые проблемы, которые я вижу:

Вы говорите в своих заголовках, что разделитель —BOUNDARY и затем используйте ту же строку, что и фактический разделитель. Это не верно. Формат

—DELIMITER
content
—DELIMITER
content
—DELIMITER—

Так что ваши заголовки должны сказать просто BOUNDARY в качестве разделителя.

Content-Type: multipart/form-data; boundary=BOUNDARY

Вы также должны добавить трейлинг к заключительному разделителю.

У вас также есть \r\n\n при отделении заголовков от корпуса. Так должно быть \r\n\r\n,

Эти ошибки приведут к тому, что синтаксический анализатор MIME нигде не найдет данные формы.

Вы не должны использовать производительность sprintf добавить данные, указав сначала буфер, а затем то, что вы хотите добавить. Это приведет к чрезмерному копированию данных, которые уже есть. Вы должны использовать strncat скорее, все это строки, которые нужно добавить. Или отслеживая длину строки и используя sprintf до конца, чтобы добавить. Увидеть этот вопрос для дополнительной информации.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector