//  [c]
error_t httpClientFormatAuthorizationField(HttpClientContext *context)
{
   size_t n;
   char_t *p;
   HttpClientAuthParams *authParams;

   //Make sure the buffer contains a valid HTTP request
   if(context->bufferLen < 2 || context->bufferLen > HTTP_CLIENT_BUFFER_SIZE)
      return ERROR_INVALID_SYNTAX;

   //Point to the HTTP authentication parameters
   authParams = &context->authParams;

#if (HTTP_CLIENT_BASIC_AUTH_SUPPORT == ENABLED)
   //Basic authentication scheme?
   if(authParams->mode == HTTP_AUTH_MODE_BASIC)
   {
      size_t k;
      size_t m;

      //Calculate the length of the username and password
      n = osStrlen(authParams->username) + osStrlen(authParams->password);

      //Make sure the buffer is large enough
      if((context->bufferLen + n + 22) > HTTP_CLIENT_BUFFER_SIZE)
         return ERROR_BUFFER_OVERFLOW;

      //Point to the buffer where to format the Authorization header field
      p = context->buffer + context->bufferLen - 2;

      //Format Authorization header field
      n = osSprintf(p, "Authorization: Basic ");

      //The client sends the username and password, separated by a single
      //colon character, within a Base64-encoded string in the credentials
      m = osSprintf(p + n, "%s:%s", authParams->username, authParams->password);

      //The first pass calculates the length of the Base64-encoded string
      base64Encode(p + n, m, NULL, &k);

      //Make sure the buffer is large enough
      if((context->bufferLen + n + k) > HTTP_CLIENT_BUFFER_SIZE)
         return ERROR_BUFFER_OVERFLOW;

      //The second pass encodes the string using Base64
      base64Encode(p + n, m, p + n, &k);
      //Update the total length of the header field
      n += k;

      //Make sure the buffer is large enough
      if((context->bufferLen + n + 2) > HTTP_CLIENT_BUFFER_SIZE)
         return ERROR_BUFFER_OVERFLOW;

      //Terminate the header field with a CRLF sequence
      osSprintf(p + n, "\r\n\r\n");

      //Adjust the length of the request header
      context->bufferLen = context->bufferLen + n + 2;
   }
   else
#endif
#if (HTTP_CLIENT_DIGEST_AUTH_SUPPORT == ENABLED)
   //Digest authentication scheme?
   if(authParams->mode == HTTP_AUTH_MODE_DIGEST)
   {
      error_t error;
      const char_t *q;
      const char_t *uri;
      size_t uriLen;
      char_t response[HTTP_CLIENT_MAX_RESPONSE_LEN + 1];

      //Properly terminate the string with a NULL character
      context->buffer[context->bufferLen] = '\0';

      //The Request-Line begins with a method token
      q = osStrchr(context->buffer, ' ');
      //Any parsing error?
      if(q == NULL)
         return ERROR_INVALID_SYNTAX;

      //The method token is followed by the Request-URI
      uri = q + 1;

      //Point to the end of the Request-URI
      q = osStrchr(uri, ' ');
      //Any parsing error?
      if(q == NULL)
         return ERROR_INVALID_SYNTAX;

      //Compute the length of the current URI
      uriLen = q - uri;

      //Check quality of protection
      if(authParams->qop == HTTP_AUTH_QOP_AUTH ||
         authParams->qop == HTTP_AUTH_QOP_AUTH_INT)
      {
         //Make sure that a valid callback function has been registered
         if(context->randCallback == NULL)
            return ERROR_PRNG_NOT_READY;

         //A cryptographically strong random number generator must be used to
         //generate the cnonce
         error = context->randCallback(authParams->cnonce, HTTP_CLIENT_CNONCE_SIZE);
         //Any error to report?
         if(error)
            return error;

         //Convert the byte array to hex string
         httpEncodeHexString(authParams->cnonce, HTTP_CLIENT_CNONCE_SIZE,
            authParams->cnonce);

         //Count of the number of requests (including the current request)
         //that the client has sent with the nonce value in this request
         authParams->nc++;
      }

      //Perform digest operation
      error = httpClientComputeDigest(authParams, context->method,
         osStrlen(context->method), uri, uriLen, response);
      //Any error to report?
      if(error)
         return error;

      //Determine the length of the header field
      n = osStrlen(authParams->username) + osStrlen(authParams->realm) +
         uriLen + osStrlen(authParams->nonce) + osStrlen(authParams->cnonce) +
         osStrlen(response) + osStrlen(authParams->opaque);

      //Make sure the buffer is large enough
      if((context->bufferLen + n + 121) > HTTP_CLIENT_BUFFER_SIZE)
         return ERROR_BUFFER_OVERFLOW;

      //Point to the buffer where to format the Authorization header field
      p = context->buffer + context->bufferLen - 2;

      //Format Authorization header field
      n = osSprintf(p, "Authorization: Digest ");

      //Format username and realm parameter
      n += osSprintf(p + n, "username=\"%s\", ", authParams->username);
      n += osSprintf(p + n, "realm=\"%s\", ", authParams->realm);

      //Format uri parameter
      n += osSprintf(p + n, "uri=\"");
      osStrncpy(p + n, uri, uriLen);
      n += uriLen;
      n += osSprintf(p + n, "\", ");

      //Format nonce parameter
      n += osSprintf(p + n, "nonce=\"%s\", ", authParams->nonce);

      //Check quality of protection
      if(authParams->qop == HTTP_AUTH_QOP_AUTH)
      {
         //Format qop, nc, cnonce parameters
         n += osSprintf(p + n, "qop=auth, ");
         n += osSprintf(p + n, "nc=%08x, ", authParams->nc);
         n += osSprintf(p + n, "cnonce=\"%s\", ", authParams->cnonce);
      }

      //Format response parameter
      n += osSprintf(p + n, "response=\"%s\"", response);

      //The opaque parameter should be returned by the client unchanged in
      //the Authorization header field of subsequent requests
      if(authParams->opaque[0] != '\0')
      {
         //Format opaque parameter
         n += osSprintf(p + n, ", opaque=\"%s\"", authParams->opaque);
      }

      //Terminate the header field with a CRLF sequence
      osSprintf(p + n, "\r\n\r\n");

      //Adjust the length of the request header
      context->bufferLen = context->bufferLen + n + 2;
   }
   else
#endif
   //Unknown authentication scheme?
   {
      //Just for sanity
   }

   //Successful processing
   return NO_ERROR;
}