cURL URL编码混乱

时间:2019-04-12 21:19:55

标签: c++ curl encoding

我正在尝试编码请求。请求如下:

echo `echo bar`

如您所见,您有很多特殊字符。如果我将该URL卷曲,则由于某些字符,我将不会对其进行处理。因此,我决定使用自己的方法和curl的方法对URL进行编码。这是使用curl编码的代码示例:

https://www.overpass-api.de/api/interpreter?data=area["name"="Nicaragua"]["admin_level"="2"]->.boundaryarea;(node["type"="route"]["route"="bus"](area.boundaryarea);way["type"="route"]["route"="bus"](area.boundaryarea);>;relation["type"="route"]["route"="bus"](area.boundaryarea);>>;);out meta;

将对整个请求进行编码,结果类似

std::string d = ...;
   CURL *curl = curl_easy_init();
if(curl) {
  char *output = curl_easy_escape(curl, d.c_str(), d.length());
  if(output) {
    printf("Encoded: %s\n", output);
    curl_free(output);
  }
}

如果我随后尝试使其卷曲以进行处理,它将抛出并说它无法解析主机,这对我来说很有意义。因此,由于开发工具的帮助,我决定检查chrome编码时的功能。这就是它的样子:

https%3A%2F%2Fwww.overpass-api.de%2Fapi%2Finterpreter%3Fdata%3D ...

如果我按原样卷曲,它将正确处理。

为什么某些字符被编码而其余字符不被编码?为什么卷曲会以这种方式接受它?

编辑:更重要的是,如何在我的代码中复制它?

2 个答案:

答案 0 :(得分:1)

您必须转义URI部分。看一下JavaScript的encodeURI()encode​URIComponent()函数,这是必经之路。

我正在使用模仿JavaScript的encodeURIComponent的以下函数,以便对各个部分进行编码

std::string encodeURIComponent(std::string const&value)
{
    std::ostringstream oss;
    oss << std::hex;
    for(auto c : value){
      int uc = static_cast<unsigned char>(c);
      if(((0x30 <= uc) && (uc <= 0x39)) || ((0x41 <= uc) && (uc <= 0x5A)) || ((0x61 <= uc) && (uc <= 0x7A))){
        oss << c;
        continue;
      }
      switch(c){
      case '-': oss << c; break;
      case '_': oss << c; break;
      case '.': oss << c; break;
      case '!': oss << c; break;
      case '~': oss << c; break;
      case '*': oss << c; break;
      case '\'': oss << c; break;
      case '(': oss << c; break;
      case ')': oss << c; break;
      default:
          oss << std::uppercase << '%' << std::setw(2) << uc << std::nouppercase;
          break;
      }
    }
    return oss.str();
}

答案 1 :(得分:0)

请勿将 entire URL作为单个字符串转义。仅转义实际需要转义的各个片段,例如查询参数。但即使如此,在name=value对中,根据需要分别转义namevalue,否则在=对中定界name=value和定界{一对之间的{1}}会逃脱,您不想发生这种情况。

尝试更多类似的方法:

&

Live Demo

输出:

https://www.overpass-api.de/api/interpreter?data=area[%22name%22=%22Nicaragua%22][%22admin_level%22=%222%22]-%3E.boundaryarea;(node[%22type%22=%22route%22][%22route%22=%22bus%22](area.boundaryarea);way[%22type%22=%22route%22][%22route%22=%22bus%22](area.boundaryarea);%3E;relation[%22type%22=%22route%22][%22route%22=%22bus%22](area.boundaryarea);%3E%3E;);out%20meta;
  

为什么某些字符被编码而其余字符不被编码?

RFC 3986,尤其是Section 2 "Characters"及其第2.1-2.5小节涵盖了规则。 Section 3.4涵盖了查询组件。