microsoft / cpprestsdk

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.
Other
8.02k stars 1.66k forks source link

Help with translating modern Casablanca standard C++ code to a version that will work on Windows 2003 #91

Closed rambopierce closed 8 years ago

rambopierce commented 8 years ago

Hello Casablanca Team,

The partial code snippet below compiles and works perfectly in Visual Studio 2015 with the latest version of the Casablanca library with a target system of Windows 2012 64-bit. I can also target the DLL at Windows Server 2003 32-bit (OS Version 5.01), but the DLL encounters a memory access violation near the creation of the first parallel task. I’m suspecting that the code is trying to use a feature or features that were not available for this older OS.

Encountering the access violation, I found myself in the need of remote debugging tools, however my understanding is that the most current Visual Studio and corresponding remote debug tools for Windows 2003 is Visual Studio 2010 (pretty old). It seems that the most current version of Casablanca that supported Visual Studio 2010 is version 1.2. Referencing Casablanca 1.2 using VS 2010 this code will not compile:

credentials creds = credentials::credentials(mySailPointUsername.c_str(), mySailPointPassword.c_str());

   http_client_config config;

   config.set_credentials(creds);
   http_client client(mySailPointURI.c_str(), config);

   http_request req(methods::POST);
   req.set_request_uri(U("policies/checkPasswordPolicies"));
   req.headers().set_content_type(U("application/json"));
   req.headers().add(U("UserName"), mySailPointUsername.c_str());  // The credentials necessary to call Sailpoint's service
   req.headers().add(U("Password"), mySailPointPassword.c_str());

   // Create the JSON object to send with our request
   json::value obj;
   obj[U("id")] = json::value::string(wcUsername);  // The actual user's id and requested new password
   obj[U("password")] = json::value::string(wcPassword);

   req.set_body(obj);

   return client.request(req).then([](http_response response) -> pplx::task < json::value >
   {
          if (response.status_code() == status_codes::OK)
          {
                 return response.extract_json();
          }

          // Handle error cases, for now return empty json value... 
          return pplx::task_from_result(json::value());
   })
          .then([&result](pplx::task<json::value> previousTask)
   {
          try
          {
                 // Get the JSON value from the task and call the DisplayJSONValue method
                 try
                 {
                       json::value const & val = previousTask.get();
                       json::value value = val;
                       result = value[U("valid")].as_bool();

                 }
                 catch (...)
                 {
                 }
          }
          catch (...)
          {
          }
   });

The problematic line of code that will not compile is:

return client.request(req).then([](http_response response) -> pplx::task < json::value >

IntelliSense underlines the variable client and the pop up error says the following:

Error: No suitable user-defined conversion from “pplx::taskppx::details::_BadContinuationParamType” to “pplx::task” exists

I’m thinking to make this work on the older Server 2003 32-bit OS, the code needs to be restructured to do only a plain http request response and then follow that up with json parsing calls to parse the response. The request/response is very simple with the response being one Boolean field json formatted. However, the request does require Windows login creds to be passed to authenticate to the remote service.

Could one of you Casablanca experts possibly help me restructure this code snippet so that it will compile and work with the older Casablanca 1.2 version? You should recognize this code snippet as pretty straight forward as it closely resembles examples in modern versions of Casablanca. So far, studying the three samples included with 1.2, I am coming up blank and would appreciate some assistance.

Thanks, Richard

rambopierce commented 8 years ago

OK, not getting any response on the detailed original question, so I have a more basic question. I have continued the research and have made the Bingrequest sample included in Casablanca 1.2 work on Server 2003. However, slightly more complex code does not run on Server 2003 due to cpprest 1.2 relying on an entry point of httpapi.dll that did not exist in Server 2003; ref. https://msdn.microsoft.com/en-us/library/windows/desktop/aa814335%28v=vs.85%29.aspx Requirements Table: "Minimum supported server - Windows Server 2008.

The basic question is, was there any version of Casablanca that was fully supported under Windows Server 2003? If so, where can it be located?

If the answer is no, then does anyone have any recommendations on making a very simple REST/JSON request to a remote https service requiring authentication using Visual Studio 2010 C++ without Casablanca?

thanks, Richard

rambopierce commented 8 years ago

I have completed enough research to answer my own question and make recommendations here for reference in hopes that it may help someone who is stuck with supporting Server 2003 and older. The answer is parts of Casablanca 1.2 will work on Server 2003, but the developer can not be sure until testing at run time whether the code has included items (e.g. entry points into a system DLL) that did not exist and are not supported until Server 2008. For example, I was able to build the cpprest bingrequest sample and make it work on Server 2003, but more complex cpprest sample such as one that sets credentials in the request header will not work on Server 2003. See Microsoft tech note: https://msdn.microsoft.com/en-us/library/windows/desktop/aa814335%28v=vs.85%29.aspx , "Minimum supported server - Windows Server 2008".

For a simple (small payload) request, my recommendation is to shelve Casablanca and use Winhttp instead ( https://msdn.microsoft.com/en-us/library/windows/desktop/aa384081%28v=vs.85%29.aspx ). In my case the request and response were both less than 75 bytes and the web service responds very quickly. Additionally, I was not developing an interactive Windows interface so the need for all the parallel tasking and continuation mumbo jumbo complexity was not necessary. Then you can find a pure JSON library to construct the JSON request and parse the JSON response or you can use pure C and C++ for that. I chose the latter approach. By throwing out the dependency and static linking of Casablanca, I was also able to reduce the size of the produced custom DLL from 1,333KB to 124KB.

Casablanca is a rich library with a massive number of modules and feature set. So you would definitely want to use it for complex REST/JSON implementations as long as they are targeted at fairly current (supported) versions of Windows.

Richard