Apache2 access.log отличается для одних и тех же пакетов

У меня есть программа на C ++, которая пытается загрузить файл с помощью приложения PHP, работающего на веб-сервере Apache2. У меня очень странная проблема, с которой я не уверен, что делать. Поэтому я создаю HTTP-запрос с помощью функции httpSendRequest (), и он выглядит правильно отформатированным при просмотре в wireshark проволочное изображение. Однако файл не загружен, и когда я просматриваю файл access.log для apache, он не показывает ни агента пользователя, ни длины контента, несмотря на то, что оба явно присутствуют в захвате пакета. изображение ошибки apache

Для справки: запросы, которые вернули статус 200, представляют собой один и тот же пакет, отправленный с использованием пакета burp, вместо моей программы, использующей httpSendRequest, и я также могу успешно загрузить файл с помощью веб-браузера.

Вот код для создания запроса с использованием httpSendRequest, большая часть которого была взята непосредственно из этот пост codeguru.

#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[]  = "PaulRules";            //Header boundary
static char nameForm[]  = "fileToUpload";     //Input form name
static char iaddr[]     = "192.168.0.105";        //IP address
static char url[]       = "upload.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=\"fileToUpload\"; filename=\"test.bmp\"\r\n",boundary,nameForm,filename);
sprintf(buffer,"%sContent-Type: %s\r\n\r\n",buffer,type);

int cb = strlen(buffer);
char * bp = buffer + cb;
memcpy(bp, content, lSize);
bp += lSize;
int cw = sprintf(bp,"\r\n--%s--\r\n",boundary);

//Open internet connection
HINTERNET hSession = InternetOpen("Paul was here :)",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, 1);
if(hRequest==NULL) return ERROR_INTERNET_REQ;

BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, cb + lSize + cw);
if(!sent) return ERROR_INTERNET_SEND;

//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);

return 0;
}

А вот PHP-скрипт на стороне сервера

<?php
$target_dir = "recvFile/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);

// Check if file already exists
if (file_exists($target_file)) {
echo "File already exists";
$uploadOk = 0;
}

// Check file size
if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "File to large";
$uploadOk = 0;
}

// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "ERROR File not uploaded";
}

//attempt to upload the file
else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
//echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
echo "Command:1";
}
else {
echo $_FILES["fileToUpload"]["tmp_name"];
echo "ERROR uploading file";
}
}
?>

1

Решение

Ваш исходный файл "test.txt" но вы загружаете в "test.bmp", Сделайте так, чтобы они имели одинаковое расширение.

type = "image/jpg";

+ Изменить type в "image/*" или же "text/*" если это должен быть текст.

Ваша операция, вероятно, успешно выполнена, поскольку она печатает "Command 1", Файл, вероятно, там, но это не тот, который вы ожидаете. Если нет, посмотрите, какую ошибку вы можете извлечь со стороны PHP.

sprintf(buffer,"--%s\r\nContent-Disposition: form-data; \
name=\"fileToUpload\"; filename=\"test.bmp\"\r\n",
boundary,nameForm,filename);

У вас есть один спецификатор формата "%s" и 4 параметра. Удалите последние два параметра.

использование HttpOpenRequest способ, которым это рекомендуется:

const char *accept[] = { "image/*", NULL }; // or `"text/*"`
HttpOpenRequest(hConnect, "POST",url, NULL, NULL, accept, 0, 1);

Код с использованием C ++

#include <Windows.h>
#include <Wininet.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

#pragma comment(lib, "wininet.lib")

int main()
{
HINTERNET hsession = NULL;
HINTERNET hconnect = NULL;
HINTERNET hrequest = NULL;

const char* server = "localhost";
const char* url = "upload.php";
const char* type = "image/*";
std::string filename = "test.bmp";

std::ifstream infile("c:\\test\\test.bmp", std::ios::binary);
if(!infile)
return 0;

std::ostringstream oss;
oss << infile.rdbuf();

std::string headers = "Content-type: multipart/form-data, boundary=uniquestring";

std::string data = "--uniquestring\r\n\
Content-Disposition: form-data; name=\"fileToUpload\"; filename=\"%1\"\r\n\
Content-Type: %2\r\n\
\r\n\
%3\r\n\
--uniquestring--";

data.replace(data.find("%1"), 2, filename);
data.replace(data.find("%2"), 2, type);
data.replace(data.find("%3"), 2, oss.str());

hsession = InternetOpen("appname", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(!hsession)
goto cleanup;

hconnect = InternetConnect(hsession, server, INTERNET_DEFAULT_HTTP_PORT,
NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if(!hconnect)
goto cleanup;

const char *accept[] = { type, NULL };
hrequest = HttpOpenRequest(hconnect, "POST", url, NULL, NULL, accept, 0, 1);
if(!hrequest)
goto cleanup;

BOOL sent = HttpSendRequest(hrequest, headers.data(), headers.size(),
&data[0], data.size());
if(sent)
{
DWORD bufsize = 4096;
std::string read(bufsize, 0);
InternetReadFile(hrequest, &read[0], bufsize, &bufsize);
read.resize(bufsize);
std::cout << read << "\n";
}
else
{
goto cleanup;
}

cleanup:
if(hrequest) InternetCloseHandle(hrequest);
if(hconnect) InternetCloseHandle(hconnect);
if(hsession) InternetCloseHandle(hsession);
return 0;
}
1

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

Просто для полноты здесь приведен полностью рабочий код

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

using namespace std;
int main()
{
// Local variables
static char *filename   = "Desert.jpg";   //Filename to be loaded
static char *type       = "multipart/form-data";
static char boundary[]  = "PaulRules";            //Header boundary
static char nameForm[]  = "fileToUpload";     //Input form name
static char iaddr[]     = "192.168.0.105";        //IP address
static char url[]       = "upload.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" );

// 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);

// copy the file into the buffer:
result = fread (content,1,lSize,pFile);

// 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=\"fileToUpload\"; filename=\"%s\"\r\n",boundary, filename);
sprintf(buffer,"%sContent-Type: %s\r\n\r\n",buffer,type);

int cb = strlen(buffer);
char * bp = buffer + cb;
memcpy(bp, content, lSize);
bp += lSize;
int cw = sprintf(bp,"\r\n--%s--\r\n",boundary);

//Open internet connection
HINTERNET hSession = InternetOpen("Winsock",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);

HINTERNET hConnect = InternetConnect(hSession, iaddr,INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);

const char* accept[] = {"*/*", NULL};
HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",url, NULL, NULL, accept, 0, 1);

BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, cb + lSize + cw);

DWORD dwSize, dwRead;
CHAR szBuffer[1024];
if(!InternetQueryDataAvailable(hRequest, &dwSize, 0, 0)){
std::cout << "QUERYDATA ERROR: " << GetLastError() << std::endl;
}
else{
while(InternetReadFile(hRequest, szBuffer, sizeof(szBuffer)-1, &dwRead) && dwRead) {
szBuffer[dwRead] = 0;
dwRead=0;
}
cout << szBuffer;
}

//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);

return 0;
}
1

По вопросам рекламы [email protected]