如何在C中使用wininet api将文件上载到anonfile?

如何在C中使用wininet api将文件上载到anonfile?,c,winapi,http-post,C,Winapi,Http Post,我正在尝试使用wininet库将文件上载到C中的anonfile 根据,我们需要将指定文件的POST HTTP请求发送到以下URL: https://api.anonfile.com/upload 此外,我还上传了一个带有CURL的文件,以查看生成的标题: 因此,我的函数看起来像这样()。请注意,它仍然不处理服务器响应,只处理发送: #include <windows.h> #include <wininet.h> #include <stdio.h> #

我正在尝试使用wininet库将文件上载到C中的anonfile

根据,我们需要将指定文件的POST HTTP请求发送到以下URL:

https://api.anonfile.com/upload
此外,我还上传了一个带有CURL的文件,以查看生成的标题:

因此,我的函数看起来像这样()。请注意,它仍然不处理服务器响应,只处理发送:

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

#pragma comment(lib,"Wininet.lib") //Library
#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

int main(int argc, char* argv[])
{
    // Local variables
    char* filename = "C:\\test.zip";   //Filename to be loaded
    char* type = "binary";
    char boundary[] = "pippo";            //Header boundary
    char nameForm[] = "upload";     //Input form name
    char iaddr[] = "api.anonfile.com";        //IP address
    char url[] = "upload";         //URL

    char hdrs[1024];                  //Headers
    char* buffer;                   //Buffer containing file + headers
    char* content;                  //Buffer containing file
    FILE* pFile;                    //File pointer
    long lSize;                      //File size
    HRESULT result;

    // Open file
    fopen_s(&pFile, 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_s(hdrs,
        1024,
        "POST /upload HTTP/2\r\n"
        "Host: api.anonfile.com\r\n"
        "User-Agent: curl/7.60.0"
        "cache-control: no-cache\r\n"
        "content-type: multipart/form-data\r\n"
        "name=\"%s\"; filename=\"%s\"\r\n"
        "Content-Length: %i\r\n"
        "Accept: */*\r\n"
        "\n", nameForm, filename, lSize);

    //Open internet connection
    HINTERNET hSession = InternetOpen("WinSock", 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) {
        printf("%d", GetLastError());
        return ERROR_INTERNET_CONN;
    }

    HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST", url, NULL, NULL, (const char**)"*/*\0", 0, 1);
    if (hRequest == NULL) {
        printf("%d", GetLastError());
        return ERROR_INTERNET_REQ;
    } 

    BOOL sent = HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));
    if (!sent) {
        printf("%d", GetLastError());
            return ERROR_INTERNET_SEND;
    } 

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

    return 0;
}
我错过了什么


这里是,但是它使用CURL,它是在C++中。

< p>您的错误消息意味着代码在互联网络()/<代码> >

上失败了。 错误代码123是
Error\u INVALID\u NAME
:“文件名、目录名或卷标语法不正确”

API要求您通过HTTPS进行post,但您正在尝试连接到HTTP端口80,而不是HTTPS端口443


您需要将
INTERNET\u DEFAULT\u HTTP\u端口
更改为
INTERNET\u DEFAULT\u HTTPS\u端口

您的错误消息意味着代码在
InternetConnect()
上失败

错误代码123是
Error\u INVALID\u NAME
:“文件名、目录名或卷标语法不正确”

API要求您通过HTTPS进行post,但您正在尝试连接到HTTP端口80,而不是HTTPS端口443


您需要将
INTERNET\u DEFAULT\u HTTP\u端口
更改为
INTERNET\u DEFAULT\u HTTPS\u端口

访问安全站点时,如RemyLebeau所述,更改为
INTERNET\u DEFAULT\u HTTPS\u PORT

HttpOpenRequest

要使用
“内容类型:多部分/表单数据”
上载数据,需要使用
stru open
stru close
包装数据,如下代码所示:

注意,
“$$ABCXYZ$$”
是一些随机文本。将其更改为目标文件中不存在的更随机的内容

int main()
{
    const char* str_header = "Content-Type: multipart/form-data; boundary=----$$ABCXYZ$$";
    const char* str_open = "------$$ABCXYZ$$\r\n"
        "Content-Disposition: form-data; name=\"file\"; filename=\"filename.txt\"\r\n"
        "Content-Type: application/octet-stream\r\n"
        "\r\n";
    const char *str_close = "\r\n------$$ABCXYZ$$--\r\n";

    FILE *fp = NULL;
    fopen_s(&fp, "filename.txt", "rb");
    if(!fp)
        return 0;

    fseek(fp, 0, SEEK_END);
    long filesize = ftell(fp);
    rewind(fp);
    int datalen = filesize + strlen(str_open) + strlen(str_close);
    char *data = malloc(datalen);

    strcpy_s(data, datalen, str_open);
    fread(data + strlen(str_open), 1, filesize, fp);
    memcpy(data + strlen(str_open) + filesize, str_close, strlen(str_close));

    HINTERNET hsession = NULL, hconnect = NULL, hrequest = NULL;

    hsession = InternetOpenA("myname", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if(!hsession)
        goto cleanup;

    hconnect = InternetConnectA(hsession, "api.anonfile.com",
        INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
    if(!hconnect)
        goto cleanup;

    hrequest = HttpOpenRequestA(hconnect, "POST", "/upload",
        NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0);
    if(!hrequest)
        goto cleanup;

    if(!HttpSendRequestA(hrequest, str_header, (DWORD)-1, data, datalen))
        goto cleanup;

    DWORD received;
    BYTE buf[1024];
    while(InternetReadFile(hrequest, buf, sizeof(buf), &received) && received)
    {
        buf[received] = 0;
        printf("%s\n", buf);
    }

cleanup:
    fclose(fp);
    if(hsession)InternetCloseHandle(hsession);
    if(hconnect)InternetCloseHandle(hconnect);
    if(hrequest)InternetCloseHandle(hrequest);

    return 0;
}

编辑:更改
datalen
,将
strlen(data)
更改为
datalen
,以实现二进制文件兼容性

访问安全站点时,请更改为RemyLebeau提到的
INTERNET\u DEFAULT\u HTTPS\u PORT

HttpOpenRequest

要使用
“内容类型:多部分/表单数据”
上载数据,需要使用
stru open
stru close
包装数据,如下代码所示:

注意,
“$$ABCXYZ$$”
是一些随机文本。将其更改为目标文件中不存在的更随机的内容

int main()
{
    const char* str_header = "Content-Type: multipart/form-data; boundary=----$$ABCXYZ$$";
    const char* str_open = "------$$ABCXYZ$$\r\n"
        "Content-Disposition: form-data; name=\"file\"; filename=\"filename.txt\"\r\n"
        "Content-Type: application/octet-stream\r\n"
        "\r\n";
    const char *str_close = "\r\n------$$ABCXYZ$$--\r\n";

    FILE *fp = NULL;
    fopen_s(&fp, "filename.txt", "rb");
    if(!fp)
        return 0;

    fseek(fp, 0, SEEK_END);
    long filesize = ftell(fp);
    rewind(fp);
    int datalen = filesize + strlen(str_open) + strlen(str_close);
    char *data = malloc(datalen);

    strcpy_s(data, datalen, str_open);
    fread(data + strlen(str_open), 1, filesize, fp);
    memcpy(data + strlen(str_open) + filesize, str_close, strlen(str_close));

    HINTERNET hsession = NULL, hconnect = NULL, hrequest = NULL;

    hsession = InternetOpenA("myname", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if(!hsession)
        goto cleanup;

    hconnect = InternetConnectA(hsession, "api.anonfile.com",
        INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
    if(!hconnect)
        goto cleanup;

    hrequest = HttpOpenRequestA(hconnect, "POST", "/upload",
        NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0);
    if(!hrequest)
        goto cleanup;

    if(!HttpSendRequestA(hrequest, str_header, (DWORD)-1, data, datalen))
        goto cleanup;

    DWORD received;
    BYTE buf[1024];
    while(InternetReadFile(hrequest, buf, sizeof(buf), &received) && received)
    {
        buf[received] = 0;
        printf("%s\n", buf);
    }

cleanup:
    fclose(fp);
    if(hsession)InternetCloseHandle(hsession);
    if(hconnect)InternetCloseHandle(hconnect);
    if(hrequest)InternetCloseHandle(hrequest);

    return 0;
}

编辑:更改了
datalen
,将
strlen(数据)
更改为
datalen
,以实现二进制文件兼容性

:如果连接成功,则返回会话的有效句柄,否则返回NULL。要检索扩展错误信息,请调用GetLastError。应用程序还可以使用InternetGetLastResponseInfo来确定拒绝访问服务的原因。“
缓冲区
不包含任何内容。您希望发送
内容
lSize
(尽管这不会解决您的主要问题):“如果连接成功,则返回会话的有效句柄,否则为空。要检索扩展错误信息,请调用GetLastError。应用程序还可以使用InternetGetLastResponseInfo确定拒绝访问该服务的原因。“
缓冲区
不包含任何内容。您想发送
内容
lSize
(虽然这不会解决您的主要问题)谢谢!但我在InternetConnect()中发现一个错误,GetLastError()函数检索值
123
。我刚刚在
fopen_s
和头文件的
filename
变量中更改了文件的路径。是否看到发生的任何线索?是否收到任何编译警告?通过设置Unicode并提供错误的ANSI输入,我可以复制123错误。请尝试修改后的使用ANSI
Internet***A
函数编写代码。就是这样!非常感谢,伙计!:)谢谢!但是我在InternetConnect()中发现了一个错误,GetLastError()函数检索值
123
。我刚刚在
fopen_s
和头文件的
filename
变量中更改了文件的路径。是否看到发生的任何线索?是否收到任何编译警告?通过设置Unicode并提供错误的ANSI输入,我可以复制123错误。请尝试修改后的使用ANSI
Internet***A
函数编写代码。就是这样!非常感谢,伙计!:)