diff --git a/examples/HelloWorld.cpp b/examples/HelloWorld.cpp index d18e8d8..94e6215 100644 --- a/examples/HelloWorld.cpp +++ b/examples/HelloWorld.cpp @@ -1,4 +1,5 @@ #include "App.h" +#include /* Note that uWS::SSLApp({options}) is the same as uWS::App() when compiled without SSL support */ @@ -9,6 +10,8 @@ int main() { .cert_file_name = "../misc/cert.pem", .passphrase = "1234" }).get("/*", [](auto *res, auto *req) { + std::cout << res->getRemoteAddressAsText() << std::endl; + std::cout << res->getProxiedRemoteAddressAsText() << std::endl; res->end("Hello world!"); }).listen(3000, [](auto *token) { if (token) { diff --git a/src/AsyncSocket.h b/src/AsyncSocket.h index 3957fed..ce2a894 100644 --- a/src/AsyncSocket.h +++ b/src/AsyncSocket.h @@ -1,5 +1,5 @@ /* - * Authored by Alex Hultman, 2018-2019. + * Authored by Alex Hultman, 2018-2020. * Intellectual property of third-party. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -95,6 +95,24 @@ protected: return (int) getAsyncSocketData()->buffer.size(); } + /* Returns the text representation of an IPv4 or IPv6 address */ + std::string_view addressAsText(std::string_view binary) { + static thread_local char buf[64]; + int ipLength = 0; + + unsigned char *b = (unsigned char *) binary.data(); + + if (binary.length() == 4) { + ipLength = sprintf(buf, "%u.%u.%u.%u", b[0], b[1], b[2], b[3]); + } else { + ipLength = sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], + b[12], b[13], b[14], b[15]); + } + + return {buf, ipLength}; + } + /* Returns the remote IP address or empty string on failure */ std::string_view getRemoteAddress() { static thread_local char buf[16]; @@ -103,6 +121,11 @@ protected: return std::string_view(buf, ipLength); } + /* Returns the text representation of IP */ + std::string_view getRemoteAddressAsText() { + return addressAsText(getRemoteAddress()); + } + /* Write in three levels of prioritization: cork-buffer, syscall, socket-buffer. Always drain if possible. * Returns pair of bytes written (anywhere) and wheter or not this call resulted in the polling for * writable (or we are in a state that implies polling for writable). */ diff --git a/src/HttpParser.h b/src/HttpParser.h index 557f292..a4719b6 100644 --- a/src/HttpParser.h +++ b/src/HttpParser.h @@ -28,13 +28,8 @@ #include "f2/function2.hpp" #include "BloomFilter.h" - - -// if using proxy parser, depend on the layout of HttpResponesData #include "ProxyParser.h" - - namespace uWS { /* We require at least this much post padding */ diff --git a/src/HttpResponse.h b/src/HttpResponse.h index b50d900..63c7540 100644 --- a/src/HttpResponse.h +++ b/src/HttpResponse.h @@ -52,13 +52,6 @@ private: return (HttpResponseData *) Super::getAsyncSocketData(); } - /* If we have proxy support */ -#ifdef WITH_PROXY - void getProxiedRemoteAddress() { - getHttpResponseData()->proxyParser.getSourceIp(); - } -#endif - /* Write an unsigned 32-bit integer in hex */ void writeUnsignedHex(unsigned int value) { char buf[10]; @@ -174,6 +167,17 @@ private: } public: + /* If we have proxy support */ +#ifdef WITH_PROXY + std::string_view getProxiedRemoteAddress() { + return getHttpResponseData()->proxyParser.getSourceIp(); + } + + std::string_view getProxiedRemoteAddressAsText() { + return Super::addressAsText(getProxiedRemoteAddress()); + } +#endif + /* Manually upgrade to WebSocket. Typically called in upgrade handler. Immediately calls open handler. * NOTE: Will invalidate 'this' as socket might change location in memory. Throw away aftert use. */ template @@ -284,6 +288,7 @@ public: using Super::close; using Super::getRemoteAddress; + using Super::getRemoteAddressAsText; /* Note: Headers are not checked in regards to timeout. * We only check when you actively push data or end the request */ diff --git a/src/ProxyParser.h b/src/ProxyParser.h index a6d0b79..9835e9c 100644 --- a/src/ProxyParser.h +++ b/src/ProxyParser.h @@ -41,8 +41,8 @@ private: public: /* Returns 4 or 16 bytes */ - std::string_view getSourceIP() { - return {"hello", 5}; + std::string_view getSourceIp() { + return {(char *) sourceIp, 16}; } /* Returns [done, consumed] where done = false on failure */ @@ -86,6 +86,10 @@ public: printf("Family: %d\n", (header.fam & 0xf0) >> 4); printf("Transport: %d\n", (header.fam & 0x0f)); + //memcpy(sourceIp, ) + + + return {true, 16 + hostLength}; } diff --git a/src/WebSocket.h b/src/WebSocket.h index 692f8ca..a395f99 100644 --- a/src/WebSocket.h +++ b/src/WebSocket.h @@ -50,6 +50,7 @@ public: /* See AsyncSocket */ using Super::getBufferedAmount; using Super::getRemoteAddress; + using Super::getRemoteAddressAsText; /* Simple, immediate close of the socket. Emits close event */ using Super::close;