1

I am trying to send a file to HTTP server via POST request (c++ and winapi), steps:

// Read file into "buff" and file size into "buffSize" 
        ....
    ....
    ....

    HINTERNET internetRoot;
    HINTERNET httpSession;
    HINTERNET httpRequest;

    internetRoot = InternetOpen(agent_info, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);

    //Connecting to the http server
    httpSession = InternetConnect(internetRoot, IP,PORT_NUMBER, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, NULL);

    //Creating a new HTTP POST request to the default resource on the server
    httpRequest = HttpOpenRequest(httpSession, TEXT("POST"), TEXT("/Post.aspx"), NULL, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, NULL);

    //Send POST request
    HttpSendRequest(httpRequest, NULL, NULL, buff, buffSize);

    //Closing handles...

In server I am recieving the file using this code (asp.net)

Stream httpStream;
        try
        {
            httpStream = request.RequestContext.HttpContext.Request.InputStream;
        }
        catch (HttpException)
        {
            return;
        }

            byte[] tmp = new byte[httpStream.Length];
            int bytesRead = httpStream.Read(tmp, 0, 1024 * 1024);
            int totalBytesRead = bytesRead;
            while (bytesRead > 0)
            {
                bytesRead = httpStream.Read(tmp, totalBytesRead, 1024 * 1024);
                totalBytesRead += bytesRead;
            }
            httpStream.Close();
            httpStream.Dispose();

           //Save "tmp" to file...

I can send large files on local server (visual studio asp server), but I cannot send files over 1 MB to internet server. (HttpOpenRequest is failing) is there a better way to upload files?

2 Answers 2

1

Caveat: My Wininet is very rusty these days.

I wonder whether you ought to be setting the "Content-Length" header yourself. Your code seems to assume that either a) you are making a HTTP/1.0 request or b) that HttpSendRequest will add the header for your (which I don't think it does).

Either way without the server being told how big the incoming request is the default configuration of IIS will reject it if it can't determine the request size itself quickly.

My guess is if you use the lpszHeaders and dwHeadersLength parameters of the HttpSendRequest function to include the appropriate "Content-Length" header the problem will be resolved.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks for the answer I will try that, but it is odd why locally it worked (since no IIS involved) and when we went through IIS things changed ...
@CnativeFreak: Well that sounds about right to me, its my guess that IIS is rejecting the request in an attempt to prevent rogue or malicious requests doing bad things to a server like a DOS attack. The Cassini development server has no need for this protection and therefore you local debugging without IIS works fine.
I did the following char headers[255]; memset(headers,0,255); sprintf(headers,"Content-Length: %d",buffSize); if(!HttpSendRequest(httpRequest, headers, strlen(headers), buff, buffSize)) but still HttpSendRequest is exiting with not errors very fast
1

What error do you receive? I mean what does GetLastError() returns? If you send file 800KB then it works OK? I dont really see how because HttpOpenRequest does not know about size of the data.

Maybe it timeouts? But this would mean that HttpSendRequest actually fails. It might buffer all data but since size is huge, then it takes more time than timeout allows.

use following code to query current timeouts (in ms):

InternetQueryOption(h, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwReceiveTimeOut, sizeof(dwReceiveTimeOut));
InternetQueryOption(h, INTERNET_OPTION_SEND_TIMEOUT, &dwSendTimeOut, sizeof(dwSendTimeOut));

and following to set new ones:

InternetSetOption(h, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwNewReceiveTimeOut, sizeof(dwNewReceiveTimeOut));
InternetSetOption(h, INTERNET_OPTION_SEND_TIMEOUT, &dwNewSendTimeOut, sizeof(dwNewSendTimeOut));

2 Comments

I tried this, and it seems I can only send about 800KB I couldnt even send 1 MB
I read them checked them in debugger and they were 30000 then set them to 600000 DWORD dwReceiveTimeOut; DWORD dwSendTimeOut; DWORD size=sizeof(dwReceiveTimeOut); InternetQueryOption(httpRequest, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwReceiveTimeOut, &size); InternetQueryOption(httpRequest, INTERNET_OPTION_SEND_TIMEOUT, &dwSendTimeOut, &size); dwReceiveTimeOut=600000; dwSendTimeOut=600000; InternetSetOption(httpRequest, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwReceiveTimeOut,size); InternetSetOption(httpRequest, INTERNET_OPTION_SEND_TIMEOUT, &dwSendTimeOut, size);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.