qicosmos / cinatra

modern c++(c++20), cross-platform, header-only, easy to use http framework
MIT License
1.9k stars 375 forks source link

client URL 检测 的奇怪 bug #590

Closed twiify closed 6 months ago

twiify commented 6 months ago

同一个 URL,在 Linux 下 使用 gcc 编译后提示 URL 不合法,但 Windows 下使用 MSVC 编译却没这个问题。

URL 已经通过 code_utils::url_encode() 处理过。

Linux 下

Windows 下

qicosmos commented 6 months ago

把测试代码附上,这个图看不出来什么。

twiify commented 6 months ago

简化后的代码:

#include "cinatra.hpp"
#include <chrono>
#include <fstream>

namespace Coro = async_simple::coro;
using namespace cinatra;

Coro::Lazy<void> test(std::string endpoint)
{
    using namespace std::chrono_literals;
    coro_http_client client;
    client.set_conn_timeout(3s);
    client.set_req_timeout(2s);
    auto result = co_await client.async_post(
        endpoint,
        "{\"xxx\": \"xxx\"}",
        req_content_type::json);
    if (result.status == 200) {
        std::cout << "OK\n";
    } else {
        std::cout << "Error\n";
    }
    co_return;
}

Coro::Lazy<void> test1()
{
    std::ifstream infile("apis.txt");
    std::string line;

    std::vector<Coro::Lazy<void>> tasks;

    if (infile.is_open()) {
        while(std::getline(infile, line)) {
            line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
            if (!line.empty()) {
                tasks.push_back(test(line));
            }
        }
    }
    co_await Coro::collectAll(std::move(tasks));
    co_return;
}

int main()
{
    Coro::syncAwait(test1());
    return 0;
}

apis.txt 文件内容:

http://103.152.35.2:1188/translate
http://49.233.41.73:1188/translate
http://101.43.76.234:1188/translate
http://49.232.164.78:1188/translate
http://1.12.243.147:1188/translate
http://82.156.36.11:1188/translate
http://106.14.17.223:1188/translate
http://82.157.137.187:1188/translate
http://8.142.134.155:1188/translate
http://132.145.80.159:1188/translate
qicosmos commented 6 months ago

好的,晚点看一下

helintongh commented 6 months ago

txt文件默认换行符号是\r\n。windows系统采用的标准的换行格式\r\n,所以读文件的时候会直接去掉\r\n。

linux采用的非标准格式,所有读出来的文件末尾多了一个\r符号。

cinatra解析url的path的时候会判断字符,出现非path字符会直接退出。

因此修改为如下代码即可:

后续改进方案cinatra会在url值填入前去除\r\n等非path符号

#include <chrono>
#include <fstream>
#include <iostream>

#include "cinatra.hpp"

namespace Coro = async_simple::coro;
using namespace cinatra;

Coro::Lazy<void> test(std::string endpoint) {
  using namespace std::chrono_literals;
  std::cout << "endpoint is: " << endpoint << std::endl;
  coro_http_client client;
  client.set_conn_timeout(3s);
  client.set_req_timeout(2s);
  auto result = co_await client.async_post(endpoint, "{\"xxx\": \"xxx\"}",
                                           req_content_type::json);
  if (result.status == 200) {
    std::cout << "OK\n";
  }
  else {
    std::cout << "Error\n";
  }
  co_return;
}

Coro::Lazy<void> test1() {
  std::ifstream infile("apis.txt");
  std::string line;

  std::vector<Coro::Lazy<void>> tasks;

  if (infile.is_open()) {
    while (std::getline(infile, line)) {
      line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
      line.erase(std::remove_if(line.begin(), line.end(),
                               [](char c) {
                                  return c == '\r';
                               }),
                 line.end());
      if (!line.empty()) {
        tasks.push_back(test(line));
      }
    }
  }
  co_await Coro::collectAll(std::move(tasks));
  co_return;
}

int main() {
  Coro::syncAwait(test1());
  return 0;
}
qicosmos commented 6 months ago

简化后的代码:

#include "cinatra.hpp"
#include <chrono>
#include <fstream>

namespace Coro = async_simple::coro;
using namespace cinatra;

Coro::Lazy<void> test(std::string endpoint)
{
    using namespace std::chrono_literals;
    coro_http_client client;
    client.set_conn_timeout(3s);
    client.set_req_timeout(2s);
    auto result = co_await client.async_post(
        endpoint,
        "{\"xxx\": \"xxx\"}",
        req_content_type::json);
    if (result.status == 200) {
        std::cout << "OK\n";
    } else {
        std::cout << "Error\n";
    }
    co_return;
}

Coro::Lazy<void> test1()
{
    std::ifstream infile("apis.txt");
    std::string line;

    std::vector<Coro::Lazy<void>> tasks;

    if (infile.is_open()) {
        while(std::getline(infile, line)) {
            line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
            if (!line.empty()) {
                tasks.push_back(test(line));
            }
        }
    }
    co_await Coro::collectAll(std::move(tasks));
    co_return;
}

int main()
{
    Coro::syncAwait(test1());
    return 0;
}

apis.txt 文件内容:

http://103.152.35.2:1188/translate
http://49.233.41.73:1188/translate
http://101.43.76.234:1188/translate
http://49.232.164.78:1188/translate
http://1.12.243.147:1188/translate
http://82.156.36.11:1188/translate
http://106.14.17.223:1188/translate
http://82.157.137.187:1188/translate
http://8.142.134.155:1188/translate
http://132.145.80.159:1188/translate

代码设置超时时间不对,req_timeout 包括连接时间的,你设置的连接超时时间比req 超时时间还短是不对的。

twiify commented 6 months ago

感谢答复,我晚上再试试。

twiify commented 6 months ago

已解决!