2017-11-25 5 views
0

내 서버로 파일 보내기에 문제가 있습니다. 좀 다른 질문이 대부분의 문제를 해결하기 위해 노력 확인했지만 마지막에 내가 파일 을 업로드 할 수 없습니다 나는 여기에 내 C++ 코드 :POST를 사용하여 파일 보내기 [업로드 할 수 없습니다] 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를 내 POST 요청 및 응답을 이미 컨텐츠 타입 라인하지만 도움이되지 후 1 개 라인이 개 새로운 라인을 교체 시도 [한다 사용 : 이미 파일을 생성하고 삭제하는 다른 사람을 위해 업로드 폴더 권한을 변경 한 구분 기호 변경 후 :

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/plain 


Whats 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

적어도 닫는 구분 기호와 헤더의 구분 기호가 잘못되었습니다. - 경계의 일부가 아니므로 헤더에서 제거하십시오. 닫는 구분 기호도 필요합니다. sprintfs는 새로운 데이터를 추가하는 대신 기존 데이터를 계속해서 복사하므로 좋지 않습니다. 그리고 시체가 실종되기 전에 \ r. –

+0

죄송합니다, 무슨 뜻인지 이해할 수 없습니다. 정교하게 작성하거나 코드를 편집하여 이해할 수 있습니까? –

답변

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을 사용하여 추가합니다. 자세한 내용은 this question을 참조하십시오.

+0

내가 구분 기호를 변경했고 업데이트 된 요청은 위와 같지만 여전히 파일을 업로드 할 수 없습니까 ?? 어떠한 제안 –