29 {
30 if (!header_complete_) {
31 auto header_end = buffer.find("\r\n\r\n");
32 if (header_end == std::string::npos) {
33 return {
34 .complete = false,
35 .message = "",
36 .consumed_bytes = 0,
37 .error = ""};
38 }
39
40
41 std::istringstream header_stream(buffer.substr(0, header_end));
42 std::string header_line;
43 bool found_length = false;
44 while (std::getline(header_stream, header_line) && !header_line.empty()) {
45 if (header_line.starts_with("Content-Length:")) {
46 try {
47 expected_length_ = std::stoi(header_line.substr(15));
48 found_length = true;
49 } catch (const std::exception&) {
50 return {
51 .complete = false,
52 .message = "",
53 .consumed_bytes = 0,
54 .error = "Invalid Content-Length header"};
55 }
56 }
57 }
58
59 if (!found_length) {
60 return {
61 .complete = false,
62 .message = "",
63 .consumed_bytes = 0,
64 .error = "Missing Content-Length header"};
65 }
66
67 header_complete_ = true;
68 header_size_ = header_end + 4;
69 }
70
71
72 if (buffer.size() < header_size_ + expected_length_) {
73 return {
74 .complete = false,
75 .message = "",
76 .consumed_bytes = 0,
77 .error = ""};
78 }
79
80
81 std::string message = buffer.substr(header_size_, expected_length_);
82 std::size_t total_consumed = header_size_ + expected_length_;
83
84
85 header_complete_ = false;
86 expected_length_ = 0;
87 header_size_ = 0;
88
89 return {
90 .complete = true,
91 .message = message,
92 .consumed_bytes = total_consumed,
93 .error = ""};
94 }