首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >错误:块编码中的非法或丢失十六进制序列

错误:块编码中的非法或丢失十六进制序列
EN

Stack Overflow用户
提问于 2021-03-02 13:31:36
回答 1查看 1.8K关注 0票数 0

我正在编写我自己的http服务器,现在我正在尝试修改块传输编码。我的尝试是这样的:

代码语言:javascript
复制
void HttpServer::SendRespons(HttpServer::Connection &socket_) noexcept {
  int sent = 0;
  int counter = 0;
  int index = 0;
  std::size_t response_size_;
  std::ifstream t(this->conf_.GetRootPath() + socket_.data);
  socket_.respons = {(std::istreambuf_iterator<char>(t)),
                     std::istreambuf_iterator<char>()};
  t.clear();
  response_size_ = socket_.respons.size();
  std::vector<std::string> strVec;
  strVec.reserve(socket_.respons.size() / BUFSIZE + 2);
  strVec.push_back(
      "HTTP/1.1 200 OK\r\nServer: http\r\nContent-Type: "
      "text/html\r\nTransfer-Encoding: "
      "chunked\r\nConnection: Keep-Alive\r\n\r\n");
  while (index + 16374 < static_cast<int>(response_size_)) {
    strVec.push_back("3ff6\r\n" + socket_.respons.substr(index, 16374) +
                     "\r\n\r\n");
    index += 16374;
  }
  std::stringstream stream;
  stream << std::hex
         << std::atoi(std::to_string(response_size_ - index).c_str());
  strVec.push_back(stream.str() + "\r\n" +
                   socket_.respons.substr(index, response_size_ - index) +
                   "\r\n\r\n");
  strVec.push_back("0\r\n\r\n");
  index = 0;
  response_size_ += (strVec[0].size() + strVec[strVec.size() - 1].size());

  std::lock_guard<std::mutex> lg(this->connected_clients_mux_);
  while (index < static_cast<int>(strVec.size())) {
    int len =
        write(socket_.socket, (char *)&strVec[index][0], strVec[index].size());

    if (len < 0) {
      //...
      } else if ((errno == EPIPE) || (errno == ECONNRESET)) {
        std::cout << __FILE__ << " " << __func__
                  << " sent stop (epipe || econreset), len= " << len << " "
                  << "error #" << errno << std::endl;
        break;
      //...
    }
    ++index;
    sent += len;
    std::cout << __FILE__ << " " << __func__ << " sent " << len << " "
              << "packet #" << ++counter << std::endl;
  }
  std::cout << std::endl
            << __FILE__ << " " << __func__
            << " assumed length:" << response_size_
            << " sent:" << sent << " to: " << socket_.socket << std::endl;
}

上面的函数应该读取文件,将其分割成几个部分,然后一个一个地传递。据我所知,分片进行得很好,但当试图发送文件时:

代码语言:javascript
复制
curl -v http://localhost:8080/filename

我得到了:

代码语言:javascript
复制
*   Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /filename HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: http
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: Keep-Alive
< 
//.... here is first chunk
* Illegal or missing hexadecimal sequence in chunked-encoding
* Closing connection 0
curl: (56) Illegal or missing hexadecimal sequence in chunked-encoding

如您所见,客户端接收响应的第一部分(头)并处理它们。之后-它期待消息的正文。收到它的第一部分后,连接被关闭。我知道错误就像在消息中以我自己的块的格式写的那样,但是我自己不知道确切的位置。我听从了encoding#Format的指示,但obv犯了一个错误。由于客户端没有输出它所期望的十六进制序列的任何内容,所以它接收并错误地考虑到的十六进制序列没有输出,因此我请求帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-02 13:39:29

我认为在这部分代码的末尾只需要一个\r\n

代码语言:javascript
复制
    strVec.push_back("3ff6\r\n" + socket_.respons.substr(index, 16374) +
                     "\r\n\r\n");

不应该在前一个块和下一个块的十六进制大小之间插入空行。(最后一块也是如此)

您提供的维基百科页面在示例中的块之间插入空行,只是为了增加可读性,但实际上并不发送这些空行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66440424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档