Apache2 웹 서버에서 실행되는 PHP 응용 프로그램을 사용하여 파일을 업로드하려고 시도하는 C++ 프로그램이 있습니다. 나는 무엇을해야할지 잘 모르는 매우 이상한 문제가 있습니다. 그래서 httpSendRequest() 함수를 사용하여 HTTP 요청을 만들고 wireshark 에서 볼 때 올바른 형식으로 나타납니다. 그러나 파일이 업로드되지 않았고 아파치에 대한 access.log 파일을 볼 때 패킷 캡처에 명확하게 존재하지만 사용자 에이전트 또는 콘텐츠 길이가 표시되지 않습니다. 동일한 패킷에 대해 Apache2 access.log가 다릅니다.
참고로 200 상태를 반환 한 요청은 httpSendRequest를 사용하는 내 프로그램 대신에 트랩 제품군을 사용하여 보낸 동일한 패킷이며 웹 브라우저를 사용하여 파일을 성공적으로 업로드 할 수도 있습니다.
다음은 대부분 httpSendRequest를 사용하여 요청을 작성하는 코드로 this codeguru post에서 직접 가져온 것입니다. 여기
#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
$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";
}
}
?>
인가 완전히 작동 코드 콜론은 User-Agent 제품의 tok에서 합법적 인 문자입니다. 엉? – IInspectable
@IInspectable 나는 그것이 합법적이라고 확신하지만 어쨌든 불필요하기 때문에 그것을 없애 버렸다. 같은 문제가 남아있다. – pchihak