This is an automated email from the ASF dual-hosted git repository.
wesm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/master by this push:
new 4e9992a ARROW-9175: [FlightRPC][C++] Expose peer to server
4e9992a is described below
commit 4e9992aff33b56b343e4c70fb75024bd40091fdd
Author: David Li <[email protected]>
AuthorDate: Thu Jun 18 18:02:24 2020 -0500
ARROW-9175: [FlightRPC][C++] Expose peer to server
Being able to read and log the client IP/port is often useful when
analyzing a request after-the-fact.
Closes #7481 from lidavidm/arrow-9175
Authored-by: David Li <[email protected]>
Signed-off-by: Wes McKinney <[email protected]>
---
cpp/src/arrow/flight/flight_test.cc | 9 ++++++++-
cpp/src/arrow/flight/server.cc | 5 ++++-
cpp/src/arrow/flight/server.h | 2 ++
python/pyarrow/_flight.pyx | 4 ++++
python/pyarrow/includes/libarrow_flight.pxd | 1 +
python/pyarrow/tests/test_flight.py | 7 +++++--
6 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/cpp/src/arrow/flight/flight_test.cc
b/cpp/src/arrow/flight/flight_test.cc
index e040611..5ef5c3c 100644
--- a/cpp/src/arrow/flight/flight_test.cc
+++ b/cpp/src/arrow/flight/flight_test.cc
@@ -392,7 +392,9 @@ class AuthTestServer : public FlightServerBase {
Status DoAction(const ServerCallContext& context, const Action& action,
std::unique_ptr<ResultStream>* result) override {
auto buf = Buffer::FromString(context.peer_identity());
- *result = std::unique_ptr<ResultStream>(new
SimpleResultStream({Result{buf}}));
+ auto peer = Buffer::FromString(context.peer());
+ *result = std::unique_ptr<ResultStream>(
+ new SimpleResultStream({Result{buf}, Result{peer}}));
return Status::OK();
}
};
@@ -1527,6 +1529,11 @@ TEST_F(TestAuthHandler, CheckPeerIdentity) {
ASSERT_NE(result, nullptr);
// Action returns the peer identity as the result.
ASSERT_EQ(result->body->ToString(), "user");
+
+ ASSERT_OK(results->Next(&result));
+ ASSERT_NE(result, nullptr);
+ // Action returns the peer address as the result.
+ ASSERT_NE(result->body->ToString(), "");
}
TEST_F(TestBasicAuthHandler, PassAuthenticatedCalls) {
diff --git a/cpp/src/arrow/flight/server.cc b/cpp/src/arrow/flight/server.cc
index 0f9dfb9..c27d5b1 100644
--- a/cpp/src/arrow/flight/server.cc
+++ b/cpp/src/arrow/flight/server.cc
@@ -359,9 +359,11 @@ class DoExchangeMessageWriter : public FlightMessageWriter
{
class FlightServiceImpl;
class GrpcServerCallContext : public ServerCallContext {
- explicit GrpcServerCallContext(grpc::ServerContext* context) :
context_(context) {}
+ explicit GrpcServerCallContext(grpc::ServerContext* context)
+ : context_(context), peer_(context_->peer()) {}
const std::string& peer_identity() const override { return peer_identity_; }
+ const std::string& peer() const override { return peer_; }
// Helper method that runs interceptors given the result of an RPC,
// then returns the final gRPC status to send to the client
@@ -392,6 +394,7 @@ class GrpcServerCallContext : public ServerCallContext {
private:
friend class FlightServiceImpl;
ServerContext* context_;
+ std::string peer_;
std::string peer_identity_;
std::vector<std::shared_ptr<ServerMiddleware>> middleware_;
std::unordered_map<std::string, std::shared_ptr<ServerMiddleware>>
middleware_map_;
diff --git a/cpp/src/arrow/flight/server.h b/cpp/src/arrow/flight/server.h
index f1206bd..f3d33b6 100644
--- a/cpp/src/arrow/flight/server.h
+++ b/cpp/src/arrow/flight/server.h
@@ -113,6 +113,8 @@ class ARROW_FLIGHT_EXPORT ServerCallContext {
virtual ~ServerCallContext() = default;
/// \brief The name of the authenticated peer (may be the empty string)
virtual const std::string& peer_identity() const = 0;
+ /// \brief The peer address (not validated)
+ virtual const std::string& peer() const = 0;
/// \brief Look up a middleware by key. Do not maintain a reference
/// to the object beyond the request body.
/// \return The middleware, or nullptr if not found.
diff --git a/python/pyarrow/_flight.pyx b/python/pyarrow/_flight.pyx
index 6bead9e..9ec2ea2 100644
--- a/python/pyarrow/_flight.pyx
+++ b/python/pyarrow/_flight.pyx
@@ -1413,6 +1413,10 @@ cdef class ServerCallContext:
"""
return tobytes(self.context.peer_identity())
+ def peer(self):
+ """Get the address of the peer."""
+ return frombytes(self.context.peer())
+
def get_middleware(self, key):
"""
Get a middleware instance by key.
diff --git a/python/pyarrow/includes/libarrow_flight.pxd
b/python/pyarrow/includes/libarrow_flight.pxd
index 3334902..c8c12e0 100644
--- a/python/pyarrow/includes/libarrow_flight.pxd
+++ b/python/pyarrow/includes/libarrow_flight.pxd
@@ -206,6 +206,7 @@ cdef extern from "arrow/flight/api.h" namespace "arrow"
nogil:
cdef cppclass CServerCallContext" arrow::flight::ServerCallContext":
c_string& peer_identity()
+ c_string& peer()
CServerMiddleware* GetMiddleware(const c_string& key)
cdef cppclass CTimeoutDuration" arrow::flight::TimeoutDuration":
diff --git a/python/pyarrow/tests/test_flight.py
b/python/pyarrow/tests/test_flight.py
index 518e741..eed31b2 100644
--- a/python/pyarrow/tests/test_flight.py
+++ b/python/pyarrow/tests/test_flight.py
@@ -215,7 +215,7 @@ class EchoStreamFlightServer(EchoFlightServer):
def do_action(self, context, action):
if action.type == "who-am-i":
- return [context.peer_identity()]
+ return [context.peer_identity(), context.peer().encode("utf-8")]
raise NotImplementedError
@@ -935,8 +935,11 @@ def test_http_basic_auth():
client = FlightClient(('localhost', server.port))
action = flight.Action("who-am-i", b"")
client.authenticate(HttpBasicClientAuthHandler('test', 'p4ssw0rd'))
- identity = next(client.do_action(action))
+ results = client.do_action(action)
+ identity = next(results)
assert identity.body.to_pybytes() == b'test'
+ peer_address = next(results)
+ assert peer_address.body.to_pybytes() != b''
def test_http_basic_auth_invalid_password():