MFC C++ HTTP Post

I had this question after viewing How to use OpenRequest() of CHttpConnection?.

I need to send a POST to Google.Vision server, using MFC and c++. The code is the following:

        CString strHeaders = _T("Content-Type: application/x-www-form-urlencoded");
      CString strFormData = "{'requests':[{'image':{'source':{'imageUri':'https://www.galileo2000.it/download/1.jpg'}},'features':[{'type':'FACE_DETECTION'}]}]}";

      CInternetSession session;
      CHttpConnection *pConnection = session.GetHttpConnection(_T("https://vision.googleapis.com/v1/images:annotate?key=MY_GOOGLE_API_KEY"));
      CHttpFile *pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST,_T("https://vision.googleapis.com"));
      BOOL result = pFile->SendRequest(strHeaders, (LPVOID)(LPCTSTR)strFormData,strFormData.GetLength());


Actually I am not very fond on these topics, so I got the above code in Internet. But I successfully wrote a WebService in C#, which works. The strFormData is the same I use in the WebService, so it should be correct. The main doubt is the second parameter of the OpenRequest. Of course I get an error "Impossible to resolve the server or the address". (Unluckily the message is in Italian and I translated back to English, so the actual error message could be slightly different).
Thanks
Giovanni PoleseAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

David FavorLinux/LXD/WordPress/Hosting SavantCommented:
The problem looks to be here...

CString strFormData = "{'requests':[{'image':{'source':{'imageUri':'https://www.galileo2000.it/download/1.jpg'}},'features' [{'type':'FACE_DETECTION'}]}]}";

Open in new window


The data your passing looks like JSON.

Tip: If your data is JSON, then use https://jsonformatter.org/ to verify your JSON is well formed, then pass the well formed JSON to your call.
Giovanni PoleseAuthor Commented:
Hi. Thanks for answering. Yes, the request is a Json, but it is well formed. At least, as I wrote, other programs I did, work with such a string (I just barely copied the string, so I have few doubts on it). The problem is that I don't figure out the meaning of the "Action" parameter of the OpenRequest (namely the second parameter). In documentation it is written that it may be a file, etc. but I don't have anything like a file. Moreover, in other examples, this second parameter is part of the Url. I am completely confused on it. The problem is what to write in OpenRequest, after the HTTP_VERB. To further explain, I reproduce the part of the Microsoft documentation. My problem is what is pstrObjectName.

CHttpFile* OpenRequest(
    LPCTSTR pstrVerb,
    LPCTSTR pstrObjectName,
    LPCTSTR pstrReferer = NULL,
    DWORD_PTR dwContext = 1,
    LPCTSTR* ppstrAcceptTypes = NULL,
    LPCTSTR pstrVersion = NULL,
    DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT);

CHttpFile* OpenRequest(
    int nVerb,
    LPCTSTR pstrObjectName,
    LPCTSTR pstrReferer = NULL,
    DWORD_PTR dwContext = 1,
    LPCTSTR* ppstrAcceptTypes = NULL,
    LPCTSTR pstrVersion = NULL,
    DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT);

Thanks
David FavorLinux/LXD/WordPress/Hosting SavantCommented:
The JSON you posted is broken.

Run your JSON through https://jsonformatter.org/ + fix formatting, till you get a clean validation.

Tip: Just because you copied this JSON, doesn't mean it's well formed.
HTML5 and CSS3 Fundamentals

Build a website from the ground up by first learning the fundamentals of HTML5 and CSS3, the two popular programming languages used to present content online. HTML deals with fonts, colors, graphics, and hyperlinks, while CSS describes how HTML elements are to be displayed.

Giovanni PoleseAuthor Commented:
Hi. Thanks for your patience. The problem on Json may exist, as you say, but then I have two problems.. As a matter of fact, the string that I wrote is not validated by the formatter that you suggest. The reason is that the correct Json contains quotes " that cannot be written in a CString object. That's why I substituted the internal " with ' in the string, and, obviously, the formatter says that it is wrong. But, this was just a low level temptative. Actually, to embed a " in a CString, in what I know, I must write \" instead of the single ". Therefore the CString representing the Json, becomes: (first is commented because impossible in C++ MFC)

//CString strFormData = "{"requests":[{"image":{"source":{"imageUri":      "https:://www.galileo2000.it/download/1.jpg"}},"features":[      {"type":"FACE_DETECTION","maxResults" : 20}      ]}]}";

      CString strFormData = "{\"requests\":[{\"image\":{\"source\":{\"imageUri\":      \"https:://www.galileo2000.it/download/1.jpg\"}},\"features\":[      {\"type\":\"FACE_DETECTION\",\"maxResults\" : 20}      ]}]}";

And, of course, your formatter says that it is wrong. Then I don't know how to proceed. Please note that, in C#, the following code works (no question about, I can prove it):

var uri = "https://vision.googleapis.com/v1/images:annotate?key=" + MY_GOOGLE_KEY;
               
                client.Headers.Add("Content-Type:application/json");
                client.Headers.Add("Accept:application/json");
                string Req = "{'requests':[{'image':{'source':{'imageUri':'https://www.galileo2000.it/download/1.jpg'}},'features':[{'type':'FACE_DETECTION'}]}]}";
                var response = client.UploadString(uri, "POST", Req);//
                return response;

That's why I "copied" the Req string: first I tried in C# and saw that it was working. Nevertheless, the Json validator says that that string is wrong. The reason is the presence of the ', that, evidently, is valid in C# and not in C++ (unmanaged). The difference could be just this.
Thanks for your patience.
Giovanni PoleseAuthor Commented:
Sorry. I wrote: "The reason is the presence of the ', that, evidently, is valid in C# and not in C++ (unmanaged)" and this is not correct. As a matter of fact, the ' is valid either in C# or in C++ and that's why I used the CString with ' and not with \". But, either with ' or with \" the Json validator refuses the string. I repeat: the C# code works, despite the validator says that the string is wrong. This is the reason why I don't think that the problem is the JSon. By the way, in C++, putting the \" for the single " produces exactly the requested valid string.
Giovanni PoleseAuthor Commented:
Hi. By the way i solved the problem using curl library. The json string may have, for the internal fields, the (apex) ' instead of (quote) ", and it works in my case. Thanks again.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.