#include "CHttpClient.h" #include #include #include #include #include #include #include #include #include #include #include std::once_flag CHttpClient::oc_init; std::once_flag CHttpClient::oc_destory; CHttpClient::CHttpClient() { m_pCurl = nullptr; m_pList = nullptr; m_nTimeOutSecord = 30; m_formpost = nullptr; m_lastptr = nullptr; std::call_once(oc_init, [&](){ CURLcode res = curl_global_init(CURL_GLOBAL_ALL); if(CURLE_OK != res) { m_sErrorMsg = "curl_global_init初始化失败"; } }); } CHttpClient::~CHttpClient() { std::call_once(oc_destory, [](){curl_global_cleanup();}); } struct MemoryStruct { char *memory; size_t size; MemoryStruct() { memory = (char *)malloc(1); size = 0; } ~MemoryStruct() { free(memory); memory = NULL; size = 0; } }; struct FileStruct { std::string fileName; FILE *pFile; size_t size; bool setFile(std::string sFileName) { QFile file(sFileName.c_str()); if(file.exists()) { file.remove(); } pFile = fopen(sFileName.c_str(), "wb"); if( pFile == NULL ) { return false; } fileName = sFileName; return true; } void saveFile() { fclose(pFile); } FileStruct() { pFile = nullptr; fileName = ""; size = 0; } ~FileStruct() { size = 0; } }; size_t WriteFileCallback(void *ptr, size_t size, size_t nmemb, void *data) { size_t realsize = size * nmemb; FileStruct *file = (FileStruct *)data; if(file->pFile) { fwrite(ptr,realsize,1,file->pFile); file->size += realsize; } return realsize; } size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) { size_t realsize = size * nmemb; MemoryStruct *mem = (MemoryStruct *)data; mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1); if (mem->memory) { memcpy(&(mem->memory[mem->size]), ptr, realsize); mem->size += realsize; mem->memory[mem->size] = 0; } return realsize; } void CHttpClient::setTimeOut(int nTimeOut) { m_nTimeOutSecord = nTimeOut; } void CHttpClient::addParam(std::string sKey, std::string sValue) { std::string sEncodeValue = encodeStr(sValue); if(m_sParmStr.empty()) { m_sParmStr = sKey + "=" + sEncodeValue; } else { m_sParmStr = m_sParmStr + "&" + sKey + "=" + sEncodeValue; } } void CHttpClient::addHeader(std::string sKey, std::string sValue) { m_pList = curl_slist_append(m_pList, (sKey + ":" + sValue).c_str()); } bool CHttpClient::post(std::string uri, std::string &sResponse, int &nResCode) { m_pCurl = curl_easy_init(); if( NULL == m_pCurl) { m_sErrorMsg = "curl_easy_init初始化失败"; return false; } m_pList = curl_slist_append(m_pList,"Content-Type:application/x-www-form-urlencoded;charset=UTF-8"); m_pList = curl_slist_append(m_pList,"Accept-Language:zh-CN,zh;q=0.8"); curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList); curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT,m_nTimeOutSecord); //设置超时时长 curl_easy_setopt(m_pCurl, CURLOPT_URL, uri.c_str() ); //提交表单的URL地址 curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L); //启用时会将头文件的信息作为数据流输 curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向 curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L); //将返回结果通过回调函数写到自定义的对象中 MemoryStruct oDataChunk; curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &oDataChunk); curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息 //libcur的相关POST配置项 curl_easy_setopt(m_pCurl, CURLOPT_POST, 1L); curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, m_sParmStr.c_str()); curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, m_sParmStr.size()); // curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, false); // curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, false); sslVerify(); CURLcode res = curl_easy_perform(m_pCurl); long res_code = -1; res = curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &res_code); nResCode = res_code; if( res == CURLE_OK ) { sResponse = std::string(oDataChunk.memory, oDataChunk.size); curl_slist_free_all(m_pList); m_pList = NULL; m_sParmStr = ""; curl_easy_cleanup(m_pCurl); return true; } else { curl_slist_free_all(m_pList); m_pList = NULL; m_sParmStr = ""; curl_easy_cleanup(m_pCurl); return false; } } bool CHttpClient::post(std::string uri, std::string sPostStr, std::string &sResponse, int &nResCode) { m_pCurl = curl_easy_init(); if( NULL == m_pCurl) { m_sErrorMsg = "curl_easy_init初始化失败"; return false; } m_pList = curl_slist_append(m_pList,"Content-Type:application/json"); m_pList = curl_slist_append(m_pList,"Accept-Language:zh-CN,zh;q=0.8"); curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList); curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT,m_nTimeOutSecord); //设置超时时长 curl_easy_setopt(m_pCurl, CURLOPT_URL, uri.c_str() ); //提交表单的URL地址 curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L); //启用时会将头文件的信息作为数据流输 curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向 curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L); //将返回结果通过回调函数写到自定义的对象中 MemoryStruct oDataChunk; curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &oDataChunk); curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息 //libcur的相关POST配置项 curl_easy_setopt(m_pCurl, CURLOPT_POST, 1L); curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, sPostStr.c_str()); curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, sPostStr.size()); //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, false); //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, false); sslVerify(); CURLcode res = curl_easy_perform(m_pCurl); long res_code = -1; res = curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &res_code); nResCode = res_code; if( res == CURLE_OK ) { sResponse = std::string(oDataChunk.memory, oDataChunk.size); curl_slist_free_all(m_pList); m_pList = NULL; m_sParmStr = ""; curl_easy_cleanup(m_pCurl); return true; } else { curl_slist_free_all(m_pList); m_pList = NULL; m_sParmStr = ""; curl_easy_cleanup(m_pCurl); return false; } } void CHttpClient::addFormDataList(FORM_DATA_TYPE nType, std::string sKey, std::vector sValue) { curl_forms *pArray = new curl_forms[sValue.size()+1]; curl_forms *temp = pArray; for (std::string sItem : sValue) { if (nType == fdt_content) { temp->option = CURLFORM_COPYCONTENTS; } else { temp->option = CURLFORM_FILE; } temp->value = sItem.c_str(); temp++; } temp->option = CURLFORM_END; curl_formadd(&m_formpost, &m_lastptr, CURLFORM_COPYNAME, sKey.c_str(), CURLFORM_ARRAY, pArray, CURLFORM_END); delete [] pArray; } void CHttpClient::addFormData(FORM_DATA_TYPE nType, std::string sKey, std::string sValue) { if(nType == fdt_content) { curl_formadd(&m_formpost, &m_lastptr, CURLFORM_COPYNAME, sKey.c_str(), CURLFORM_COPYCONTENTS, sValue.c_str(), CURLFORM_END); } else { curl_formadd(&m_formpost, &m_lastptr, CURLFORM_COPYNAME, sKey.c_str(), CURLFORM_FILE, sValue.c_str(), CURLFORM_END); } } bool CHttpClient::postFormData(std::string uri, std::string &sResponse, int &nResCode) { m_pCurl = curl_easy_init(); if( NULL == m_pCurl) { m_sErrorMsg = "curl_easy_init初始化失败"; return false; } m_pList = curl_slist_append(m_pList,"Content-type:multipart/form-data"); m_pList = curl_slist_append(m_pList,"Accept-Language:zh-CN,zh;q=0.8"); curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList); curl_easy_setopt(m_pCurl, CURLOPT_URL, uri.c_str() ); //提交表单的URL地址 // 设置Form表单参数 curl_easy_setopt(m_pCurl, CURLOPT_HTTPPOST, m_formpost); // curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L); //启用时会将头文件的信息作为数据流输 // curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向 curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L); //将返回结果通过回调函数写到自定义的对象中 MemoryStruct oDataChunk; curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &oDataChunk); curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息 //libcur的相关POST配置项 // curl_easy_setopt(m_pCurl, CURLOPT_POST, 1L); // curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, m_sParmStr.c_str()); // curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, m_sParmStr.size()); curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT,m_nTimeOutSecord); //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, false); //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, false); sslVerify(); CURLcode res = curl_easy_perform(m_pCurl); long res_code = -1; res = curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &res_code); nResCode = res_code; if( res == CURLE_OK ) { sResponse = std::string(oDataChunk.memory, oDataChunk.size); curl_easy_cleanup(m_pCurl); curl_slist_free_all(m_pList); curl_formfree(m_formpost); m_formpost = NULL; m_lastptr = NULL; m_pList = NULL; m_sParmStr = ""; return true; } else { curl_easy_cleanup(m_pCurl); curl_slist_free_all(m_pList); curl_formfree(m_formpost); m_lastptr = NULL; m_pList = NULL; m_sParmStr = ""; return false; } } CURLcode CHttpClient::sslctx_function(CURL *curl, void *sslctx, void *parm) { X509 *cert = NULL; BIO *bio = NULL; BIO *kbio = NULL; RSA *rsa = NULL; int ret; const char *mypem = "-----BEGIN CERTIFICATE-----\n" "MIIDOjCCAiICBQCHhjV3MA0GCSqGSIb3DQEBBAUAMIGiMQswCQYDVQQGEwJDTjES\n" "MBAGA1UECAwJR3VhbmdEb25nMRIwEAYDVQQHDAlTaGVuWmhlbmcxEDAOBgNVBAoM\n" "B0FsaWJhYmExDTALBgNVBAsMBFByb2QxKDAmBgNVBAMMH29lLXN0dWRlbnQtY2xp\n" "ZW50LmV4YW0tY2xvdWQuY24xIDAeBgkqhkiG9w0BCQEWEWh1eXVlQHFtdGguY29t\n" "LmNuMB4XDTIxMTExMTA5MDUyM1oXDTMxMTEwOTA5MDUyM1owgaIxCzAJBgNVBAYT\n" "AkNOMRIwEAYDVQQIDAlHdWFuZ0RvbmcxEDAOBgNVBAoMB0FsaWJhYmExDTALBgNV\n" "BAsMBFByb2QxEjAQBgNVBAcMCVNoZW5aaGVuZzEoMCYGA1UEAwwfb2Utc3R1ZGVu\n" "dC1jbGllbnQuZXhhbS1jbG91ZC5jbjEgMB4GCSqGSIb3DQEJARYRaHV5dWVAcW10\n" "aC5jb20uY24wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMss/6qUMhiOdu80\n" "cyhZpkwBGO3raA+81ujwt8lEiK0idRE4dj+G6Bd6KjNJGdhQogfOgDPklv+oLxU/\n" "w4mXogHtb1DtFYPfEY72kdvEeLtRtG0gaRXN2/BJ1U6qZ+zvmhjEiqf/k5Q0HkZi\n" "hXZcADWrgPn3Dv43mUU9qvhbk9sFAgMBAAEwDQYJKoZIhvcNAQEEBQADggEBAAZa\n" "0K3mmslMCAQZWuidSA2O5tyRNT6uijKX/3UCm9NQ/Q98vMQ90cyXh2KyqNxi/L37\n" "EWPcMo1R8yuds41k8/sxSqF3A2zRs9uPTh3kYiu54dx7Z8amE31S0eh07fQs8qvp\n" "Jdi6vyARhgzNKKvvPi5hF5X03BAVdTGKaAWi2gMZMmeDuC8pjENTycixt9+usylV\n" "uB+Cheb9M/8FtJU6bKTwOyw3mYqhMK1wgKahjBSnUkp7IEXoaITDkn2Mz44xqCtN\n" "zZJ4R8wtV9uGm8HalDVaS9LWR1NPdLSkaIjtfESfjnWd4cjWOrHZ035yClab0uj4\n" "OyGCQKEQjVOot6szUP8=\n" "-----END CERTIFICATE-----"; /*replace the XXX with the actual RSA key*/ const char *mykey = "-----BEGIN RSA PRIVATE KEY-----\n" "MIICXgIBAAKBgQDLLP+qlDIYjnbvNHMoWaZMARjt62gPvNbo8LfJRIitInUROHY/\n" "hugXeiozSRnYUKIHzoAz5Jb/qC8VP8OJl6IB7W9Q7RWD3xGO9pHbxHi7UbRtIGkV\n" "zdvwSdVOqmfs75oYxIqn/5OUNB5GYoV2XAA1q4D59w7+N5lFPar4W5PbBQIDAQAB\n" "AoGBAK++19REZmTpbqWRN/9yNK/PzzGWDCh4z2klN8SoPJWOlbb0oQxodIBCUxiT\n" "pgCAFvgrvqeklpzEbR2zTz/IYwA+8wMVXT/V72QNygVKOohuhRYFH88LHTNOQV/X\n" "ieg6OoYz5bGvaNYHwx7kIqkeE2sBDtq89sX73bR9NWTb/n8hAkEA7XPDDHN2qdhh\n" "9xAl14L18UVTlTUK/cXZXaxNp0nmKL1jnQtHibWSUgyTDdv0vplXnqjRIk2mEtR/\n" "We3np/9mTQJBANsL0yGQrsMhAcRRHptYd4E9SrYp27L6/Oi3TGn8QNv5lawaGfCu\n" "0tat8AJfGzNgOWP16lwAz3/nns9HFVi4E5kCQQCbrGdVxGUpmPkxFt8YWX2Qflj7\n" "21inY4zMQuhuIp7IWtHx5bEy8V1KeX/3eBsO0k2FcTwa9zlH4xTTCovzsheJAkEA\n" "rEwK0NYbgUUPPLqKFqtppPDvOYaHV6txECROKPfQlLcnce4+BUGeelrq9RKWNL01\n" "p1kh9Sh2DyfDlUtWkSiJ0QJAZSLI92yo116QJz6SmU9g10pm8LSlAPa7j+1lfLvz\n" "eTIXiFpu5fbF1I1sFMuLKISSoqWPihMCIWxsE5a5i5OOuA== \n" "-----END RSA PRIVATE KEY-----"; (void)curl; /* avoid warnings */ (void)parm; /* avoid warnings */ /* get a BIO */ bio = BIO_new_mem_buf((char *)mypem, -1); if (bio == NULL) { printf("BIO_new_mem_buf failed\n"); } /* use it to read the PEM formatted certificate from memory into an X509 * structure that SSL can use */ cert = PEM_read_bio_X509(bio, NULL, 0, NULL); if (cert == NULL) { printf("PEM_read_bio_X509 failed...\n"); } /*tell SSL to use the X509 certificate*/ ret = SSL_CTX_use_certificate((SSL_CTX*)sslctx, cert); if (ret != 1) { printf("Use certificate failed\n"); } /*create a bio for the RSA key*/ kbio = BIO_new_mem_buf((char *)mykey, -1); if (kbio == NULL) { printf("BIO_new_mem_buf failed\n"); } /*read the key bio into an RSA object*/ rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL); if (rsa == NULL) { printf("Failed to create key bio\n"); } /*tell SSL to use the RSA key from memory*/ ret = SSL_CTX_use_RSAPrivateKey((SSL_CTX*)sslctx, rsa); if (ret != 1) { printf("Use Key failed\n"); } /* free resources that have been allocated by openssl functions */ if (bio) BIO_free(bio); if (kbio) BIO_free(kbio); if (rsa) RSA_free(rsa); if (cert) X509_free(cert); /* all set to go */ return CURLE_OK; } void CHttpClient::sslVerify() { curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, false); /* curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 2); curl_easy_setopt(m_pCurl, CURLOPT_SSLCERTTYPE, "PEM"); curl_easy_setopt(m_pCurl, CURLOPT_SSLKEYTYPE, "PEM"); curl_easy_setopt(m_pCurl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function); */ } bool CHttpClient::get(std::string uri, std::string &sResponse, int &nResCode) { m_pCurl = curl_easy_init(); if( NULL == m_pCurl) { m_sErrorMsg = "curl_easy_init初始化失败"; return false; } m_pList = curl_slist_append(m_pList,"Content-Type:application/json"); m_pList = curl_slist_append(m_pList,"Accept-Language:zh-CN,zh;q=0.8"); curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList); curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT,m_nTimeOutSecord); //设置超时时长 std::string strUrl = ""; strUrl = /*encodeURL*/(uri); curl_easy_setopt(m_pCurl, CURLOPT_URL, strUrl.c_str() ); //提交表单的URL地址 curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L); //启用时会将头文件的信息作为数据流输 curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向 curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L); //将返回结果通过回调函数写到自定义的对象中 MemoryStruct oDataChunk; curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &oDataChunk); curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息 //libcur的相关POST配置项 // curl_easy_setopt(m_pCurl, CURLOPT_POST, 1L); // curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, m_sParmStr.c_str()); // curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, m_sParmStr.size()); sslVerify(); CURLcode res = curl_easy_perform(m_pCurl); long res_code = -1; res = curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &res_code); nResCode = res_code; if( res == CURLE_OK ) { sResponse = std::string(oDataChunk.memory, oDataChunk.size); curl_slist_free_all(m_pList); m_pList = NULL; m_sParmStr = ""; curl_easy_cleanup(m_pCurl); return true; } else { curl_slist_free_all(m_pList); m_pList = NULL; m_sParmStr = ""; curl_easy_cleanup(m_pCurl); return false; } } bool CHttpClient::put(std::string uri, std::string &sResponse, int &nResCode) { m_pCurl = curl_easy_init(); if (NULL == m_pCurl) { m_sErrorMsg = "curl_easy_init初始化失败"; return false; } m_pList = curl_slist_append(m_pList, "Content-Type:application/json"); m_pList = curl_slist_append(m_pList, "Accept-Language:zh-CN,zh;q=0.8"); curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList); curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT, m_nTimeOutSecord); //设置超时时长 std::string strUrl = ""; strUrl = uri; curl_easy_setopt(m_pCurl, CURLOPT_URL, strUrl.c_str()); //提交表单的URL地址 curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L); //启用时会将头文件的信息作为数据流输 curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向 curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息 curl_easy_setopt(m_pCurl, CURLOPT_PUT, 1L); //将返回结果通过回调函数写到自定义的对象中 MemoryStruct oDataChunk; curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &oDataChunk); curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, false); //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, false); sslVerify(); CURLcode res = curl_easy_perform(m_pCurl); long res_code = -1; res = curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &res_code); nResCode = res_code; if (res == CURLE_OK) { sResponse = std::string(oDataChunk.memory, oDataChunk.size); } curl_slist_free_all(m_pList); m_pList = NULL; m_sParmStr = ""; curl_easy_cleanup(m_pCurl); if (res == CURLE_OK) { return true; } else { return false; } } bool CHttpClient::download(std::string uri, std::string sFileName, int &nResCode) { m_pCurl = curl_easy_init(); if( NULL == m_pCurl) { m_sErrorMsg = "curl_easy_init初始化失败"; return false; } // m_pList = curl_slist_append(m_pList,"Content-Type:application/x-www-form-urlencoded;charset=UTF-8"); // m_pList = curl_slist_append(m_pList,"Accept-Language:zh-CN,zh;q=0.8"); // curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList); std::string strUrl = ""; int nPos = uri.find_last_of(":"); strUrl = uri.substr(0, nPos+1); strUrl += encodeURL(uri.substr(nPos + 1, uri.length() - nPos - 1)); //myDebug()<