mirror of https://github.com/kiwix/libkiwix.git
Make getNetworkInterfaces() and getBestPublicIp() available via tools.h
Remove HTTP URL helper line - should be done in kiwix-serve Add getters at server level - getAddress and getPort
This commit is contained in:
parent
4b563e567e
commit
9554ab5db0
|
@ -60,6 +60,8 @@ namespace kiwix
|
||||||
{ m_withTaskbar = withTaskbar; m_withLibraryButton = withLibraryButton; }
|
{ m_withTaskbar = withTaskbar; m_withLibraryButton = withLibraryButton; }
|
||||||
void setBlockExternalLinks(bool blockExternalLinks)
|
void setBlockExternalLinks(bool blockExternalLinks)
|
||||||
{ m_blockExternalLinks = blockExternalLinks; }
|
{ m_blockExternalLinks = blockExternalLinks; }
|
||||||
|
int getPort();
|
||||||
|
std::string getAddress();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Library* mp_library;
|
Library* mp_library;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace kiwix {
|
namespace kiwix {
|
||||||
|
|
||||||
|
@ -194,5 +195,17 @@ bool fileExists(const std::string& path);
|
||||||
* @return mimetype from filename in string format.
|
* @return mimetype from filename in string format.
|
||||||
*/
|
*/
|
||||||
std::string getMimeTypeForFile(const std::string& filename);
|
std::string getMimeTypeForFile(const std::string& filename);
|
||||||
|
|
||||||
|
/** Provides all available network interfaces
|
||||||
|
*
|
||||||
|
* This function provides the available IPv4 network interfaces
|
||||||
|
*/
|
||||||
|
std::map<std::string, std::string> getNetworkInterfaces();
|
||||||
|
|
||||||
|
/** Provides the best IP address
|
||||||
|
* This function provides the best IP address from the list given by getNetworkInterfaces
|
||||||
|
*/
|
||||||
|
std::string getBestPublicIp();
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif // KIWIX_TOOLS_H
|
#endif // KIWIX_TOOLS_H
|
||||||
|
|
|
@ -26,7 +26,6 @@ kiwix_sources = [
|
||||||
'server/etag.cpp',
|
'server/etag.cpp',
|
||||||
'server/request_context.cpp',
|
'server/request_context.cpp',
|
||||||
'server/response.cpp',
|
'server/response.cpp',
|
||||||
'server/networkTools.cpp',
|
|
||||||
'server/internalServer.cpp',
|
'server/internalServer.cpp',
|
||||||
'server/internalServer_catalog_v2.cpp',
|
'server/internalServer_catalog_v2.cpp',
|
||||||
'opds_catalog.cpp'
|
'opds_catalog.cpp'
|
||||||
|
|
|
@ -71,4 +71,14 @@ void Server::setRoot(const std::string& root)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Server::getPort()
|
||||||
|
{
|
||||||
|
return mp_server->getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Server::getAddress()
|
||||||
|
{
|
||||||
|
return mp_server->getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ extern "C" {
|
||||||
#include "tools/regexTools.h"
|
#include "tools/regexTools.h"
|
||||||
#include "tools/stringTools.h"
|
#include "tools/stringTools.h"
|
||||||
#include "tools/archiveTools.h"
|
#include "tools/archiveTools.h"
|
||||||
|
#include "tools/networkTools.h"
|
||||||
#include "library.h"
|
#include "library.h"
|
||||||
#include "name_mapper.h"
|
#include "name_mapper.h"
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
|
@ -159,8 +160,9 @@ bool InternalServer::start() {
|
||||||
sockAddr.sin_family = AF_INET;
|
sockAddr.sin_family = AF_INET;
|
||||||
sockAddr.sin_port = htons(m_port);
|
sockAddr.sin_port = htons(m_port);
|
||||||
if (m_addr.empty()) {
|
if (m_addr.empty()) {
|
||||||
if (0 != INADDR_ANY)
|
if (0 != INADDR_ANY) {
|
||||||
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
}
|
||||||
m_addr = kiwix::getBestPublicIp();
|
m_addr = kiwix::getBestPublicIp();
|
||||||
} else {
|
} else {
|
||||||
if (inet_pton(AF_INET, m_addr.c_str(), &(sockAddr.sin_addr.s_addr)) == 0) {
|
if (inet_pton(AF_INET, m_addr.c_str(), &(sockAddr.sin_addr.s_addr)) == 0) {
|
||||||
|
@ -168,11 +170,6 @@ bool InternalServer::start() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string url = "http://" + m_addr + ":" + std::to_string(m_port) + "/";
|
|
||||||
std::cout << "The Kiwix server is running and can be accessed in the local network at : "
|
|
||||||
<< url << std::endl;
|
|
||||||
|
|
||||||
mp_daemon = MHD_start_daemon(flags,
|
mp_daemon = MHD_start_daemon(flags,
|
||||||
m_port,
|
m_port,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
@ -35,7 +35,6 @@ extern "C" {
|
||||||
|
|
||||||
#include "server/request_context.h"
|
#include "server/request_context.h"
|
||||||
#include "server/response.h"
|
#include "server/response.h"
|
||||||
#include "networkTools.h"
|
|
||||||
|
|
||||||
namespace kiwix {
|
namespace kiwix {
|
||||||
|
|
||||||
|
@ -68,6 +67,8 @@ class InternalServer {
|
||||||
void** cont_cls);
|
void** cont_cls);
|
||||||
bool start();
|
bool start();
|
||||||
void stop();
|
void stop();
|
||||||
|
std::string getAddress() { return m_addr; }
|
||||||
|
int getPort() { return m_port; }
|
||||||
|
|
||||||
private: // functions
|
private: // functions
|
||||||
std::unique_ptr<Response> handle_request(const RequestContext& request);
|
std::unique_ptr<Response> handle_request(const RequestContext& request);
|
||||||
|
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 Emmanuel Engelhart <kelson@kiwix.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
||||||
* MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "networkTools.h"
|
|
||||||
|
|
||||||
std::map<std::string, std::string> kiwix::getNetworkInterfaces() {
|
|
||||||
std::map<std::string, std::string> interfaces;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
|
|
||||||
if (sd == SOCKET_ERROR) {
|
|
||||||
std::cerr << "Failed to get a socket. Error " << WSAGetLastError() <<
|
|
||||||
std::endl;
|
|
||||||
return interfaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERFACE_INFO InterfaceList[20];
|
|
||||||
unsigned long nBytesReturned;
|
|
||||||
if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList,
|
|
||||||
sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) {
|
|
||||||
std::cerr << "Failed calling WSAIoctl: error " << WSAGetLastError() <<
|
|
||||||
std::endl;
|
|
||||||
return interfaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
|
|
||||||
for (int i = 0; i < nNumInterfaces; ++i) {
|
|
||||||
sockaddr_in *pAddress;
|
|
||||||
pAddress = (sockaddr_in *) & (InterfaceList[i].iiAddress);
|
|
||||||
|
|
||||||
/* Add to the map */
|
|
||||||
std::string interfaceName = std::string(inet_ntoa(pAddress->sin_addr));
|
|
||||||
std::string interfaceIp = std::string(inet_ntoa(pAddress->sin_addr));
|
|
||||||
interfaces.insert(std::pair<std::string, std::string>(interfaceName, interfaceIp));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* Get Network interfaces information */
|
|
||||||
char buf[16384];
|
|
||||||
struct ifconf ifconf;
|
|
||||||
int fd = socket(PF_INET, SOCK_DGRAM, 0); /* Only IPV4 */
|
|
||||||
ifconf.ifc_len=sizeof buf;
|
|
||||||
ifconf.ifc_buf=buf;
|
|
||||||
if(ioctl(fd, SIOCGIFCONF, &ifconf)!=0) {
|
|
||||||
perror("ioctl(SIOCGIFCONF)");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Go through each interface */
|
|
||||||
int i;
|
|
||||||
size_t len;
|
|
||||||
struct ifreq *ifreq;
|
|
||||||
ifreq = ifconf.ifc_req;
|
|
||||||
for (i = 0; i < ifconf.ifc_len; ) {
|
|
||||||
if (ifreq->ifr_addr.sa_family == AF_INET) {
|
|
||||||
/* Get the network interface ip */
|
|
||||||
char host[128] = { 0 };
|
|
||||||
const int error = getnameinfo(&(ifreq->ifr_addr), sizeof ifreq->ifr_addr,
|
|
||||||
host, sizeof host,
|
|
||||||
0, 0, NI_NUMERICHOST);
|
|
||||||
if (!error) {
|
|
||||||
std::string interfaceName = std::string(ifreq->ifr_name);
|
|
||||||
std::string interfaceIp = std::string(host);
|
|
||||||
/* Add to the map */
|
|
||||||
interfaces.insert(std::pair<std::string, std::string>(interfaceName, interfaceIp));
|
|
||||||
} else {
|
|
||||||
perror("getnameinfo()");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* some systems have ifr_addr.sa_len and adjust the length that
|
|
||||||
* way, but not mine. weird */
|
|
||||||
#ifndef __linux__
|
|
||||||
len=IFNAMSIZ + ifreq->ifr_addr.sa_len;
|
|
||||||
#else
|
|
||||||
len=sizeof *ifreq;
|
|
||||||
#endif
|
|
||||||
ifreq=(struct ifreq*)((char*)ifreq+len);
|
|
||||||
i+=len;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return interfaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string kiwix::getBestPublicIp() {
|
|
||||||
std::map<std::string, std::string> interfaces = kiwix::getNetworkInterfaces();
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
const char* const prioritizedNames[] =
|
|
||||||
{ "eth0", "eth1", "wlan0", "wlan1", "en0", "en1" };
|
|
||||||
const int count = (sizeof prioritizedNames) / (sizeof prioritizedNames[0]);
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
std::map<std::string, std::string>::const_iterator it =
|
|
||||||
interfaces.find(prioritizedNames[i]);
|
|
||||||
if (it != interfaces.end())
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (std::map<std::string, std::string>::iterator iter = interfaces.begin();
|
|
||||||
iter != interfaces.end(); ++iter) {
|
|
||||||
std::string interfaceIp = iter->second;
|
|
||||||
if (interfaceIp.length() >= 7 && interfaceIp.substr(0, 7) == "192.168")
|
|
||||||
return interfaceIp;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::map<std::string, std::string>::iterator iter = interfaces.begin();
|
|
||||||
iter != interfaces.end(); ++iter) {
|
|
||||||
std::string interfaceIp = iter->second;
|
|
||||||
if (interfaceIp.length() >= 7 && interfaceIp.substr(0, 7) == "172.16.")
|
|
||||||
return interfaceIp;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::map<std::string, std::string>::iterator iter = interfaces.begin();
|
|
||||||
iter != interfaces.end(); ++iter) {
|
|
||||||
std::string interfaceIp = iter->second;
|
|
||||||
if (interfaceIp.length() >= 3 && interfaceIp.substr(0, 3) == "10.")
|
|
||||||
return interfaceIp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "127.0.0.1";
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2012 Emmanuel Engelhart <kelson@kiwix.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
||||||
* MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef KIWIX_NETWORKTOOLS_H
|
|
||||||
#define KIWIX_NETWORKTOOLS_H
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#else
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace kiwix {
|
|
||||||
std::map<std::string, std::string> getNetworkInterfaces();
|
|
||||||
std::string getBestPublicIp();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012 Emmanuel Engelhart <kelson@kiwix.org>
|
* Copyright 2012 Emmanuel Engelhart <kelson@kiwix.org>
|
||||||
|
* Copyright 2021 Nikhil Tanwar <2002nikhiltanwar@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
#include <tools/networkTools.h>
|
#include <tools/networkTools.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -29,6 +31,17 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <iostream>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t write_callback_to_iss(char* ptr, size_t size, size_t nmemb, void* userdata)
|
size_t write_callback_to_iss(char* ptr, size_t size, size_t nmemb, void* userdata)
|
||||||
{
|
{
|
||||||
|
@ -57,3 +70,104 @@ std::string kiwix::download(const std::string& url) {
|
||||||
}
|
}
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> kiwix::getNetworkInterfaces() {
|
||||||
|
std::map<std::string, std::string> interfaces;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
|
||||||
|
if (sd == SOCKET_ERROR) {
|
||||||
|
std::cerr << "Failed to get a socket. Error " << WSAGetLastError() << std::endl;
|
||||||
|
return interfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERFACE_INFO InterfaceList[20];
|
||||||
|
unsigned long nBytesReturned;
|
||||||
|
if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList,
|
||||||
|
sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) {
|
||||||
|
std::cerr << "Failed calling WSAIoctl: error " << WSAGetLastError() << std::endl;
|
||||||
|
return interfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
|
||||||
|
for (int i = 0; i < nNumInterfaces; ++i) {
|
||||||
|
sockaddr_in *pAddress;
|
||||||
|
pAddress = (sockaddr_in *) & (InterfaceList[i].iiAddress.AddressIn);
|
||||||
|
if(pAddress->sin_family == AF_INET) {
|
||||||
|
/* Add to the map */
|
||||||
|
std::string interfaceName = std::string(inet_ntoa(pAddress->sin_addr));
|
||||||
|
interfaces[interfaceName] = interfaceName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Get Network interfaces information */
|
||||||
|
char buf[16384];
|
||||||
|
struct ifconf ifconf;
|
||||||
|
int fd = socket(PF_INET, SOCK_DGRAM, 0); /* Only IPV4 */
|
||||||
|
ifconf.ifc_len = sizeof(buf);
|
||||||
|
ifconf.ifc_buf=buf;
|
||||||
|
if(ioctl(fd, SIOCGIFCONF, &ifconf)!=0) {
|
||||||
|
perror("ioctl(SIOCGIFCONF)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go through each interface */
|
||||||
|
struct ifreq *ifreq;
|
||||||
|
ifreq = ifconf.ifc_req;
|
||||||
|
for (int i = 0; i < ifconf.ifc_len; ) {
|
||||||
|
if (ifreq->ifr_addr.sa_family == AF_INET) {
|
||||||
|
/* Get the network interface ip */
|
||||||
|
char host[128] = { 0 };
|
||||||
|
const int error = getnameinfo(&(ifreq->ifr_addr), sizeof(ifreq->ifr_addr),
|
||||||
|
host, sizeof(host),
|
||||||
|
0, 0, NI_NUMERICHOST);
|
||||||
|
if (!error) {
|
||||||
|
std::string interfaceName = std::string(ifreq->ifr_name);
|
||||||
|
std::string interfaceIp = std::string(host);
|
||||||
|
/* Add to the map */
|
||||||
|
interfaces[interfaceName] = interfaceIp;
|
||||||
|
} else {
|
||||||
|
perror("getnameinfo()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* some systems have ifr_addr.sa_len and adjust the length that
|
||||||
|
* way, but not mine. weird */
|
||||||
|
size_t len;
|
||||||
|
#ifndef __linux__
|
||||||
|
len = IFNAMSIZ + ifreq->ifr_addr.sa_len;
|
||||||
|
#else
|
||||||
|
len = sizeof(*ifreq);
|
||||||
|
#endif
|
||||||
|
ifreq = (struct ifreq*)((char*)ifreq+len);
|
||||||
|
i += len;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return interfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string kiwix::getBestPublicIp() {
|
||||||
|
auto interfaces = getNetworkInterfaces();
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
const char* const prioritizedNames[] =
|
||||||
|
{ "eth0", "eth1", "wlan0", "wlan1", "en0", "en1" };
|
||||||
|
for(auto name: prioritizedNames) {
|
||||||
|
auto it = interfaces.find(name);
|
||||||
|
if(it != interfaces.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* const prefixes[] = { "192.168", "172.16.", "10.0" };
|
||||||
|
for(auto prefix : prefixes){
|
||||||
|
for(auto& itr : interfaces) {
|
||||||
|
auto interfaceIp = itr.second;
|
||||||
|
if (interfaceIp.find(prefix) == 0) {
|
||||||
|
return interfaceIp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "127.0.0.1";
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue