C++

Cómo proporcionar servicios RESTful para desarrolladores de C++

Sridhar Poduri

Descargar el ejemplo de código

En este artículo voy a mostrar cómo utilizar el resto de C++ SDK para construir una aplicación simple cliente basado en Windows que carga un archivo en Dropbox, junto con una clase C++ estándar que soporta OAuth.

El mundo de los dispositivos conectados mueve cada vez más en una mezcla heterogénea de aplicaciones nativas, aplicaciones Web y sitios Web conectar todos a una mezcla de nube - y no-servicios en la nube.Estas aplicaciones compartan y consuman datos a través de esta mezcolanza de dispositivos y servicios y proporcionan experiencias inmersivas, ricas para los usuarios finales. Estos usuarios utilizan cada vez más aplicaciones instaladas en sus dispositivos personales (smartphones, tablets, PCs y otros dispositivos similares).Los desarrolladores tienen la tarea de crear experiencias sin fisuras en las aplicaciones para facilitar el intercambio, organización y visualización de datos — y a los usuarios de deleite.

Aplicaciones están escritas en una variedad de lenguajes de programación.Algunos, tales como PHP, C# y Java, son por default Web-enabled y puede satisfacer las necesidades de algunos de los escenarios comunes para compartir y consumir datos.En otros casos, pueden utilizarse bibliotecas especializadas para realizar server-side computación, procesamiento y análisis y devolver una respuesta a la aplicación cliente.

En su papel, "Welcome to the Jungle" (bit.ly/uhfrzH), Herb Sutter inequívocamente describe el movimiento dominante a elástico, distributed computing como una evolución natural de la misma escala y rendimiento que las tendencias han impulsado multinúcleo y heterogéneo de computación en la corriente principal.

C++ es el lenguaje de programación preferido cuando código de multiplataforma compartido y rendimiento son consideraciones de diseño.Cuando se trata de cloud computing, aunque C++ aparentemente no entregar en todo su potencial.Una de las principales razones citadas para este aparente fracaso es la falta de una biblioteca multiplataforma de alto rendimiento, eficientemente escalable que permita un Desarrollador C++ a fin de integrar código C y C++ existente en el entorno de la nube.

El resto de C++ SDK (bit.ly/VI67I5) es la primera incursión de Microsoft que permite código nativo mover al medio de la nube.Su objetivo es proporcionar a los desarrolladores con herramientas y APIs que resolver los problemas cotidianos de código nativo en movimiento a la nube.La versión inicial es una librería client-side, cross-platform para servicios REST de acceso.El objetivo es hacer el resto de C++ SDK una biblioteca verdaderamente multiplataforma que puede desbloquear el verdadero potencial de código nativo en la nube.El resto de C++ SDK puede ser la base de la construcción de bibliotecas más especializadas como los apoyo a servicios de Windows Azure de autoría, y permitirá ligeros, alto rendimiento servicios Web escrita en código C++ portable sin necesidad de estructuras adicionales o runtimes que se desplieguen en la nube basado en máquinas virtuales (VMs).

¿Por qué elegir el resto de C++ SDK?

Para acceder a servicios REST, un Desarrollador C++ puede construir abstracciones sobre las API de C-estilo como WinINet o WinHTTP en Windows y APIs similares en otras plataformas.Ante tales opciones, es una pregunta que exige una respuesta inmediata: ¿Por qué un desarrollador debe elegir el resto de C++ SDK?

El resto de C++ SDK está diseñado y escrito desde cero utilizando C++ moderno.Las características incluyen:

  • Soporte para acceder a servicios basados en REST de código nativo en Windows Vista, Windows 7, Windows 8, Windows Store apps y Linux proporcionando enlaces asíncronos a HTTP, JSON, XML, URIs, y así sucesivamente.
  • Una extensión de Visual Studio SDK que permite el consumo del SDK de Windows Store aplicaciones.
  • Un modelo de programación consistente y potente para componer las operaciones asincrónicas basado en estándar C ++ 11 características.
  • Implementación de arroyos asincrónicas y almacenadores intermediarios de la corriente que pueden utilizarse para leer y escribir en secuencias de archivo o dispositivo.

Las clases de cliente de resto de C++

RESTO de C++ se basa en la premisa de C++ moderno y patrones de programación asincrónicos.Para mis experimentos con Dropbox, he utilizado la clase http_client, las clases de tarea y arroyos asincrónica.Analizaré cada uno.

La http_client clase como su nombre indica, se utiliza la clase http_client en el espacio de nombres web::http para configurar y mantener una conexión a un servicio HTTP Web.Si se crea una instancia de la http_client y un URI para el punto final del servicio, la instancia del objeto puede utilizarse para hacer peticiones en nombre del cliente.Asincronía es construido en la biblioteca C++ resto, así que las respuestas son devueltos por la biblioteca como tareas.

La clase de tarea una tarea representa una operación que potencialmente podría terminar cuando la función produciendo dijo tarea ya ha regresado.No todas las tareas de llegar a su fin, y tampoco no hay ninguna garantía en el orden de realización.Cada objeto de la tarea tiene una función miembro, is_done, que devuelve un bool.Cuando la tarea se ha quedado a la terminación, is_done devuelve true; de lo contrario, devuelve false.Una vez que una tarea se ejecuta a terminación — como se indica por el valor booleano devuelto por la función miembro de is_done — invocando la tarea de la función get devuelve el valor de la tarea.Tenga cuidado de llamar a la función get cuando la función is_done devuelve false.Hacerlo bloqueará el hilo y derrotar el propósito de construir patrones asincrónicos en código.

En lugar de comprobar continuamente para is_done, es mejor utilizar la función de entonces.Se basa en asociar una función de controlador a la tarea, similar a las promesas en extensiones de JavaScript para aplicaciones Windows Store.Debe ser fácilmente identificable para los desarrolladores que utilizan las tareas PPL, utilizadas para la programación de operaciones asincrónicas de tiempo de ejecución de Windows (WinRT).La función de controlador pasada a la función entonces debe tomar un argumento de tipo T o tarea <T>.Utilizando el argumento de la tarea de tipo <T> otorga un beneficio adicional: Es la única manera de atrapar excepciones planteadas por la propia operación de tarea!

Porque sólo después de completa la tarea, se invoca el controlador para la función entonces, llamando a la función get dentro del controlador es seguro y no bloquea el hilo.

Los arroyos asincrónico el resto de C++ biblioteca incluye un conjunto de clases auxiliares para leer y escribir objetos encapsulados como arroyos y almacenadores intermediarios de la corriente.Siguiendo el patrón y precedencia establecido en la biblioteca estándar de C++, arroyos y buffers en C++ resto separan la preocupación de dar formato a datos de entrada y salida de la preocupación de la escritura y la lectura de bytes o colecciones de bytes a y desde algún medio subyacente como un socket TCP, un archivo de disco o incluso un búfer de memoria.En cierto modo, arroyos están desconectados del medio subyacente utilizado para leer y escribir datos.La gran diferencia con las secuencias en el resto de C++ es que apoyan la lectura asincrónica y escribir las operaciones, a diferencia de clases estándar de C++, que están bloqueando.Como es el diseño con otros objetos del resto de C++, los métodos asincrónicos en las clases de corriente volver una tarea <T> en lugar de un valor.

Con este primer resto de C++, ahora es tiempo de pensar en la API REST de Dropbox.En el resto de este artículo, analizaré el acceso a la API REST de Dropbox usando C++ resto para cargar un archivo desde la máquina local, ejecutando Windows a la carpeta de Dropbox del usuario.

La API REST de Dropbox

Dropbox utiliza OAuth versión 1 para autenticar todas las peticiones de su API (bit.ly/ZJLP4o) y requiere que todas las solicitudes se realizan mediante SSL.Una búsqueda en Internet para una biblioteca estándar de C++ apoyando OAuth devuelve sólo la biblioteca OAuth, liboauth, y requiere ya sea abiertas­SSL (bit.ly/BpfcH) o servicios de seguridad de red (NSS) Mozilla (mzl.la/abU77o).Quería una clase de peso ligera, multiplataforma que soporta OAuth, así que me dispuse a construir uno para admitir la autenticación de Dropbox.

Para la gente curiosa, Brook Miles tiene una gran serie de posts sobre el acceso a Twitter OAuth en C++ de Win32 (bit.ly/137Ms6y).He construido sobre sus ideas básicas pero refactorizar el código para trabajar con las APIs de Dropbox, utilizando los tipos estándar de C++ admite C++ resto tanto como sea posible.Además, no pretendo usar WinINet o WinHTTP para realizar solicitudes de cualquier Web, como me ataban a la plataforma de Windows sólo y me obliga a usar una API de C-estilo.

Ahora analizaré construyendo una simple clase de C++ que soporta OAuth y una aplicación Win32 utilizando el resto de C++ que hace llamadas a Dropbox y carga un archivo en Dropbox.En un artículo de la carta recordativa, te voy a mostrar cómo utilizar C++ resto desde una aplicación Windows Store y subir archivos a Dropbox.

Antes de empezar escribiendo una aplicación que se puede acceder a Dropbox, necesito registrarlo con Dropbox.Esto se hace en el portal de la consola de aplicaciones de Dropbox (bit.ly/R14tjq).Había firmado para una cuenta gratuita de Dropbox y había registrado en el portal de la consola de aplicaciones creó una nueva aplicación haciendo clic en el botón "Crear app".

El proceso le pide que elija un nombre de aplicación, app tipo y un tipo de permiso.Entré en "test" y eligió el tipo de aplicación Core (ver figura 1).Los otros tipos de aplicación son Dropbox Chooser (útil para los desarrolladores de JavaScript) y sincronización API (mejor para iOS y Android desarrolladores).Finalmente, elegí el tipo de permiso como Dropbox completo, como esto me da la flexibilidad de la lectura, escritura y sincronización a cualquier carpeta de Dropbox versus una carpeta específica, que es proporcionada por el tipo de permiso de carpeta de la aplicación "sandbox".

Choices for Creating a Dropbox App
Figura 1 opciones para crear una aplicación de Dropbox

Al hacer clic en el botón "Crear app", Dropbox crea la aplicación y proporciona los datos necesarios para el acceso, como la clave de la aplicación, secreto de app y así sucesivamente, como se muestra en figura 2.Hice la nota de estos porque los necesito para realizar la autenticación programática y solicitudes de autorización mediante OAuth.

Choosing Dropbox App DetailsFigura 2 elegir los detalles de la aplicación de Dropbox

Una Simple clase de C++ multiplataforma para OAuth

Ahora para la verdadera acción.Como he dicho antes, yo quería escribir una clase de plataforma cruzada que podría usarse en Windows y Linux.La versión actual del resto SDK C++ no admite hacer peticiones HTTPS desde una caja Linux.Esto es una decepción, y he oído que pronto viene completo soporte HTTPS para Linux.La clase de C++ que discutir aquí debe trabajar a través de Windows y Linux sin grandes modificaciones.Para admitir la autenticación basada en OAuth para Dropbox, tenía que cumplir los siguientes requisitos principales (consulte el sitio de Dropbox para los requisitos completos):

  • Todas las solicitudes deben realizarse mediante SSL.Esto significa utilizar sólo HTTPS, versus HTTP.
  • OAuth requiere esa petición URIs y parámetros ser firmado usando encriptación HMAC-SHA1 o RSA-SHA1, o texto plano si la solicitud se realiza mediante SSL.

Con el fin de mis experimentos, me puse utilizando texto firma transporte y hacer peticiones via HTTPS.Construyendo un cifrado API que funciona en Windows y Linux es complejo y requiere mucho tiempo y vale la pena una exploración detallada más adelante.

Una vez me puse los requisitos, ya era hora de construir la clase.Me declaré a un alto nivel de nombres, convenientemente llamada autenticación y una clase dentro de llamado oAuth.En el nivel de espacio de nombres, que tenía unas cuerdas const declaradas por los extremos URI, la clave de la aplicación y secreto de aplicación para la aplicación obtenida en el proceso de registro de aplicación y algunos métodos auxiliares, como se muestra en figura 3.

Figura 3 el oAuth clase del edificio

// Dropbox consumer key and secret
const std::wstring consumerKey = L"Your app key";
const std::wstring consumerSecret = L"Your app secret";
// List of Dropbox authenticate, authorize, request and file upload URIs
const std::wstring DropBoxRequestTokenURI =
  L"https://api.dropbox.com/1/oauth/request_token";
const std::wstring DropBoxAuthorizeURI =
  L"https://www.dropbox.com/1/oauth/authorize";
const std::wstring DropBoxAccessTokenURI =
  L"https://api.dropbox.com/1/oauth/access_token";
const std::wstring DropBoxFileUploadURI =
  L"https://api-content.dropbox.com/1/files_put/dropbox/<your file name here>";
const std::wstring LocalFiletoUpload = L"Your local file goes here";

El soporte del protocolo OAuth todo está implementado en el método BuildSignedOAuthParameters de la clase oAuth. Este método acepta el endpoint URI, el tipo de método HTTP (GET, POST, PUT y así sucesivamente), la clave de la aplicación, secreto de app, token de petición y secreto token y construye una firma que debe enviarse a través de Dropbox con cada solicitud. Dropbox intenta construir la firma exacta en su extremo usando los parámetros pasados con la petición HTTPS y coinciden con las firmas generadas. Si las firmas no coinciden, devuelve un código de error HTTP.

Una firma es construida usando un número aleatorio — llamado un nonce en jerga OAuth — incluyendo un sello de tiempo para la solicitud, la versión del protocolo OAuth apoyado, el tipo de firma y más. El método devuelve una lista de todos los parámetros necesarios, ordenados por nombre y con la firma URL codificada (ver figura 4).

Figura 4 una firma de construcción

HTTPParameters BuildSignedOAuthParameters( 
  const HTTPParameters& requestParameters,
  const std::wstring& url,
  const std::wstring& httpMethod,
  const HTTPParameters* postParameters,
  const std::wstring& consumerKey,
  const std::wstring& consumerSecret,
  const std::wstring& requestToken = L"",
  const std::wstring& requestTokenSecret = L""
  )
{
  std::wstring timestamp = OAuthCreateTimestamp();
  std::wstring nonce = OAuthCreateNonce();          

  m_oauthParameters[L"oauth_timestamp"] = timestamp;
  m_oauthParameters[L"oauth_nonce"] = nonce;
  m_oauthParameters[L"oauth_version"] = L"1.0";
  m_oauthParameters[L"oauth_signature_method"] = L"PLAINTEXT";
  m_oauthParameters[L"oauth_consumer_key"] = consumerKey;

  // Add the request token if found
  if (!requestToken.empty())
  {
    m_oauthParameters[L"oauth_token"] = requestToken;
  }

            
  // Create a parameter list containing both oauth and original
  // parameters; this will be used to create the parameter signature
  HTTPParameters allParameters = requestParameters;
  if(Compare(httpMethod, L"POST", false) && postParameters)
  {
    allParameters.insert(postParameters->begin(), 
      postParameters->end());
  }
  allParameters.insert(m_oauthParameters.begin(), 
    m_oauthParameters.end());

  // Prepare a signature base, a carefully formatted string containing 
  // all of the necessary information needed to generate a valid signature
  std::wstring normalUrl = OAuthNormalizeUrl(url);
  std::wstring normalizedParameters = 
    OAuthNormalizeRequestParameters(allParameters);

  std::wstring signatureBase = 
    OAuthConcatenateRequestElements(httpMethod, 
    normalUrl, 
    normalizedParameters);

  // Obtain a signature and add it to header requestParameters
  std::wstring signature = OAuthCreateSignature(signatureBase, 
    consumerSecret,
    requestTokenSecret);

  m_oauthParameters[L"oauth_signature"] = UrlEncode(signature);

  return m_oauthParameters;
}

Con soporte para OAuth fuera del camino, escribí el código de cliente para acceder a archivos en Dropbox. Creé cuatro métodos:

  1. oAuthLoginAsync: Realiza el login a Dropbox usando la tecla de aplicación y secreto.
  2. AuthorizeDropBoxAccess: Inicia Internet Explorer y autoriza el acceso de la aplicación de Dropbox. Este método es específico de Windows y lanza Internet Explorer independientemente de si es el navegador por defecto.
  3. oAuthAcquireTokenAsync: Realiza la acción para adquirir el token de acceso real de Dropbox.
  4. UploadFileToDropBoxAsync: Carga un archivo desde el sistema local de almacenamiento en la nube Dropbox.

Cada una de estas operaciones se hace extremadamente fácil y transparente con las clases de cliente del resto de C++.

El código del cliente

¿Cómo cliente código escrito usando C++ moderno con tareas asincrónicas concuerdan contra el uso de una API de C-style? Es hora de averiguarlo.

Con un estilo C API como WinINet, hubiera tenido que hacer las siguientes llamadas de WinINet API para conseguir mi trabajo de aplicación:

  • Manualmente construir la cabecera de petición HTTP.
  • Llame al InternetCrackUrl para resolver el resto endpoint URL.
  • Llamar a InternetOpen y obtener un identificador para la conexión a Internet. Normalmente esto se devuelve como una instancia HINTERNET.
  • Una vez tuve una manija HINTERNET válida, hacer una llamada a Http­OpenRequest, que devuelve otra instancia de HINTERNET.
  • Hacer la siguiente llamada a HttpAddRequestHeaders, que devuelve un valor booleano que indica si se ha agregado exitosamente la información del encabezado de la solicitud HTTP.
  • Una vez que exitosamente completado todos los pasos anteriores con el manejo de error apropiado ponen en su lugar, hacer la llamada a HttpSendRequest, que envía la solicitud actual.
  • Al recibir una respuesta a la petición anterior, hacer otra llamada a InternetReadFile para leer la secuencia de respuesta.

Tenga en cuenta que todas las APIs anteriores son estilo C API sin apoyo para modernos idiomas de programación C++ como punteros compartidos, Lambda y asincrónicos patrones construidos en.

Para el código real utilizando el SDK de resto de C++. Figura 5 muestra la función oAuthLoginAsync, que realiza la operación de inicio de sesión a Dropbox y la función UploadFileToDropBoxAsync que carga un archivo desde el sistema local a Dropbox.

Figura 5 el oAuthLoginAsync función

HTTPParameters BuildSignedOAuthParameters(
  const HTTPParameters& requestParameters,
  const std::wstring& url,
  const std::wstring& httpMethod,
  const HTTPParameters* postParameters,
  const std::wstring& consumerKey,
  const std::wstring& consumerSecret,
  const std::wstring& requestToken = L"",
  const std::wstring& requestTokenSecret = L""
  )
{
  std::wstring timestamp = OAuthCreateTimestamp();
  std::wstring nonce = OAuthCreateNonce();                                         
  m_oauthParameters[L"oauth_timestamp"] = timestamp;
  m_oauthParameters[L"oauth_nonce"] = nonce;
  m_oauthParameters[L"oauth_version"] = L"1.0";
  m_oauthParameters[L"oauth_signature_method"] = L"PLAINTEXT";
  m_oauthParameters[L"oauth_consumer_key"] = consumerKey;
  // Add the request token if found
  if (!requestToken.empty())
  {
    m_oauthParameters[L"oauth_token"] = requestToken;
  }
  // Create a parameter list containing both oauth and original
  // parameters; this will be used to create the parameter signature
  HTTPParameters allParameters = requestParameters;
  if(Compare(httpMethod, L"POST", false) && postParameters)
  {
    allParameters.insert(postParameters->begin(), 
      postParameters->end());
  }
  allParameters.insert(m_oauthParameters.begin(), 
    m_oauthParameters.end());
  // Prepare a signature base, a carefully formatted string containing
  // all of the necessary information needed to generate a valid signature
  std::wstring normalUrl = OAuthNormalizeUrl(url);
  std::wstring normalizedParameters =
    OAuthNormalizeRequestParameters(allParameters);
  std::wstring signatureBase =
    OAuthConcatenateRequestElements(httpMethod,
    normalUrl,
    normalizedParameters);
  // Obtain a signature and add it to header requestParameters
  std::wstring signature = OAuthCreateSignature(signatureBase,
    consumerSecret,
    requestTokenSecret);
  m_oauthParameters[L"oauth_signature"] = UrlEncode(signature);
  return m_oauthParameters;
}
task<void> oAuthLoginAsync(std::shared_ptr<app_credentials>& creds)
{           
  uri url(DropBoxRequestTokenURI);
  std::shared_ptr<oAuth> oAuthObj = std::make_shared<oAuth>();
  auto signatureParams =
   oAuthObj->CreateOAuthSignedParameters(url.to_string(),
   L"GET",
   NULL,
   consumerKey,
   consumerSecret
   );
  std::wstring sb = oAuthObj->OAuthBuildSignedHeaders(url);
  http_client client(sb);   
  // Make the request and asynchronously process the response
  return client.request(methods::GET)
    .then([&creds](http_response response)
  {                                          
    if(response.status_code() != status_codes::OK)
    {                             
      // Handle error cases ...
return pplx::task_from_result();
    }
    // Perform actions here reading from the response stream ...
// in this example, parse the response body and
    // extract the token and token secret
    istream bodyStream = response.body();
    container_buffer<std::string> inStringBuffer;
    return bodyStream.read_to_end(inStringBuffer)
      .then([inStringBuffer, &creds](pplx::task<size_t> previousTask)
    {
      const std::string &text = inStringBuffer.collection();
      // Convert the response text to a wide-character
      // string and then extract the tokens
      std::wstring_convert
        <std::codecvt_utf8_utf16<wchar_t>, wchar_t> utf16conv;
      std::wostringstream ss;
      std::vector<std::wstring> parts;
      ss << utf16conv.from_bytes(text.c_str()) << std::endl;
      Split(ss.str(), parts, '&', false);
      unsigned pos = parts[1].find('=');
      std::wstring token = parts[1].substr(pos + 1, 16);
      pos = parts[0].find('=');
      std::wstring tokenSecret = parts[0].substr(pos + 1);
      creds->set_Token(token);
      creds->set_TokenSecret(tokenSecret);
    });
  });
}

En la función oAuthLoginAsync, primero construir una instancia URI de una representación de cadena del extremo Login URI. A continuación, crear una instancia de la clase oAuth y llamar a la función miembro CreateOAuthSignedParameters, que construye un mapa que contiene todos los parámetros de solicitud necesarios del OAuth. Finalmente, firmo las cabeceras llamando a la función miembro de OAuthBuildSignedHeaders. Firma de cabeceras es obligatorio según la especificación de OAuth. Ahora comienza la comunicación HTTP. Sólo necesito crear una instancia de un http_client y se pasa la cadena de solicitud firmada. Dropbox utilizará la cadena de petición e información del encabezado y el intento de construir la misma solicitud de cadena en el lado del servidor y compararlo contra lo enviaré como parte de la solicitud HTTP. Si coinciden las cadenas, tengo un código de retorno de éxito; de lo contrario, me da un error.

Que comience el proceso de comunicación mediante la creación de una instancia de la clase http_client y entonces llamar a la función miembro de petición. Especificar el método HTTP como llegar. Cuando el método de petición finaliza la ejecución, devuelve un objeto http_response que utilizo para analizar y extraer el token y token secreto, que se almacenan en la instancia de la clase app_credentials. La muestra debe enviarse junto con todas las solicitudes posteriores de API a Dropbox.

La función UploadFileToDropBoxAsync se muestra en la figura 6. Sigue un patrón similar a la función oAuthLoginAsync hasta que construya las cabeceras OAuth firmadas. Una vez que crear la información del encabezado, crear una tarea que lee un archivo desde el sistema de archivos local en un objeto file_stream y establece el objeto file_stream como el cuerpo de la solicitud HTTP. Entonces puedo crear una instancia de una clase de http_client y establece la instancia de solicitud, que contiene el contenido de file_stream como el cuerpo, y poner la petición PUT. Al finalizar, tengo una tarea que contiene un http_response que puede ser analizado para el éxito o el fracaso. Realmente es así de sencillo.

Figura 6 la función UploadFileToDropBoxAsync

task<void> UploadFileToDropBoxAsync(std::shared_ptr<app_credentials>& creds)
{
  using concurrency::streams::file_stream;
  using concurrency::streams::basic_istream;
  uri url(DropBoxFileUploadURI);
  std::shared_ptr<oAuth> oAuthObj = std::make_shared<oAuth>();
  auto signatureParams =     
    oAuthObj->CreateOAuthSignedParameters(url.to_string(),
    L"PUT",
    NULL,
    consumerKey,
    consumerSecret,
    creds->Token(),
    creds->TokenSecret()
    );
  std::wstring sb = oAuthObj->OAuthBuildSignedHeaders(url);
  return file_stream<unsigned char>::open_istream(LocalFiletoUpload)
    .then([sb, url](pplx::task<basic_istream<unsigned char>> previousTask)
  {
    try
    {
      auto fileStream = previousTask.get();
      // Get the content length, which is used to set the
      // Content-Length property
      fileStream.seek(0, std::ios::end);
      auto length = static_cast<size_t>(fileStream.tell());
      fileStream.seek(0, 0);
      // Make HTTP request with the file stream as the body
      http_request req;                                    
      http_client client(sb);                
      req.set_body(fileStream, length);
      req.set_method(methods::PUT);
      return client.request(req)
        .then([fileStream](pplx::task<http_response> previousTask)
      {
        fileStream.close();
        std::wostringstream ss;
        try
        {
          auto response = previousTask.get();
          auto body = response.body();                  
          ss << L"Server returned returned status code "
            << response.status_code() << L"."
            << std::endl;      
          std::wcout << ss.str();
        }
        catch (const http_exception& e)
        {
          ss << e.what() << std::endl;
             }
        std::wcout << ss.str();
      });
      }                       
      catch (const std::system_error& e)
      {
        std::wostringstream ss;
        ss << e.what() << std::endl;
        std::wcout << ss.str();
        // Return an empty task
        return pplx::task_from_result();
      }
  });
}

En comparación con utilizando un API de C-estilo para la comunicación de la Web o bajando la ruta de apoyo mediante plataforma -­API específicas como WinINet, el código escrito usando C++ moderno es más concisa, legible y elegante. De hecho, todos los detalles de implementación de bajo nivel se abstraen de la interfaz pública de la biblioteca. El resto de C++ SDK se basa en la promesa de C++ moderno y aplica los mismos principios de diseño para la Comunicación RESTful. El resultado final es una biblioteca muy bien diseñada y modelada utilizando C++ moderno que hace que el proceso de construcción de aplicaciones conectadas fáciles y transparente.

Siguiente: Una aplicación de Windows Store

En este artículo he explorado cómo construir una aplicación simple cliente basados en Windows usando el SDK de resto de C++ que carga un archivo en Dropbox. En el camino, también he hablado de construir una clase C++ estándar que soporta OAuth. En un artículo de la carta recordativa, te voy a mostrar cómo construir una aplicación de Windows Store utilizando el SDK de resto de C++. ¡ Estad atentos!

Sridhar Poduri es un administrador de programa en el equipo de Windows de Microsoft. Un aficionado de C++ y autor del libro, "Moderno C++ y tienda de aplicaciones de Windows" (Sridhar Poduri, 2013), blogs regularmente sobre C++ y el tiempo de ejecución de Windows en sridharpoduri.com.

Gracias al siguiente experto técnico por su ayuda en la revisión de este artículo: Artur Laksberg (Microsoft)
Artur Laksberg es una pista senior desarrollo trabajando en el equipo de resto de C++ SDK.