Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

httprequest.cpp中的ParseFromUrlencoded_函数有问题 #97

Open
geekzizi opened this issue Nov 25, 2023 · 1 comment
Open

httprequest.cpp中的ParseFromUrlencoded_函数有问题 #97

geekzizi opened this issue Nov 25, 2023 · 1 comment

Comments

@geekzizi
Copy link

httprequest.cpp 中的 ParseFromUrlencoded_ 函数有问题,无法解析加密字符,比如 # 字符在服务器端收到的是 %23 ,理论上应该解析为十进制数 35 ,然后直接替换 body_[i] 的值替换为 35 对应的字符 #

有三个函数需要修改,修改后的代码如下

void HttpRequest::ParseFromUrlencoded_() {
  if (body_.size() == 0) {
    return;
  }

  std::string key, value;
  int num = 0;
  int n = body_.size();
  int i = 0, j = 0;

  for (; i < n; i++) {
    char ch = body_[i];
    switch (ch) {
      case '=':
        key = body_.substr(j, i - j);
        j = i + 1;
        break;
      case '+':
        body_[i] = ' ';
        break;
      case '%':
        num = ConverHex(body_[i + 1]) * 16 + ConverHex(body_[i + 2]);
        body_[i] = num;
        body_.erase(body_.begin() + i + 1);
        body_.erase(body_.begin() + i + 1);
        n -= 2;
        break;
      case '&':
        value = body_.substr(j, i - j);
        j = i + 1;
        post_[key] = value;
        LOG_DEBUG("%s = %s", key.c_str(), value.c_str());
        break;
      default:
        break;
    }
  }
  assert(j <= i);
  if (post_.find(key) == post_.end() && j < i) {
    value = body_.substr(j, i - j);
    post_[key] = value;
  }
}
int HttpRequest::ConverHex(char ch) {
  unsigned int y;
  if (ch >= 'A' && ch <= 'F') {
    y = ch - 'A' + 10;
  } else if (ch >= 'a' && ch <= 'f') {
    y = ch - 'a' + 10;
  } else if (ch >= '0' && ch <= '9') {
    y = ch - '0';
  } else {
    assert(0);
  }
  return y;
}
bool HttpRequest::parse(Buffer& buff) {
  const char CRLF[] = "\r\n";
  if (buff.ReadableBytes() <= 0) {
    return false;
  }
  while (buff.ReadableBytes() && state_ != FINISH) {
    const char* lineEnd =
        std::search(buff.Peek(), buff.BeginWriteConst(), CRLF, CRLF + 2);
    std::string line(buff.Peek(), lineEnd);
    switch (state_) {
      case REQUEST_LINE:
        if (!ParseRequestLine_(line)) {
          return false;
        }
        ParsePath_();
        break;
      case HEADERS:
        ParseHeader_(line);
        if (buff.ReadableBytes() <= 2) {
          state_ = FINISH;
        }
        break;
      case BODY:
        ParseBody_(line);
        break;
      default:
        break;
    }
    if (lineEnd == buff.BeginWrite()) {
      buff.RetrieveUntil(lineEnd);
      break;
    }
    buff.RetrieveUntil(lineEnd + 2);
  }
  LOG_DEBUG("[%s], [%s], [%s]", method_.c_str(), path_.c_str(),
            version_.c_str());
  return true;
}
@Cwj1212
Copy link

Cwj1212 commented Apr 22, 2024

我也发现了,好像确实错了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants