Skip to content

Commit

Permalink
Merge pull request #1436 from meganz/hotfix/http_server_ipv4_or_ipv6
Browse files Browse the repository at this point in the history
Hotfix/http server ipv4 or ipv6
  • Loading branch information
mattw-mega authored May 5, 2019
2 parents 34367ec + f132a29 commit eb55118
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 44 deletions.
4 changes: 2 additions & 2 deletions bindings/ios/MEGASdk.h
Original file line number Diff line number Diff line change
Expand Up @@ -6021,7 +6021,7 @@ typedef NS_ENUM(NSUInteger, StorageState) {
* ready to accept connections. The initialization is synchronous.
*
* The server will serve files using this URL format:
* http://127.0.0.1/<NodeHandle>/<NodeName>
* http://[::1]/<NodeHandle>/<NodeName>
*
* The node name must be URL encoded and must match with the node handle.
* You can generate a correct link for a MEGANode using [MEGASdk httpServerGetLocalLink]
Expand All @@ -6042,7 +6042,7 @@ typedef NS_ENUM(NSUInteger, StorageState) {
*
* The HTTP server will only stream a node if it's allowed by all configuration options.
*
* @param localOnly YES to listen on 127.0.0.1 only, NO to listen on all network interfaces
* @param localOnly YES to listen on ::1 only, NO to listen on all network interfaces
* @param port Port in which the server must accept connections
* @return YES is the server is ready, NO if the initialization failed
*/
Expand Down
4 changes: 2 additions & 2 deletions bindings/ios/MEGASdk.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1944,7 +1944,7 @@ - (BOOL)createAvatar:(NSString *)imagePath destinationPath:(NSString *)destinati
#pragma mark - HTTP Proxy Server

- (BOOL)httpServerStart:(BOOL)localOnly port:(NSInteger)port {
return self.megaApi->httpServerStart(localOnly, (int)port);
return self.megaApi->httpServerStart(localOnly, (int)port, false, NULL, NULL, true);
}

- (void)httpServerStop {
Expand Down Expand Up @@ -2000,7 +2000,7 @@ - (void)httpServerRemoveDelegate:(id<MEGATransferDelegate>)delegate {
}

- (NSURL *)httpServerGetLocalLink:(MEGANode *)node {
const char *val = self.megaApi->httpServerGetLocalLink([node getCPtr], true);
const char *val = self.megaApi->httpServerGetLocalLink([node getCPtr]);
if (!val) return nil;

NSURL *ret = [NSURL URLWithString:[NSString stringWithUTF8String:val]];
Expand Down
14 changes: 7 additions & 7 deletions contrib/cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,11 @@ IF(WIN32)
ENDIF(USE_MEDIAINFO)

IF(HAVE_FFMPEG)
ImportVcpkgLibrary(ffmpeg_avformat "${prebuilt_dir}/include" "${prebuilt_dir}/libs/x32d/avformat.lib" "${prebuilt_dir}/libs/x32/avformat.lib")
ImportVcpkgLibrary(ffmpeg_avutil "${prebuilt_dir}/include" "${prebuilt_dir}/libs/x32d/avutil.lib" "${prebuilt_dir}/libs/x32/avutil.lib")
ImportVcpkgLibrary(ffmpeg_avcodec "${prebuilt_dir}/include" "${prebuilt_dir}/libs/x32d/avcodec.lib" "${prebuilt_dir}/libs/x32/avcodec.lib")
ImportVcpkgLibrary(ffmpeg_avfilter "${prebuilt_dir}/include" "${prebuilt_dir}/libs/x32d/avfilter.lib" "${prebuilt_dir}/libs/x32/avfilter.lib")
ImportVcpkgLibrary(ffmpeg_avdevice "${prebuilt_dir}/include" "${prebuilt_dir}/libs/x32d/avdevice.lib" "${prebuilt_dir}/libs/x32/avdevice.lib")
ImportVcpkgLibrary(ffmpeg_avformat "${prebuilt_dir}/include/ffmpeg" "${prebuilt_dir}/libs/x32d/avformat.lib" "${prebuilt_dir}/libs/x32/avformat.lib")
ImportVcpkgLibrary(ffmpeg_avutil "${prebuilt_dir}/include/ffmpeg" "${prebuilt_dir}/libs/x32d/avutil.lib" "${prebuilt_dir}/libs/x32/avutil.lib")
ImportVcpkgLibrary(ffmpeg_avcodec "${prebuilt_dir}/include/ffmpeg" "${prebuilt_dir}/libs/x32d/avcodec.lib" "${prebuilt_dir}/libs/x32/avcodec.lib")
ImportVcpkgLibrary(ffmpeg_avfilter "${prebuilt_dir}/include/ffmpeg" "${prebuilt_dir}/libs/x32d/avfilter.lib" "${prebuilt_dir}/libs/x32/avfilter.lib")
ImportVcpkgLibrary(ffmpeg_avdevice "${prebuilt_dir}/include/ffmpeg" "${prebuilt_dir}/libs/x32d/avdevice.lib" "${prebuilt_dir}/libs/x32/avdevice.lib")
ENDIF(HAVE_FFMPEG)

IF(USE_LIBUV)
Expand Down Expand Up @@ -442,9 +442,9 @@ target_link_libraries(Mega PUBLIC z
$<${USE_FREEIMAGE}:freeimage_lzma> $<${USE_FREEIMAGE}:freeimage_lcms2> $<${USE_FREEIMAGE}:freeimage_raw>
$<${USE_FREEIMAGE}:freeimage_tiff> $<${USE_FREEIMAGE}:freeimage_tiffxx>
$<${USE_FREEIMAGE}:freeimage_jasper> $<${USE_FREEIMAGE}:freeimage_libpng> $<${USE_FREEIMAGE}:freeimage_half>
$<${USE_FREEIMAGE}:freeimage_webp> $<${USE_FREEIMAGE}:freeimage_webpdecoder> $<${USE_FREEIMAGE}:freeimage_webpdemux> $<${USE_FREEIMAGE}:freeimage_webpmux>
$<${USE_FREEIMAGE}:freeimage_swscale> $<${USE_FREEIMAGE}:freeimage_swresample>
$<${USE_FREEIMAGE}:freeimage_webp> $<${USE_FREEIMAGE}:freeimage_webpdecoder> $<${USE_FREEIMAGE}:freeimage_webpdemux> $<${USE_FREEIMAGE}:freeimage_webpmux>
$<${HAVE_FFMPEG}:ffmpeg_avformat> $<${HAVE_FFMPEG}:ffmpeg_avcodec> $<${HAVE_FFMPEG}:ffmpeg_avutil> $<${HAVE_FFMPEG}:ffmpeg_avfilter> $<${HAVE_FFMPEG}:ffmpeg_avdevice> $<${HAVE_FFMPEG}:ffmpeg_avdevice >
$<${HAVE_FFMPEG}:ffmpeg_swscale> $<${HAVE_FFMPEG}:ffmpeg_swresample>
$<${USE_QT}:ffmpeg_swscale> $<${USE_QT}:ffmpeg_swresample>
${Mega_PlatformSpecificLibs})
target_compile_definitions(Mega PUBLIC
Expand Down
6 changes: 3 additions & 3 deletions include/megaapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -12422,9 +12422,10 @@ class MegaApi
* enabling this flag will cause the function to return false.
* @param certificatepath path to certificate (PEM format)
* @param keypath path to certificate key
* @param useIPv6 true to use [::1] as host, false to use 127.0.0.1
* @return True if the server is ready, false if the initialization failed
*/
bool httpServerStart(bool localOnly = true, int port = 4443, bool useTLS = false, const char *certificatepath = NULL, const char * keypath = NULL);
bool httpServerStart(bool localOnly = true, int port = 4443, bool useTLS = false, const char *certificatepath = NULL, const char * keypath = NULL, bool useIPv6 = false);

/**
* @brief Stop the HTTP proxy server
Expand Down Expand Up @@ -12656,10 +12657,9 @@ class MegaApi
* You take the ownership of the returned value
*
* @param node Node to generate the local HTTP link
* @param formatIPv6 true to use [::1] as host, false to use 127.0.0.1
* @return URL to the node in the local HTTP proxy server, otherwise NULL
*/
char *httpServerGetLocalLink(MegaNode *node, bool formatIPv6 = false);
char *httpServerGetLocalLink(MegaNode *node);

/**
* @brief Returns a WEBDAV valid URL to a node in the local HTTP proxy server
Expand Down
13 changes: 7 additions & 6 deletions include/megaapi_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2217,12 +2217,12 @@ class MegaApiImpl : public MegaApp

#ifdef HAVE_LIBUV
// start/stop
bool httpServerStart(bool localOnly = true, int port = 4443, bool useTLS = false, const char *certificatepath = NULL, const char *keypath = NULL);
bool httpServerStart(bool localOnly = true, int port = 4443, bool useTLS = false, const char *certificatepath = NULL, const char *keypath = NULL, bool useIPv6 = false);
void httpServerStop();
int httpServerIsRunning();

// management
char *httpServerGetLocalLink(MegaNode *node, bool formatIPv6 = false);
char *httpServerGetLocalLink(MegaNode *node);
char *httpServerGetLocalWebDavLink(MegaNode *node);
MegaStringList *httpServerGetWebDavLinks();
MegaNodeList *httpServerGetWebDavAllowedNodes();
Expand Down Expand Up @@ -2917,12 +2917,13 @@ class MegaTCPServer
virtual void processOnExitHandleClose(MegaTCPServer* tcpServer);

public:
bool useTLS;
const bool useIPv6;
const bool useTLS;
MegaFileSystemAccess *fsAccess;

std::string basePath;

MegaTCPServer(MegaApiImpl *megaApi, std::string basePath, bool useTLS = false, std::string certificatepath = std::string(), std::string keypath = std::string());
MegaTCPServer(MegaApiImpl *megaApi, std::string basePath, bool useTLS = false, std::string certificatepath = std::string(), std::string keypath = std::string(), bool useIPv6 = false);
virtual ~MegaTCPServer();
bool start(int port, bool localOnly = true);
void stop(bool doNotWait = false);
Expand All @@ -2936,7 +2937,7 @@ class MegaTCPServer
int getRestrictedMode();
bool isHandleAllowed(handle h);
void clearAllowedHandles();
char* getLink(MegaNode *node, std::string protocol = "http", bool formatIPv6 = false);
char* getLink(MegaNode *node, std::string protocol = "http");

set<handle> getAllowedHandles();
void removeAllowedHandle(MegaHandle handle);
Expand Down Expand Up @@ -3055,7 +3056,7 @@ class MegaHTTPServer: public MegaTCPServer
static void returnHttpCodeAsyncBasedOnRequestError(MegaHTTPContext* httpctx, MegaError *e);
static void returnHttpCodeAsync(MegaHTTPContext* httpctx, int errorCode, std::string errorMessage = string());

MegaHTTPServer(MegaApiImpl *megaApi, string basePath, bool useTLS = false, std::string certificatepath = std::string(), std::string keypath = std::string());
MegaHTTPServer(MegaApiImpl *megaApi, string basePath, bool useTLS = false, std::string certificatepath = std::string(), std::string keypath = std::string(), bool useIPv6 = false);
virtual ~MegaHTTPServer();
char *getWebDavLink(MegaNode *node);

Expand Down
8 changes: 4 additions & 4 deletions src/megaapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3637,9 +3637,9 @@ void MegaApi::catchup(MegaRequestListener *listener)
}

#ifdef HAVE_LIBUV
bool MegaApi::httpServerStart(bool localOnly, int port, bool useTLS, const char * certificatepath, const char * keypath)
bool MegaApi::httpServerStart(bool localOnly, int port, bool useTLS, const char * certificatepath, const char * keypath, bool useIPv6)
{
return pImpl->httpServerStart(localOnly, port, useTLS, certificatepath, keypath);
return pImpl->httpServerStart(localOnly, port, useTLS, certificatepath, keypath, useIPv6);
}

void MegaApi::httpServerStop()
Expand Down Expand Up @@ -3717,9 +3717,9 @@ void MegaApi::httpServerRemoveListener(MegaTransferListener *listener)
pImpl->httpServerRemoveListener(listener);
}

char *MegaApi::httpServerGetLocalLink(MegaNode *node, bool formatIPv6)
char *MegaApi::httpServerGetLocalLink(MegaNode *node)
{
return pImpl->httpServerGetLocalLink(node, formatIPv6);
return pImpl->httpServerGetLocalLink(node);
}

char *MegaApi::httpServerGetLocalWebDavLink(MegaNode *node)
Expand Down
82 changes: 62 additions & 20 deletions src/megaapi_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7985,7 +7985,7 @@ bool MegaApiImpl::isOnline()
}

#ifdef HAVE_LIBUV
bool MegaApiImpl::httpServerStart(bool localOnly, int port, bool useTLS, const char *certificatepath, const char *keypath)
bool MegaApiImpl::httpServerStart(bool localOnly, int port, bool useTLS, const char *certificatepath, const char *keypath, bool useIPv6)
{
#ifndef ENABLE_EVT_TLS
if (useTLS)
Expand All @@ -8010,7 +8010,7 @@ bool MegaApiImpl::httpServerStart(bool localOnly, int port, bool useTLS, const c
}

httpServerStop();
httpServer = new MegaHTTPServer(this, basePath, useTLS, certificatepath ? certificatepath : string(), keypath ? keypath : string());
httpServer = new MegaHTTPServer(this, basePath, useTLS, certificatepath ? certificatepath : string(), keypath ? keypath : string(), useIPv6);
httpServer->setMaxBufferSize(httpServerMaxBufferSize);
httpServer->setMaxOutputSize(httpServerMaxOutputSize);
httpServer->enableFileServer(httpServerEnableFiles);
Expand Down Expand Up @@ -8063,7 +8063,7 @@ int MegaApiImpl::httpServerIsRunning()
return result;
}

char *MegaApiImpl::httpServerGetLocalLink(MegaNode *node, bool formatIPv6)
char *MegaApiImpl::httpServerGetLocalLink(MegaNode *node)
{
if (!node)
{
Expand All @@ -8077,7 +8077,7 @@ char *MegaApiImpl::httpServerGetLocalLink(MegaNode *node, bool formatIPv6)
return NULL;
}

char *result = httpServer->getLink(node, "http", formatIPv6);
char *result = httpServer->getLink(node, "http");
sdkMutex.unlock();
return result;
}
Expand Down Expand Up @@ -23040,7 +23040,13 @@ void StreamingBuffer::setMaxOutputSize(unsigned int outputSize)
// http_parser settings
http_parser_settings MegaTCPServer::parsercfg;

MegaTCPServer::MegaTCPServer(MegaApiImpl *megaApi, string basePath, bool useTLS, string certificatepath, string keypath)
MegaTCPServer::MegaTCPServer(MegaApiImpl *megaApi, string basePath, bool tls, string certificatepath, string keypath, bool ipv6)
: useIPv6(ipv6)
#ifdef ENABLE_EVT_TLS
, useTLS(tls)
#else
, useTLS(false)
#endif
{
this->megaApi = megaApi;
this->localOnly = true;
Expand All @@ -23054,14 +23060,11 @@ MegaTCPServer::MegaTCPServer(MegaApiImpl *megaApi, string basePath, bool useTLS,
this->closing = false;
this->thread = new MegaThread();
#ifdef ENABLE_EVT_TLS
this->useTLS = useTLS;
this->certificatepath = certificatepath;
this->keypath = keypath;
this->closing = false;
this->remainingcloseevents = 0;
this->evtrequirescleaning = false;
#else
this->useTLS = false;
#endif
fsAccess = new MegaFileSystemAccess();

Expand Down Expand Up @@ -23156,6 +23159,7 @@ int MegaTCPServer::uv_tls_writer(evt_tls_t *evt_tls, void *bfr, int sz)
}
#endif

// todo: a lot of this function is the same as initializeAndStartListening, we should factor them (maybe call that one from this one?)
void MegaTCPServer::run()
{
LOG_debug << " Running tcp server: " << port << " TLS=" << useTLS;
Expand Down Expand Up @@ -23185,15 +23189,34 @@ void MegaTCPServer::run()

uv_tcp_keepalive(&server, 0, 0);

struct sockaddr_in6 address;
if (localOnly)
union {
struct sockaddr_in6 ipv6;
struct sockaddr_in ipv4;
} address;

if (useIPv6)
{
uv_ip6_addr("::1", port, &address);
if (localOnly)
{
uv_ip6_addr("::1", port, &address.ipv6);
}
else
{
uv_ip6_addr("::", port, &address.ipv6);
}
}
else
{
uv_ip6_addr("::", port, &address);
if (localOnly)
{
uv_ip4_addr("127.0.0.1", port, &address.ipv4);
}
else
{
uv_ip4_addr("0.0.0.0", port, &address.ipv4);
}
}

uv_connection_cb onNewClientCB;
#ifdef ENABLE_EVT_TLS
if (useTLS)
Expand Down Expand Up @@ -23271,15 +23294,34 @@ void MegaTCPServer::initializeAndStartListening()

uv_tcp_keepalive(&server, 0, 0);

struct sockaddr_in6 address;
if (localOnly)
union {
struct sockaddr_in6 ipv6;
struct sockaddr_in ipv4;
} address;

if (useIPv6)
{
uv_ip6_addr("::1", port, &address);
if (localOnly)
{
uv_ip6_addr("::1", port, &address.ipv6);
}
else
{
uv_ip6_addr("::", port, &address.ipv6);
}
}
else
{
uv_ip6_addr("::", port, &address);
if (localOnly)
{
uv_ip4_addr("127.0.0.1", port, &address.ipv4);
}
else
{
uv_ip4_addr("0.0.0.0", port, &address.ipv4);
}
}

uv_connection_cb onNewClientCB;
#ifdef ENABLE_EVT_TLS
if (useTLS)
Expand Down Expand Up @@ -23393,7 +23435,7 @@ void MegaTCPServer::clearAllowedHandles()
lastHandle = INVALID_HANDLE;
}

char *MegaTCPServer::getLink(MegaNode *node, string protocol, bool formatIPv6)
char *MegaTCPServer::getLink(MegaNode *node, string protocol)
{
if (!node)
{
Expand All @@ -23403,7 +23445,7 @@ char *MegaTCPServer::getLink(MegaNode *node, string protocol, bool formatIPv6)
lastHandle = node->getHandle();
allowedHandles.insert(lastHandle);

string localhostIP = formatIPv6 ? "[::1]" : "127.0.0.1";
string localhostIP = useIPv6 ? "[::1]" : "127.0.0.1";

ostringstream oss;
oss << protocol << (useTLS ? "s" : "") << "://" << localhostIP << ":" << port << "/";
Expand Down Expand Up @@ -23910,8 +23952,8 @@ void MegaTCPServer::processAsyncEvent(MegaTCPContext *tcpctx)
// MegaHTTPServer specifics //
///////////////////////////////

MegaHTTPServer::MegaHTTPServer(MegaApiImpl *megaApi, string basePath, bool useTLS, string certificatepath, string keypath)
: MegaTCPServer(megaApi, basePath, useTLS, certificatepath, keypath)
MegaHTTPServer::MegaHTTPServer(MegaApiImpl *megaApi, string basePath, bool useTLS, string certificatepath, string keypath, bool useIPv6)
: MegaTCPServer(megaApi, basePath, useTLS, certificatepath, keypath, useIPv6)
{
// parser callbacks
parsercfg.on_url = onUrlReceived;
Expand Down

0 comments on commit eb55118

Please sign in to comment.