code: public QiniuMKFileResponseData makeFile(int fileTotalSize, List<String> uploadFileCtxs, int retry)
            throws Exception {
      try {
        String endPoint = String.format(QINIU_MKFILE_EP, this.uploadUrl, fileTotalSize,
                Base64.encodeToString(this.fileKey.getBytes(), Base64.URL_SAFE | Base64.NO_WRAP));
        final String joinedFileCtx = StringUtil.join(",", uploadFileCtxs);
        Request.Builder builder = new Request.Builder();
        builder.url(endPoint);
        builder.addHeader(HEAD_CONTENT_TYPE, TEXT_CONTENT_TYPE);
        builder.addHeader(HEAD_CONTENT_LENGTH, String.valueOf(joinedFileCtx.length()));
        builder.addHeader(HEAD_AUTHORIZATION, "UpToken " + this.uploadToken);
  
        LOGGER.d("makeFile to qiniu with uploadUrl: " + endPoint);
        builder = builder.post(RequestBody.create(MediaType.parse(TEXT_CONTENT_TYPE), joinedFileCtx));
        Response response = this.client.newCall(builder.build()).execute();
        return parseQiniuResponse(response, QiniuMKFileResponseData.class);
      } catch (Exception e) {
        if (retry-- > 0) {
          return makeFile(fileTotalSize, uploadFileCtxs, retry);
        } else {
          LOGGER.w(e);
        }
      }
      return null;
    }
docs: REST API
  POST /mkfile/<fileSize>/key/<encodedKey>/mimeType/<encodedMimeType>/x:user-var/<encodedUserVars> HTTP/1.1
  Host:           <UpHost>
  Content-Type:   text/plain
  Content-Length: <ctxListSize>
  Authorization:  UpToken <UploadToken>
  <ctxList>
  
  Request params:
  - fileSize
  - encodeKey
  - encodedMimeType
  - encodedUserVars
  
  Response:
  {
  "hash": "<ContentHash  string>",
  "key":  "<Key          string>"
  }
  
  @param fileTotalSize
  @param uploadFileCtxs
  @param retry
  @return
  @throws Exception