| 564 | } |
| 565 | |
| 566 | void SerializeHttpRequest(butil::IOBuf* /*not used*/, |
| 567 | Controller* cntl, |
| 568 | const google::protobuf::Message* pbreq) { |
| 569 | HttpHeader& hreq = cntl->http_request(); |
| 570 | const bool is_http2 = (cntl->request_protocol() == PROTOCOL_H2); |
| 571 | bool is_grpc = false; |
| 572 | ControllerPrivateAccessor accessor(cntl); |
| 573 | if (!accessor.protocol_param().empty() && hreq.content_type().empty()) { |
| 574 | const std::string& param = accessor.protocol_param(); |
| 575 | if (param.find('/') == std::string::npos) { |
| 576 | std::string& s = hreq.mutable_content_type(); |
| 577 | s.reserve(12 + param.size()); |
| 578 | s.append("application/"); |
| 579 | s.append(param); |
| 580 | } else { |
| 581 | hreq.set_content_type(param); |
| 582 | } |
| 583 | } |
| 584 | if (pbreq != NULL) { |
| 585 | // If request is not NULL, message body will be serialized proto/json, |
| 586 | if (!pbreq->IsInitialized()) { |
| 587 | return cntl->SetFailed( |
| 588 | EREQUEST, "Missing required fields in request: %s", |
| 589 | pbreq->InitializationErrorString().c_str()); |
| 590 | } |
| 591 | if (!cntl->request_attachment().empty()) { |
| 592 | return cntl->SetFailed(EREQUEST, "request_attachment must be empty " |
| 593 | "when request is not NULL"); |
| 594 | } |
| 595 | HttpContentType content_type = HTTP_CONTENT_OTHERS; |
| 596 | if (hreq.content_type().empty()) { |
| 597 | // Set content-type if user did not. |
| 598 | // Note that http1.x defaults to json and h2 defaults to pb. |
| 599 | if (is_http2) { |
| 600 | content_type = HTTP_CONTENT_PROTO; |
| 601 | hreq.set_content_type(common->CONTENT_TYPE_PROTO); |
| 602 | } else { |
| 603 | content_type = HTTP_CONTENT_JSON; |
| 604 | hreq.set_content_type(common->CONTENT_TYPE_JSON); |
| 605 | } |
| 606 | } else { |
| 607 | bool is_grpc_ct = false; |
| 608 | content_type = ParseContentType(hreq.content_type(), &is_grpc_ct); |
| 609 | is_grpc = (is_http2 && is_grpc_ct); |
| 610 | } |
| 611 | |
| 612 | butil::IOBufAsZeroCopyOutputStream wrapper(&cntl->request_attachment()); |
| 613 | if (content_type == HTTP_CONTENT_PROTO) { |
| 614 | // Serialize content as protobuf |
| 615 | if (!pbreq->SerializeToZeroCopyStream(&wrapper)) { |
| 616 | cntl->request_attachment().clear(); |
| 617 | return cntl->SetFailed(EREQUEST, "Fail to serialize %s", |
| 618 | butil::EnsureString(pbreq->GetTypeName()).c_str()); |
| 619 | } |
| 620 | } else if (content_type == HTTP_CONTENT_PROTO_TEXT) { |
| 621 | if (!google::protobuf::TextFormat::Print(*pbreq, &wrapper)) { |
| 622 | cntl->request_attachment().clear(); |
| 623 | return cntl->SetFailed(EREQUEST, "Fail to print %s as proto-text", |