2017-11-25 84 views
0

我在将文件发送到我的服务器时遇到问题。我已经查了一些其他问题试图解决大部分的问题,但在结束我不能够上传的文件 这里是我的C++代码:在C++中使用POST [无法上载]发送文件

#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的我的帖子的请求和响应[我已经尝试与内容-Type线,但没有帮助后,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

我有更改分界符和我更新的请求是上面但我仍然无法上传文件?任何建议 –

相关问题