none
How to construct WinHttpSendRequest for POST? RRS feed

  • Question

  • Hi,

     

    I am trying to POST data on the webserver and I have a python script that will take name and data to create a file.

    I have found a few examples of GET method but I could not quite find any complete example for POST method and I am getting an error when I call WinHttpSendRequest().


    Here is part of my code that calls WinHttpSendRequest().

    LPSTR  data = "Content-Type: application/x-www-form-urlencoded
    \nContent-Length: 29\r\nlocation=abcd.txt&data=\"cool\"\r\n";
    DWORD data_len = strlen(data);
    
    hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/sd.py/save_data",
    NULL, WINHTTP_NO_REFERER,
                                                                    WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
    
    if (!hRequest) {
            wprintf(L"WinHttpOpenRequest failed (%d)\n", GetLastError());
            goto out;
    }
    
    if (WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
    (LPVOID)data, data_len, data_len, 0) != TRUE) {
            wprintf(L"WinHttpSendRequest failed (%d)\n", GetLastError());
            goto out;
    }
    


    I am getting 12002 error code right now and if anyone can show me how
    I should create data string, I would really appreciate it. Thank you
    in advance.
    Friday, September 11, 2009 6:17 PM

Answers

  • Operation time out. Ask the server's programmer.

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP
    • Marked as answer by Nancy Shao Friday, September 18, 2009 3:29 AM
    Friday, September 11, 2009 7:50 PM

All replies

  • Operation time out. Ask the server's programmer.

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP
    • Marked as answer by Nancy Shao Friday, September 18, 2009 3:29 AM
    Friday, September 11, 2009 7:50 PM
  • Thank you very much for your reply.
    If you don't mind, let me ask you one more question.

    I have tried various ways to get this piece working but I have not been able to successfully get it to work.
    My only concern is to know how to construct lpOptional field if that is all I need.

    For instance, this works if I manually type the following after I connect to web server.

    > telnet localhost 80
    Trying ::1...
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    POST /sd.py/save_data HTTP/1.0
    From: ilho@xxxxx.com
    User-Agent: HTTPTool/1.1
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 29

    location=abc.txt&data="cool"
    HTTP/1.1 200 OK


    So I just want to know how to transform header and optional data to correctly provide to WinHttpRequestSend() API.
    Could you specify how to construct a string or if you could point me to some example on the web, I will really appreciate it. Thank you very much.
    Friday, September 11, 2009 8:24 PM
  • After many trials, I found that I do not need to supply any header information for lpOptional.

    So this is what I did and it worked.

    LPSTR  data = "location=abd.txt&data=cool";
    DWORD data_len = strlen(data);
    
    // initiate SSL
    hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/sd.py/save_data", NULL, WINHTTP_NO_REFERER, 
    								WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
    
    if (!hRequest) {
    	wprintf(L"WinHttpOpenRequest failed (%d)\n", GetLastError());
    	goto out;
    }
    
    printf("HTTP POST processing for %s\n", data);
    
    if (WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, (LPVOID)data, data_len, data_len, 0) != TRUE) {
    	wprintf(L"WinHttpSendRequest failed (%d)\n", GetLastError());
    	goto out;
    }
    
    Perhaps it is my bad but I just could not find any complete example doing POST request but I hope this would help someone like me in the future. Thanks.
    Friday, September 11, 2009 9:29 PM
  • Hi Ilho,

    Thanks for sharing your solution here. It will be benefit for other community member who get the same issue with you.

    Thanks,
    Nancy
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, September 18, 2009 3:31 AM
  • I have found that for PHP to recognise the POSTed data, I had to also do this:

       LPCWSTR additionalHeaders = L"Content-Type: application/x-www-form-urlencoded\r\n";
       DWORD hLen   = -1;
       ...

       bResults = WinHttpSendRequest( hRequest, additionalHeaders , hLen , (LPVOID)params, pLen, pLen, 0);

    If I didn't include the Content-Type header, PHP wouldn't populate its $_POST array.
    Monday, October 5, 2009 4:49 PM
  • I noticed that when I searched for WinHttpSendRequest(), my question two years ago come up as the second entry in the result and assuming that people may need more info on this.

    I wrote a small example of using WinHttpSendRequest in my blog for more info.

    http://yeilho.blogspot.com/2011/07/winhttpsendrequest.html

     

    Hopefully, it will give more info. Thanks.

    Saturday, July 23, 2011 2:32 AM
  • hi ilho,thanks for your very simple example,but when i run my code,request sent,but i am not recieving any file in destination side. this is my code & wireshark status:

    //---------------------------------------------------------------------------------

    m_sessionHandle = WinHttpOpen(L"my userAgent",  
                                            WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                                            WINHTTP_NO_PROXY_NAME,
                                            WINHTTP_NO_PROXY_BYPASS,
                                           0);

     wstring m_requestURL = L"http://localhost:9999/upload.aspx";

     wchar_t szHostName[MAX_PATH] = L"";
        wchar_t szURLPath[MAX_PATH * 5] = L"";
        URL_COMPONENTS urlComp;
        memset(&urlComp, 0, sizeof(urlComp));
        urlComp.dwStructSize = sizeof(urlComp);
        urlComp.lpszHostName = szHostName;
        urlComp.dwHostNameLength = MAX_PATH;
        urlComp.lpszUrlPath = szURLPath;
        urlComp.dwUrlPathLength = MAX_PATH * 5;
        urlComp.dwSchemeLength = 1; // None zero
        
    if (WinHttpCrackUrl(m_requestURL.c_str(), m_requestURL.size(), 0, &urlComp))
    {
        m_requestHost = szHostName;
        HINTERNET hConnect = NULL;
        hConnect = WinHttpConnect(m_sessionHandle, szHostName, urlComp.nPort, 0);
        
        HINTERNET hRequest = NULL;
            hRequest = WinHttpOpenRequest(hConnect,
                                            L"POST",
                                            urlComp.lpszUrlPath,
                                            NULL,
                                            WINHTTP_NO_REFERER,
                                            WINHTTP_DEFAULT_ACCEPT_TYPES,
                                            dwOpenRequestFlag);
        if (hRequest != NULL)
        {
            wstring m_additionalRequestHeaders = L"Content-Type: multipart/form-data; boundary=-----------------------------myfile";
            WinHttpAddRequestHeaders(hRequest, m_additionalRequestHeaders.c_str(), m_additionalRequestHeaders.size(), WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
                                
            CHAR* pszTxt= "-----------------------------myfile\r\n"
                "Content-De-data;name=\"myfile\"; filename=\"thfile.zip\"\r\n"
                "Content-Type: application/zip; charset=utf-8\r\n\r\n";
           

           
            
            char *filebytes;
            size_t fileLength;
            
            ifstream myfile(fileaddress);
            if (myfile.is_open())
            {
                myfile.seekg(0, ios::end);
                fileLength = myfile.tellg();
                *filebytes= new char[fileLength];
                myfile.seekg(0, ios::beg);
                myfile.read(filebytes, fileLength);
                myfile.close();
            }

            DWORD totalLength = (lstrlenA(pszTxt) + fileLength + lstrlenA("\r\n-----------------------------myfile--\r\n\r\n"));
            
            bool bSendRequestSucceed = false;
            if (WinHttpSendRequest(hRequest,
                WINHTTP_NO_ADDITIONAL_HEADERS,
                0,
                (LPVOID)pszTxt,
                (DWORD)lstrlenA(pszTxt),
                totalLength,
                NULL))
            {
                bSendRequestSucceed = true;
            }

            DWORD dwWritten = 0;
            unsigned int pack_size = 16384, sended = 0;
            BYTE* pack = new BYTE[pack_size];
            
            while (sended < fileLength)
            {
                unsigned int len = (sended + pack_size < fileLength) ? pack_size : fileLength - sended;
                memcpy(pack, m_pDataToSend + sended, len);
                if (!::WinHttpWriteData(hRequest,
                    pack,
                    len,
                    &dwWritten))
                {
                    m_dwLastError = ::GetLastError();
                    break;
                }
                sended += len;
            }
            delete[] pack;

            char * endBoundary="\r\n-----------------------------myfile--\r\n\r\n";
            ::WinHttpWriteData(hRequest,
                endBoundary,
                lstrlenA(endBoundary),
                &dwWritten);
            
        }
    }

    //---------------------------------------------------------------------------------

    wireshark request status: https://imgur.com/QmUSPFq

    can you explain what is wrong in my code?

    very thanks




    • Edited by mattmail Wednesday, August 14, 2019 5:21 AM
    Tuesday, August 13, 2019 7:52 AM