| 74 | } |
| 75 | |
| 76 | void HttpStreamTransport::parseChunkedMessages() { |
| 77 | for (;;) { |
| 78 | size_t chunkSize = mReader.nextChunkSize(); |
| 79 | if (chunkSize == 0) { |
| 80 | break; |
| 81 | } |
| 82 | |
| 83 | u8 stackBuf[512]; |
| 84 | fl::vector<u8> heapBuf; |
| 85 | fl::span<u8> outSpan; |
| 86 | if (chunkSize <= sizeof(stackBuf)) { |
| 87 | outSpan = fl::span<u8>(stackBuf, sizeof(stackBuf)); |
| 88 | } else { |
| 89 | heapBuf.resize(chunkSize); |
| 90 | outSpan = heapBuf; |
| 91 | } |
| 92 | |
| 93 | ChunkedReadResult result = mReader.readChunk(outSpan); |
| 94 | if (!result.hasData()) { |
| 95 | break; |
| 96 | } |
| 97 | |
| 98 | fl::string jsonStr(reinterpret_cast<const char*>(result.mData.data()), result.mData.size()); // ok reinterpret cast |
| 99 | fl::json json = fl::json::parse(jsonStr.c_str()); |
| 100 | if (json.is_null()) { |
| 101 | continue; |
| 102 | } |
| 103 | |
| 104 | // Filter heartbeats |
| 105 | if (json["method"].as_string() == "rpc.ping") { |
| 106 | mLastHeartbeatReceived = getCurrentTimeMs(); |
| 107 | continue; |
| 108 | } |
| 109 | |
| 110 | mLastHeartbeatReceived = getCurrentTimeMs(); |
| 111 | |
| 112 | // Try to dispatch to pending calls/streams by id |
| 113 | if (json.contains("id") && !json["id"].is_null()) { |
| 114 | fl::string idKey = idToString(json["id"]); |
| 115 | |
| 116 | if (resolveRpc(json, idKey)) { |
| 117 | continue; // Consumed by pending call |
| 118 | } |
| 119 | if (resolveRpcStream(json, idKey)) { |
| 120 | continue; // Consumed by pending stream |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | // Not matched - add to incoming queue for readRequest() |
| 125 | mIncomingQueue.push_back(fl::move(json)); |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | bool HttpStreamTransport::resolveRpc(const fl::json& msg, const fl::string& idKey) { |
| 130 | auto it = mPendingCalls.find(idKey); |
nothing calls this directly
no test coverage detected