8000 Progress on IPv6 · guestisp/esp32_https_server@79387a1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 79387a1

Browse files
committed
Progress on IPv6
1 parent 6e6bfb6 commit 79387a1

File tree

5 files changed

+152
-25
lines changed

5 files changed

+152
-25
lines changed

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,17 +205,19 @@ See the [Async-Server example](https://github.com/fhessel/esp32_https_server/tre
205205

206206
## Advanced Configuration
207207

208-
This section covers some advanced configuration options that allow you, for example, to customize the build process, but which might require more advanced programming skills and a more sophisticated IDE that just the default Arduino IDE.
208+
This section covers some advanced configuration options that allow you, for example, to customize the build process, but which might require more advanced programming skills and a more sophisticated IDE than just the default Arduino IDE.
209209

210-
### Saving Space by Reducing Functionality
210+
### Exclude Parts of the Library
211211

212-
To save program space on the microcontroller, there are some parts of the library that can be disabled during compilation and will then not be a part of your program.
212+
By setting build flags, you can exclude parts from the library. This can save you a bit of space in your final program or help you to disable unwanted functionality.
213213

214214
The following flags are currently available:
215215

216-
| Flag | Effect
217-
| ------------------------- | ---------------------------
218-
| HTTPS_DISABLE_SELFSIGNING | Removes the code for generating a self-signed certificate at runtime. You will need to provide certificate and private key data from another data source to use the `HTTPSServer`.
216+
| Flag | Effect
217+
| --------------------------- | ---------------------------
218+
| `HTTPS_DISABLE_SELFSIGNING` | Removes the code for generating a self-signed certificate at runtime. You will need to provide certificate and private key data from another data source to use the `HTTPSServer`.
219+
| `HTTPS_DISABLE_IPV4` | Disable support for IPv4. Cannot be used together with `HTTPS_DISABLE_IPV6`.
220+
| `HTTPS_DISABLE_IPV6` | Disable support for IPv6. Cannot be used together with `HTTPS_DISABLE_IPV4`.
219221

220222
Setting these flags requires a build environment that gives you some control of the compiler, as libraries are usually compiled separately, so just doing a `#define HTTPS_SOMETHING` in your sketch will not work.
221223

src/HTTPSServer.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,25 @@
22

33
namespace httpsserver {
44

5-
6-
HTTPSServer::HTTPSServer(SSLCert * cert, const uint16_t port, const uint8_t maxConnections, const in_addr_t bindAddress):
7-
HTTPServer(port, maxConnections, bindAddress),
5+
#ifndef HTTPS_DISABLE_IPV4
6+
HTTPSServer::HTTPSServer(SSLCert * cert, IPAddress bindAddress,
7+
const uint16_t portHTTPS, const uint8_t maxConnections):
8+
HTTPServer(bindAddress, portHTTPS, maxConnections),
89
_cert(cert) {
910

1011
// Configure runtime data
1112
_sslctx = NULL;
1213
}
14+
#endif
15+
16+
#ifndef HTTPS_DISABLE_IPV6
17+
HTTPSServer::HTTPSServer(SSLCert * cert, IPv6Address bindAddress,
18+
const uint16_t portHTTPS, const uint8_t maxConnections):
19+
HTTPServer(bindAddress, portHTTPS, maxConnections),
20+
_cert(cert) {
21+
_sslctx = NULL;
22+
}
23+
#endif
1324

1425
HTTPSServer::~HTTPSServer() {
1526

src/HTTPSServer.hpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
// Arduino stuff
88
#include <Arduino.h>
9+
#ifndef HTTPS_DISABLE_IPV4
10+
#include <IPAddress.h>
11+
#endif
12+
#ifndef HTTPS_DISABLE_IPV6
13+
#include <IPv6Address.h>
14+
#endif
915

1016
// Required for SSL
1117
#include "openssl/ssl.h"
@@ -29,7 +35,35 @@ namespace httpsserver {
2935
*/
3036
class HTTPSServer : public HTTPServer {
3137
public:
32-
HTTPSServer(SSLCert * cert, const uint16_t portHTTPS = 443, const uint8_t maxConnections = 4, const in_addr_t bindAddress = 0);
38+
#ifndef HTTPS_DISABLE_IPV4
39+
/**
40+
* \brief Create a server instance that binds to an IPv4 address
41+
*
42+
* \param cert A reference to an SSLCert to use with the server. Must be valid during the server's lifetime
43+
* \param bindAddress IPAddress to bind to. Use IPAddress() to bind to all IPv4 interfaces.
44+
* \param port TCP port to run the server on. Defaults to 443 (HTTPS default)
45+
* \param maxConnections Maximum number of parallel connections handled by the server. Defaults to 4 (more might cause trouble on ESP32s with low memory)
46+
*/
47+
HTTPSServer(SSLCert * cert, const IPAddress bindAddress = IPAddress(),
48+
const uint16_t portHTTPS = 443, const uint8_t maxConnections = 4);
49+
#endif
50+
#ifndef HTTPS_DISABLE_IPV6
51+
#ifndef HTTPS_DISABLE_IPV4
52+
/**
53+
* \brief Create a server instance that binds to an IPv6 address
54+
*
55+
* \param cert A reference to an SSLCert to use with the server. Must be valid during the server's lifetime
56+
* \param bindAddress IPAddress to bind to. Use IPv6Address() to bind to all IPv6 interfaces.
57+
* \param port TCP port to run the server on. Defaults to 443 (HTTPS default)
58+
* \param maxConnections Maximum number of parallel connections handled by the server. Defaults to 4 (more might cause trouble on ESP32s with low memory)
59+
*/
60+
HTTPSServer(SSLCert * cert, const IPv6Address bindAddress = IPv6Address(),
61+
const uint16_t portHTTPS = 443, const uint8_t maxConnections = 4);
62+
#else
63+
HTTPSServer(SSLCert * cert, const IPv6Address bindAddress,
64+
const uint16_t portHTTPS = 443, const uint8_t maxConnections = 4);
65+
#endif
66+
#endif
3367
virtual ~HTTPSServer();
3468

3569
private:

src/HTTPServer.cpp

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,30 @@
22

33
namespace httpsserver {
44

5+
#ifndef HTTPS_DISABLE_IPV4
6+
HTTPServer::HTTPServer(const IPAddress bindAddress, const uint16_t port, const uint8_t maxConnections):
7+
_port(port),
8+
_maxConnections(maxConnections) {
9+
// in_addr_t is an uint32, so no copying here
10+
_bindAddressesV4.push_back(bindAddress);
511

6-
HTTPServer::HTTPServer(const uint16_t port, const uint8_t maxConnections, const in_addr_t bindAddress):
7-
_port(port),
8-
_maxConnections(maxConnections),
9-
_bindAddress(bindAddress) {
12+
// Create space for the connections
13+
_connections = new HTTPConnection*[maxConnections];
14+
for(uint8_t i = 0; i < maxConnections; i++) _connections[i] = NULL;
15+
16+
// Configure runtime data
17+
_socket = -1;
18+
_running = false;
19+
}
20+
#endif
21+
22+
#ifndef HTTPS_DISABLE_IPV6
23+
HTTPServer::HTTPServer(const IPv6Address bindAddress, const uint16_t port, const uint8_t maxConnections):
24+
_port(port),
25+
_maxConnections(maxConnections) {
26+
// IPv6 is a buffer and we don't control bindAddress, so copy it.
27+
_bindAddressesV6.push_back(in6_addr());
28+
memcpy(_bindAddressesV6[0].un.u8_addr, (const uint8_t*)bindAddress, sizeof(in6_addr));
1029

1130
// Create space for the connections
1231
_connections = new HTTPConnection*[maxConnections];
@@ -16,6 +35,7 @@ HTTPServer::HTTPServer(const uint16_t port, const uint8_t maxConnections, const
1635
_socket = -1;
1736
_running = false;
1837
}
38+
#endif
1939

2040
HTTPServer::~HTTPServer() {
2141

@@ -168,16 +188,25 @@ int HTTPServer::createConnection(int idx) {
168188
* This method prepares the tcp server socket
169189
*/
170190
uint8_t HTTPServer::setupSocket() {
171-
// (AF_INET = IPv4, SOCK_STREAM = TCP)
172-
_socket = socket(AF_INET, SOCK_STREAM, 0);
173-
174-
if (_socket>=0) {
175-
_sock_addr.sin_family = AF_INET;
191+
if (_bindAddressesV4.size()>0) {
192+
sockaddr_in *v4addr = (sockaddr_in*)(&_sock_addr);
193+
v4addr->sin_family = AF_INET;
176194
// Listen on all interfaces
177-
_sock_addr.sin_addr.s_addr = _bindAddress;
195+
v4addr->sin_addr.s_addr = _bindAddressesV4[0];
178196
// Set the server port
179-
_sock_addr.sin_port = htons(_port);
197+
v4addr->sin_port = htons(_port);;
198+
} else {
199+
sockaddr_in6 *v6addr = (sockaddr_in6*)(&_sock_addr);
200+
v6addr->sin6_family = AF_INET6;
201+
// Listen on all interfaces
202+
v6addr->sin6_addr = _bindAddressesV6[0];
203+
// Set the server port
204+
v6addr->sin6_port = htons(_port);
205+
}
206+
207+
_socket = socket(_sock_addr.sa_family, SOCK_STREAM, 0);
180208

209+
if (_socket >= 0) {
181210
// Now bind the TCP socket we did create above to the socket address we specified
182211
// (The TCP-socket now listens on 0.0.0.0:port)
183212
int err = bind(_socket, (struct sockaddr* )&_sock_addr, sizeof(_sock_addr));

src/HTTPServer.hpp

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@
66

77
// Arduino stuff
88
#include <Arduino.h>
9+
#ifndef HTTPS_DISABLE_IPV4
10+
#include <IPAddress.h>
11+
#ifdef HTTPS_DISABLE_IPV4
12+
#error You cannot HTTPS_DISABLE_IPV4 and HTTPS_DISABLE_IPV6 at the same time
13+
#endif
14+
#endif
15+
#ifndef HTTPS_DISABLE_IPV6
16+
#include <IPv6Address.h>
17+
#ifdef HTTPS_DISABLE_IPV4
18+
#error You cannot HTTPS_DISABLE_IPV4 and HTTPS_DISABLE_IPV6 at the same time
19+
#endif
20+
#endif
921

1022
// Required for sockets
1123
#include "lwip/netdb.h"
@@ -29,7 +41,30 @@ namespace httpsserver {
2941
*/
3042
class HTTPServer : public ResourceResolver {
3143
public:
32-
HTTPServer(const uint16_t portHTTPS = 80, const uint8_t maxConnections = 8, const in_addr_t bindAddress = 0);
44+
#ifndef HTTPS_DISABLE_IPV4
45+
/**
46+
* \brief Create a server instance that binds to an IPv4 address
47+
*
48+
* \param bindAddress IPAddress to bind to. Use IPAddress() to bind to all IPv4 interfaces.
49+
* \param port TCP port to run the server on. Defaults to 80 (HTTP default)
50+
* \param maxConnections Maximum number of parallel connections handled by the server. Defaults to 8.
51+
*/
52+
HTTPServer(const IPAddress bindAddress = IPAddress(), const uint16_t port = 80, const uint8_t maxConnections = 8);
53+
#endif
54+
#ifndef HTTPS_DISABLE_IPV6
55+
#ifdef HTTPS_DISABLE_IPV4
56+
HTTPServer(const IPv6Address bindAddress, const uint16_t port = 80, const uint8_t maxConnections = 8);
57+
#else
58+
/**
59+
* \brief Create a server instance that binds to an IPv6 address
60+
*
61+
* \param bindAddress IPv6Address to bind to. Use IPv6Address() to bind to all IPv6 interfaces.
62+
* \param port TCP port to run the server on. Defaults to 80 (HTTP default)
63+
* \param maxConnections Maximum number of parallel connections handled by the server. Defaults to 8.
64+
*/
65+
HTTPServer(const IPv6Address bindAddress = IPv6Address(), const uint16_t port = 80, const uint8_t maxConnections = 8);
66+
#endif
67+
#endif
3368
virtual ~HTTPServer();
3469

3570
uint8_t start();
@@ -47,8 +82,24 @@ class HTTPServer : public ResourceResolver {
4782

4883
// Max parallel connections that the server will accept
4984
const uint8_t _maxConnections;
50-
// Address to bind to (0 = all interfaces)
51-
const in_addr_t _bindAddress;
85+
#ifndef HTTPS_DISABLE_IPV4
86+
/**
87+
* \brief IPv4 addresses to bind to (0 = all IPv4 interfaces)
88+
*
89+
* To enable IPv4, add at least one element to this vector.
90+
* The content cannot be changed while the server is _running
91+
*/
92+
std::vector<in_addr_t> _bindAddressesV4;
93+
#endif
94+
#ifndef HTTPS_DISABLE_IPV6
95+
/**
96+
* \brief IPv6 addresses to bind to (0 = all IPv6 interfaces)
97+
*
98+
* To enable IPv6, add at least one element to this vector.
99+
* The content cannot be changed while the server is _running
100+
*/
101+
std::vector<in6_addr> _bindAddressesV6;
102+
#endif
52103

53104
//// Runtime data ============================================
54105
// The array of connections that are currently active
@@ -59,7 +110,7 @@ class HTTPServer : public ResourceResolver {
59110
int _socket;
60111

61112
// The server socket address, that our service is bound to
62-
sockaddr_in _sock_addr;
113+
sockaddr _sock_addr;
63114
// Headers that are included in every response
64115
HTTPHeaders _defaultHeaders;
65116

0 commit comments

Comments
 (0)
0