MCPcopy Create free account
hub / github.com/apache/brpc / ParseHttpMessage

Function ParseHttpMessage

src/brpc/policy/http_rpc_protocol.cpp:1182–1336  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1180}
1181
1182ParseResult ParseHttpMessage(butil::IOBuf *source, Socket *socket,
1183 bool read_eof, const void* arg) {
1184 HttpContext* http_imsg =
1185 static_cast<HttpContext*>(socket->parsing_context());
1186 if (http_imsg == NULL) {
1187 if (read_eof || source->empty()) {
1188 // 1. read_eof: Read EOF after intact HTTP messages, a common case.
1189 // Notice that errors except NOT_ENOUGH_DATA can't be returned
1190 // otherwise the Socket will be SetFailed() and messages just
1191 // in ProcessHttpXXX() may be dropped.
1192 // 2. source->empty(): also common, InputMessage tries parse
1193 // handlers until error is met. If a message was consumed,
1194 // source is likely to be empty.
1195 return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA);
1196 }
1197 http_imsg = new (std::nothrow) HttpContext(
1198 socket->is_read_progressive(),
1199 socket->http_request_method());
1200 if (http_imsg == NULL) {
1201 LOG(FATAL) << "Fail to new HttpContext";
1202 return MakeParseError(PARSE_ERROR_NO_RESOURCE);
1203 }
1204 // Parsing http is costly, parsing an incomplete http message from the
1205 // beginning repeatedly should be avoided, otherwise the cost may reach
1206 // O(n^2) in the worst case. Save incomplete http messages in sockets
1207 // to prevent re-parsing. The message will be released when it is
1208 // completed or destroyed along with the socket.
1209 socket->reset_parsing_context(http_imsg);
1210 }
1211 ssize_t rc = 0;
1212 if (read_eof) {
1213 // Send EOF to HttpContext, check comments in http_message.h
1214 rc = http_imsg->ParseFromArray(NULL, 0);
1215 } else {
1216 // Empty `source' is sliently ignored and 0 is returned, check
1217 // comments in http_message.h
1218 rc = http_imsg->ParseFromIOBuf(*source);
1219 }
1220 if (http_imsg->is_stage2()) {
1221 // The header part is already parsed as an intact HTTP message
1222 // to the ProcessHttpXXX. Here parses the body part.
1223 if (rc >= 0) {
1224 source->pop_front(rc);
1225 if (http_imsg->Completed()) {
1226 // Already returned the message before, don't return again.
1227 CHECK_EQ(http_imsg, socket->release_parsing_context());
1228 // NOTE: calling http_imsg->Destroy() is wrong which can only
1229 // be called from ProcessHttpXXX
1230 http_imsg->RemoveOneRefForStage2();
1231 socket->OnProgressiveReadCompleted();
1232 return MakeMessage(NULL);
1233 } else {
1234 return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA);
1235 }
1236 } else {
1237 // Fail to parse the body. Since headers were parsed successfully,
1238 // the message is assumed to be HTTP, stop trying other protocols.
1239 const char* err = http_errno_description(

Callers 3

CheckResponseCodeMethod · 0.85
TEST_FFunction · 0.85
ReadOneResponseFunction · 0.85

Calls 15

MakeParseErrorFunction · 0.85
MakeMessageFunction · 0.85
http_errno_descriptionFunction · 0.85
MakeRawHttpResponseFunction · 0.85
is_failed_after_queriesFunction · 0.85
reset_parsing_contextMethod · 0.80
ParseFromArrayMethod · 0.80
ParseFromIOBufMethod · 0.80
is_stage2Method · 0.80
CompletedMethod · 0.80

Tested by 3

CheckResponseCodeMethod · 0.68
TEST_FFunction · 0.68
ReadOneResponseFunction · 0.68