public void sendApiRequestAsync(
            Dictionary <object, object> context, RequestInputModel paramBean, ResponseCallBack callback)
        {
            string validate = paramBean != null?paramBean.validateParam() : "";

            EvnContext evnContext  = (EvnContext)context[QSConstant.EVN_CONTEXT_KEY];
            string     evnValidate = evnContext.validateParam();

            if (!QSStringUtil.isEmpty(validate) || !QSStringUtil.isEmpty(evnValidate))
            {
                if (QSStringUtil.isEmpty(validate))
                {
                    validate = evnValidate;
                }
                OutputModel Out = QSParamInvokeUtil.getOutputModel(callback);
                QSHttpRequestClient.fillResponseCallbackModel(QSConstant.REQUEST_ERROR_CODE, validate, Out);
                callback.onAPIResponse(Out);
            }
            else
            {
                HttpWebRequest request = buildRequest(context, paramBean);
                QSHttpRequestClient.getInstance()
                .requestActionAsync(request, evnContext.isSafeOkHttp(), callback);
            }
        }
        public OutputModel sendApiRequest(Dictionary <object, object> context, RequestInputModel paramBean, Type outputClass)
        {
            string validate = paramBean != null?paramBean.validateParam() : "";

            EvnContext evnContext  = (EvnContext)context[QSConstant.EVN_CONTEXT_KEY];
            string     evnValidate = evnContext.validateParam();

            if (!QSStringUtil.isEmpty(validate) || !QSStringUtil.isEmpty(evnValidate))
            {
                if (QSStringUtil.isEmpty(validate))
                {
                    validate = evnValidate;
                }
                try
                {
                    OutputModel model = (OutputModel)Activator.CreateInstance(outputClass);
                    QSHttpRequestClient.fillResponseCallbackModel(QSConstant.REQUEST_ERROR_CODE, validate, model);
                    return(model);
                }
                catch (Exception e)
                {
                    logger.Fatal(e.Message);
                    throw new QSException(e.Message);
                }
            }
            else
            {
                HttpWebRequest request = buildRequest(context, paramBean);
                return(QSHttpRequestClient.getInstance().requestAction(request, evnContext.isSafeOkHttp(), outputClass));
            }
        }
        public void sendApiRequestAsync(String requestUrl, Dictionary <object, object> context, ResponseCallBack callback)
        {
            EvnContext     evnContext = (EvnContext)context[QSConstant.EVN_CONTEXT_KEY];
            HttpWebRequest request    = QSHttpRequestClient.getInstance().buildUrlRequest(requestUrl);

            QSHttpRequestClient.getInstance().requestActionAsync(request, evnContext.isSafeOkHttp(), callback);
        }
        private Dictionary <object, object> initHeadContentMd5(String requestApi, Dictionary <object, object> paramsBody, Dictionary <object, object> paramsHead)
        {
            if (QSConstant.PARAM_KEY_REQUEST_API_DELETE_MULTIPART.Equals(requestApi))
            {
                if (paramsBody.Count > 0)
                {
                    Object bodyContent = null;
                    if (paramsBody.ContainsKey("BodyInputFileStream"))
                    {
                        FileStream   fs = (FileStream)paramsBody["BodyInputFileStream"];
                        StreamReader sr = new StreamReader(fs);
                        bodyContent = sr.ReadToEnd();
                    }
                    else
                    {
                        bodyContent = QSHttpRequestClient.getInstance().getBodyContent(paramsBody);
                    }
                    try
                    {
                        MD5    md5        = new MD5CryptoServiceProvider();
                        byte[] output     = md5.ComputeHash(Encoding.Default.GetBytes(bodyContent.ToString()));
                        string contentMD5 = System.Text.Encoding.Default.GetString(output);
                        paramsHead.Add(QSConstant.PARAM_KEY_CONTENT_MD5, contentMD5);
                    }
                    catch (Exception e)
                    {
                        throw new QSException(e.Message);
                    }
                }
            }

            return(paramsHead);
        }
        /*private static HttpClient getUnsafeOkHttpClient()
         * {
         *  try
         *  {
         *  // Create a trust manager that does not validate certificate chains
         *      ServicePointManager.SecurityProtocol=SecurityProtocolType.Ssl3;
         *  // Install the all-trusting trust manager
         *
         *      SSLContext sslContext = SSLContext.getInstance("SSL");
         *  sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
         *  // Create an ssl socket factory with our all-trusting manager
         *  final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
         *
         *  OkHttpClient.Builder builder =
         *          new OkHttpClient.Builder()
         *                  .connectTimeout(
         *                          QSConstant.HTTPCLIENT_CONNECTION_TIME_OUT, TimeUnit.SECONDS)
         *                  .readTimeout(QSConstant.HTTPCLIENT_READ_TIME_OUT, TimeUnit.SECONDS)
         *                  .writeTimeout(QSConstant.HTTPCLIENT_WRITE_TIME_OUT, TimeUnit.SECONDS);
         *  builder.sslSocketFactory(sslSocketFactory);
         *  builder.hostnameVerifier(
         *          new HostnameVerifier() {
         *              @Override
         *              public boolean verify(String hostname, SSLSession session) {
         *                  return true;
         *              }
         *          });
         *
         *  OkHttpClient okHttpClient = builder.build();
         *  return okHttpClient;
         * } catch (Exception e) {
         *  logger.log(Level.SEVERE, e.getMessage());
         *  throw new RuntimeException(e);
         * }
         * }*/

        public static QSHttpRequestClient getInstance()
        {
            if (ins == null)
            {
                ins = new QSHttpRequestClient();
            }
            return(ins);
        }
        public OutputModel sendApiRequest(
            string requestUrl, Dictionary <object, object> context, Type outputClass)
        {
            EvnContext     evnContext = (EvnContext)context[QSConstant.EVN_CONTEXT_KEY];
            HttpWebRequest request    = QSHttpRequestClient.getInstance().buildUrlRequest(requestUrl);

            return(QSHttpRequestClient.getInstance()
                   .requestAction(request, evnContext.isSafeOkHttp(), outputClass));
        }
        private HttpWebRequest buildRequest(Dictionary <object, object> context, RequestInputModel Params)
        {
            EvnContext evnContext = (EvnContext)context[QSConstant.EVN_CONTEXT_KEY];
            string     zone       = (string)context[QSConstant.PARAM_KEY_REQUEST_ZONE];

            Dictionary <object, object> paramsQuery   = QSParamInvokeUtil.getRequestParams(Params, QSConstant.PARAM_TYPE_QUERY);
            Dictionary <object, object> paramsBody    = QSParamInvokeUtil.getRequestParams(Params, QSConstant.PARAM_TYPE_BODY);
            Dictionary <object, object> paramsHeaders = QSParamInvokeUtil.getRequestParams(Params, QSConstant.PARAM_TYPE_HEADER);

            if (context.ContainsKey(QSConstant.PARAM_KEY_USER_AGENT))
            {
                paramsHeaders.Add(QSConstant.PARAM_KEY_USER_AGENT, context[QSConstant.PARAM_KEY_USER_AGENT]);
            }

            String requestApi = (String)context[QSConstant.PARAM_KEY_REQUEST_APINAME];

            //string FileBody = GetBodyFile(context[QSConstant.PARAM_KEY_OBJECT_NAME].ToString()).ToString();
            paramsHeaders = initHeadContentMd5(requestApi, paramsBody, paramsHeaders);

            string method      = (string)context[QSConstant.PARAM_KEY_REQUEST_METHOD];
            string bucketName  = (string)context[QSConstant.PARAM_KEY_BUCKET_NAME];
            string requestPath = (string)context[QSConstant.PARAM_KEY_REQUEST_PATH];

            string objectName = "";

            if (context.ContainsKey(QSConstant.PARAM_KEY_OBJECT_NAME))
            {
                objectName = context[QSConstant.PARAM_KEY_OBJECT_NAME].ToString();
            }
            if (!paramsHeaders.ContainsKey(QSConstant.HEADER_PARAM_KEY_CONTENTTYPE))
            {
                paramsHeaders.Add(QSConstant.HEADER_PARAM_KEY_CONTENTTYPE, MimeMapping.GetMimeMapping(objectName));
            }

            if (context.ContainsKey(QSConstant.PARAM_KEY_OBJECT_NAME))
            {
                requestPath = requestPath.Replace(QSConstant.BUCKET_NAME_REPLACE, bucketName);
                requestPath = requestPath.Replace(QSConstant.OBJECT_NAME_REPLACE, QSStringUtil.urlCharactersEncoding(objectName));
            }
            else
            {
                requestPath = requestPath.Replace(QSConstant.BUCKET_NAME_REPLACE, bucketName + "/");
            }

            string authSign =
                QSSignatureUtil.getAuth(
                    evnContext.getAccessKey(),
                    evnContext.getAccessSecret(),
                    method,
                    requestPath,
                    paramsQuery,
                    paramsHeaders);
            string requestSuffixPath = getRequestSuffixPath((string)context[QSConstant.PARAM_KEY_REQUEST_PATH], bucketName, objectName);

            paramsHeaders.Add("Authorization", authSign);
            logger.Info(authSign);
            string singedUrl =
                getSignedUrl(
                    evnContext.getRequestUrl(),
                    zone,
                    bucketName,
                    paramsQuery,
                    requestSuffixPath);

            if (singedUrl.IndexOf("&upload_id") != -1)//?part_number=0&upload_id=1asfdsf
            {
                if (singedUrl.IndexOf("upload_id") > singedUrl.IndexOf("part_number"))
                {
                    String temp1 = singedUrl.Substring(singedUrl.IndexOf("part_number"), singedUrl.IndexOf("&upload_id") - singedUrl.IndexOf("part_number"));
                    String temp2 = singedUrl.Substring(singedUrl.IndexOf("upload_id"), singedUrl.Length - singedUrl.IndexOf("upload_id"));
                    singedUrl = singedUrl.Substring(0, singedUrl.IndexOf("?") + 1) + temp2 + "&" + temp1; //singedUrl.Replace(temp1, temp2).Replace(temp2,temp1);
                }
            }
            logger.Info(singedUrl);
            if (QSConstant.PARAM_KEY_REQUEST_API_MULTIPART.Equals(requestApi))
            {
                HttpWebRequest request =
                    QSHttpRequestClient.getInstance()
                    .buildStorMultiUpload(
                        method, paramsBody, singedUrl, paramsHeaders, paramsQuery);
                return(request);
            }
            else
            {
                //System.Console.WriteLine(singedUrl);
                HttpWebRequest request =
                    QSHttpRequestClient.getInstance()
                    .buildStorRequest(method, paramsBody, singedUrl, paramsHeaders);
                return(request);
            }
        }