0

I am new to c++ but have managed to write the following code using microsoft documentation / looking at online examples / borrowing some code.

I want this code to be process agnostic ie able to be run in the context of a user or as a service with or without a proxy.

Any help would be appreciated:

**edited to reflect working code (should have updated in another place)

std::string Downloader() {

BOOL  bResults = FALSE;

HINTERNET hSession = NULL,

    hConnect = NULL,

    hRequest = NULL;



// Use WinHttpOpen to obtain a session handle.

hSession = WinHttpOpen(NULL,

    WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,

    WINHTTP_NO_PROXY_NAME,

    WINHTTP_NO_PROXY_BYPASS, 0);



// Specify an HTTP server.

if (hSession)

    hConnect = WinHttpConnect(hSession, L"10.0.2.4:8000", INTERNET_DEFAULT_HTTP_PORT, 0);



// Create an HTTP Request handle.

if (hConnect)

    hRequest = WinHttpOpenRequest(hConnect, L"GET", L"hello.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);



// Send a Request.

if (hRequest)

    bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0,  0, 0);


if (!bResults)

    printf("Error %d has occurred.\n", GetLastError());



WinHttpReceiveResponse(hRequest, 0);



DWORD responseLength, readDataLength = 0;

WinHttpQueryDataAvailable(hRequest, &responseLength);

std::string response(responseLength);

    WinHttpReadData(hRequest, &response[0], responseLength, &readDataLength);

printf("%s\n", response);



// Close any open handles.

if (hRequest) WinHttpCloseHandle(hRequest);

if (hConnect) WinHttpCloseHandle(hConnect);

if (hSession) WinHttpCloseHandle(hSession);

return response;

}
hungli
  • 1
  • 1
  • By fails to reach out, you have packet traces (eg Wireshark) showing that no attempt is made or do you have traces showing that the attempt is made and rejected? If you step through the code with a debugger do you see anything you didn't expect? You don't appear to check `hRequest`. `WinHttpOpenRequest` returns `NULL` on failure and nothing can ruin your day quite like a null pointer/handle. – user4581301 Sep 13 '22 at 01:03
  • Tactical note: Consider replacing `PBYTE response = new byte[responseLength + 1];` with `std::vector response(responseLength + 1);` using the `data` method when you need the buffer. `vector` is a [self-managing data buffer](https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii) and it's really hard to make it screw up. Much harder than `new[]` and `delete[]`. Though in this case `std::string` might be more appropriate. – user4581301 Sep 13 '22 at 01:08
  • Hi user4581301, thanks for the notes. I would prefer to use std::string if possible but I am not sure how to go about it, would it be possible to provide a small code example as I am still learning. Thank you – hungli Sep 13 '22 at 20:05
  • `std::string response(responseLength);` and then use it with `WinHttpReadData(hRequest, response.data(), responseLength, &readDataLength);` or `WinHttpReadData(hRequest, &response[0], responseLength, &readDataLength);` depending on the version of C++ you're using. You may have to `resize` the string according to `readDataLength` if things go a bit squirrelly. – user4581301 Sep 13 '22 at 20:12
  • Thank you user4581301, that is very helpful. I will play around with it and try to get it into a working function. Appreciate the help – hungli Sep 16 '22 at 20:03
  • Hi user4581301, I have managed to get the rest of it working after a lot of trial and error. I have updated the question to reflect it for a good reference for anyone else stumbling on this and would like to mark your answer as correct. I did get the error "E0289 no instance of constructor "std::basic_string<_Elem, _Traits, _Alloc>::basic_string [with _Elem=char, _Traits=std::char_traits, _Alloc=std::allocator]" matches the argument list" while converting to std::string. Do you have any idea why? – hungli Sep 21 '22 at 22:05
  • Also, I do not seem to be able to mark your question as the answer?? – hungli Sep 21 '22 at 22:07
  • It's good to answer your own question, but I strongly recommend you do it as an answer and not as an edit to the question. – user4581301 Sep 21 '22 at 22:07
  • Ah. I see the confusion now. I did not answer formally because I was just sort-of spit-balling what it should look like. I wasn't in a position to actually test and confirm an answer, so I just made an educated guess at how it should work and left it as a comment. Since you have been able to test and prove the solution, please formally answer the question, as this will be more useful to those who follow. – user4581301 Sep 21 '22 at 22:10

0 Answers0