docs: @Override
      public void sign(InternalRequest request, BceCredentials credentials, SignOptions options) {
          checkNotNull(request, "request should not be null.");
  
          if (credentials == null) {
              return;
          }
  
          if (options == null) {
              if (request.getSignOptions() != null) {
                  options = request.getSignOptions();
              } else {
                  options = SignOptions.DEFAULT;
              }
          }
  
          String accessKeyId = credentials.getAccessKeyId();
          String secretAccessKey = credentials.getSecretKey();
  
          request.addHeader(Headers.HOST, HttpUtils.generateHostHeader(request.getUri()));
          if (credentials instanceof BceSessionCredentials) {
              request.addHeader(Headers.BCE_SECURITY_TOKEN, ((BceSessionCredentials) credentials).getSessionToken());
          }
  
          Date timestamp = options.getTimestamp();
          if (timestamp == null) {
              timestamp = new Date();
          }
  
          String authString =
                  BceV1Signer.BCE_AUTH_VERSION + "/" + accessKeyId + "/"
                          + DateUtils.formatAlternateIso8601Date(timestamp) + "/" + options.getExpirationInSeconds();
  
          String signingKey = this.sha256Hex(secretAccessKey, authString);
          // Formatting the URL with signing protocol.
          String canonicalURI = this.getCanonicalURIPath(request.getUri().getPath());
          // Formatting the query string with signing protocol.
          String canonicalQueryString = HttpUtils.getCanonicalQueryString(request.getParameters(), true);
          // Sorted the headers should be signed from the request.
          SortedMap<String, String> headersToSign =
                  this.getHeadersToSign(request.getHeaders(), options.getHeadersToSign());
          // Formatting the headers from the request based on signing protocol.
          String canonicalHeader = this.getCanonicalHeaders(headersToSign);
          String signedHeaders = "";
          if (options.getHeadersToSign() != null) {
              signedHeaders = BceV1Signer.signedHeaderStringJoiner.join(headersToSign.keySet());
              signedHeaders = signedHeaders.trim().toLowerCase();
          }
  
          String canonicalRequest =
                  request.getHttpMethod() + "\n" + canonicalURI + "\n" + canonicalQueryString + "\n" + canonicalHeader;
  
          // Signing the canonical request using key with sha-256 algorithm.
          String signature = this.sha256Hex(signingKey, canonicalRequest);
  
          String authorizationHeader = authString + "/" + signedHeaders + "/" + signature;
  
          logger.debug("CanonicalRequest:{}\tAuthorization:{}", canonicalRequest.replace("\n", "[\\n]"),
                  authorizationHeader);
  
          request.addHeader(Headers.AUTHORIZATION, authorizationHeader);
      }