| 163 | } |
| 164 | |
| 165 | ParseResult ParseSofaMessage(butil::IOBuf* source, Socket* socket, |
| 166 | bool /*read_eof*/, const void* /*arg*/) { |
| 167 | char header_buf[24]; |
| 168 | const size_t n = source->copy_to(header_buf, sizeof(header_buf)); |
| 169 | if (n >= 4) { |
| 170 | void* dummy = header_buf; |
| 171 | if (*(const uint32_t*)dummy != *(const uint32_t*)"SOFA") { |
| 172 | return MakeParseError(PARSE_ERROR_TRY_OTHERS); |
| 173 | } |
| 174 | } else { |
| 175 | if (memcmp(header_buf, "SOFA", n) != 0) { |
| 176 | return MakeParseError(PARSE_ERROR_TRY_OTHERS); |
| 177 | } |
| 178 | } |
| 179 | if (n < sizeof(header_buf)) { |
| 180 | return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA); |
| 181 | } |
| 182 | uint32_t meta_size; |
| 183 | uint64_t body_size; |
| 184 | uint64_t msg_size; |
| 185 | SofaRawUnpacker ru(header_buf + 4); |
| 186 | ru.unpack32(meta_size).unpack64(body_size).unpack64(msg_size); |
| 187 | if (msg_size != meta_size + body_size) { |
| 188 | LOG(ERROR) << "msg_size=" << msg_size << " != meta_size=" << meta_size |
| 189 | << " + body_size=" << body_size; |
| 190 | return MakeParseError(PARSE_ERROR_TRY_OTHERS); |
| 191 | } |
| 192 | if (body_size > FLAGS_max_body_size) { |
| 193 | // We need this log to report the body_size to give users some clues |
| 194 | // which is not printed in InputMessenger. |
| 195 | LOG(ERROR) << "body_size=" << body_size << " from " |
| 196 | << socket->remote_side() << " is too large"; |
| 197 | return MakeParseError(PARSE_ERROR_TOO_BIG_DATA); |
| 198 | } else if (source->length() < sizeof(header_buf) + msg_size) { |
| 199 | return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA); |
| 200 | } |
| 201 | source->pop_front(sizeof(header_buf)); |
| 202 | MostCommonMessage* msg = MostCommonMessage::Get(); |
| 203 | source->cutn(&msg->meta, meta_size); |
| 204 | source->cutn(&msg->payload, body_size); |
| 205 | return MakeMessage(msg); |
| 206 | } |
| 207 | |
| 208 | // Assemble response packet using `correlation_id', `controller', |
| 209 | // `res', and then write this packet to `sock' |