| 3783 | |
| 3784 | |
| 3785 | Future<Response> ProcessBase::_consume( |
| 3786 | const HttpEndpoint& endpoint, |
| 3787 | const string& name, |
| 3788 | const Owned<Request>& request) |
| 3789 | { |
| 3790 | Future<Option<AuthenticationResult>> authentication = None(); |
| 3791 | |
| 3792 | if (endpoint.realm.isSome()) { |
| 3793 | authentication = authenticator_manager->authenticate( |
| 3794 | *request, endpoint.realm.get()); |
| 3795 | } |
| 3796 | |
| 3797 | // TODO(bmahler): This is an interim check to diagnose MESOS-8687. |
| 3798 | CHECK(handlers.httpSequence.get() != nullptr) |
| 3799 | << "PID '" << pid << "' with endpoint name '" << name << "'"; |
| 3800 | |
| 3801 | // Sequence the authentication future to ensure the handlers |
| 3802 | // are invoked in the same order that requests arrive. |
| 3803 | authentication = handlers.httpSequence->add<Option<AuthenticationResult>>( |
| 3804 | [authentication]() { return authentication; }); |
| 3805 | |
| 3806 | return authentication |
| 3807 | .then(defer(self(), [this, endpoint, request, name]( |
| 3808 | const Option<AuthenticationResult>& authentication) |
| 3809 | -> Future<Response> { |
| 3810 | Option<Principal> principal = None(); |
| 3811 | |
| 3812 | // If authentication failed, we do not continue with authorization. |
| 3813 | if (authentication.isSome()) { |
| 3814 | if (authentication->unauthorized.isSome()) { |
| 3815 | // Request was not authenticated, challenged issued. |
| 3816 | return authentication->unauthorized.get(); |
| 3817 | } else if (authentication->forbidden.isSome()) { |
| 3818 | // Request was not authenticated, no challenge issued. |
| 3819 | return authentication->forbidden.get(); |
| 3820 | } |
| 3821 | |
| 3822 | CHECK_SOME(authentication->principal); |
| 3823 | principal = authentication->principal; |
| 3824 | } |
| 3825 | |
| 3826 | // Look for an authorization callback installed for this endpoint. |
| 3827 | // |
| 3828 | // NOTE: we use double-checked locking here to avoid |
| 3829 | // head-of-line blocking that occurs when the first thread |
| 3830 | // attempts to check for authorization callbacks. |
| 3831 | // |
| 3832 | // TODO(bmahler): Consider a read/write lock in addition to |
| 3833 | // double checked locking. Since we expect the callbacks to |
| 3834 | // be set in production, it would be ideal to avoid locking |
| 3835 | // altogether. This would be possible if authorization |
| 3836 | // callbacks were bound to the lifetime of libprocess |
| 3837 | // initialization and finalization. |
| 3838 | // |
| 3839 | // TODO(benh): Consider optimizing this further to not be |
| 3840 | // sequentially consistent. For more details see: |
| 3841 | // http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11. |
| 3842 | Future<bool> authorization = true; |
nothing calls this directly
no test coverage detected