| 728 | |
| 729 | |
| 730 | Future<Response> Http::executor( |
| 731 | const Request& request, |
| 732 | const Option<Principal>& principal) const |
| 733 | { |
| 734 | if (!slave->recoveryInfo.reconnect) { |
| 735 | CHECK_EQ(slave->state, Slave::RECOVERING); |
| 736 | return ServiceUnavailable("Agent has not finished recovery"); |
| 737 | } |
| 738 | |
| 739 | // TODO(anand): Add metrics for rejected requests. |
| 740 | |
| 741 | if (request.method != "POST") { |
| 742 | return MethodNotAllowed({"POST"}, request.method); |
| 743 | } |
| 744 | |
| 745 | v1::executor::Call v1Call; |
| 746 | |
| 747 | Option<string> contentType = request.headers.get("Content-Type"); |
| 748 | if (contentType.isNone()) { |
| 749 | return BadRequest("Expecting 'Content-Type' to be present"); |
| 750 | } |
| 751 | |
| 752 | if (contentType.get() == APPLICATION_PROTOBUF) { |
| 753 | if (!v1Call.ParseFromString(request.body)) { |
| 754 | return BadRequest("Failed to parse body into Call protobuf"); |
| 755 | } |
| 756 | } else if (contentType.get() == APPLICATION_JSON) { |
| 757 | Try<JSON::Value> value = JSON::parse(request.body); |
| 758 | if (value.isError()) { |
| 759 | return BadRequest("Failed to parse body into JSON: " + value.error()); |
| 760 | } |
| 761 | |
| 762 | Try<v1::executor::Call> parse = |
| 763 | ::protobuf::parse<v1::executor::Call>(value.get()); |
| 764 | |
| 765 | if (parse.isError()) { |
| 766 | return BadRequest("Failed to convert JSON into Call protobuf: " + |
| 767 | parse.error()); |
| 768 | } |
| 769 | |
| 770 | v1Call = parse.get(); |
| 771 | } else { |
| 772 | return UnsupportedMediaType( |
| 773 | string("Expecting 'Content-Type' of ") + |
| 774 | APPLICATION_JSON + " or " + APPLICATION_PROTOBUF); |
| 775 | } |
| 776 | |
| 777 | const executor::Call call = devolve(v1Call); |
| 778 | |
| 779 | Option<Error> error = common::validation::validateExecutorCall(call); |
| 780 | |
| 781 | if (error.isSome()) { |
| 782 | return BadRequest("Failed to validate Executor::Call: " + error->message); |
| 783 | } |
| 784 | |
| 785 | ContentType acceptType; |
| 786 | |
| 787 | if (call.type() == executor::Call::SUBSCRIBE) { |