ESP32_ChinaDieselHeater_Con.../lib/esp32_https_server-master/docs/index.html

213 lines
23 KiB
HTML
Raw Permalink Normal View History

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>ESP32 HTTPS Server: ESP32 HTTPS Server</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
$(document).ready(initResizable);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">ESP32 HTTPS Server
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('index.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="headertitle">
<div class="title">ESP32 HTTPS Server </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>This repository contains an HTTPS server library that can be used with the <a href="https://github.com/espressif/arduino-esp32">ESP32 Arduino Core</a>. It supports HTTP as well.</p>
<h2>Features</h2>
<ul>
<li>Providing support for HTTP, HTTPS or both at the same time</li>
<li>Handling requests in callback functions that can be bound to URLs, like for example in Express or Servlets.</li>
<li>Abstraction of handling the HTTP stuff and providing a simple API for it, eg. to access parameters, headers, HTTP Basic Auth etc.</li>
<li>Using middleware functions as proxy to every request to perform central tasks like authentication or logging.</li>
<li>Make use of the built-in encryption of the ESP32 module for HTTPS.</li>
<li>Handle multiple clients in parallel (max. 3-4 TLS clients due to memory limits).</li>
<li>Usage of <code>Connection: keep-alive</code> and SSL session reuse to reduce the overhead of SSL handshakes and speed up data transfer.</li>
</ul>
<h2>Dependencies</h2>
<p>The library is self-contained and just needs the Arduino and ESP32 system libraries. Running the examples requires the WiFi library in addition to that.</p>
<h2>Setup Instructions</h2>
<p>The steps to install this library depend on the IDE you are using. PlatformIO is recommended as you have more options to configure the library (see <a href="#advanced-configuration">Advanced Configuration</a>), but the library can be used with the plain Arduino IDE.</p>
<h3>PlatformIO (Recommended)</h3>
<p>The library is listed in PlatformIO's <a href="https://platformio.org/lib/show/5887/esp32_https_server/">library registry</a>. If you're using the IDE, search for <code>esp32_https_server</code> and install it, on the command line, just run:</p>
<div class="fragment"><div class="line">pio lib install &quot;esp32_https_server&quot;</div></div><!-- fragment --><p>New release can take one or two days before they get picked up by the library crawler which makes them available in the registry. The version numbers of <a href="https://github.com/fhessel/esp32_https_server/releases">releases</a> are based on <a href="https://semver.org/">semantic versioning</a>.</p>
<p>Add the library to your <code>platform.ini</code> like in the following example:</p>
<div class="fragment"><div class="line">[platformio]</div><div class="line">env_default = wrover</div><div class="line"></div><div class="line">[env:wrover]</div><div class="line">platform = espressif32</div><div class="line">board = esp32dev</div><div class="line">framework = arduino</div><div class="line">lib_deps = esp32_https_server</div></div><!-- fragment --><p>If you want a specific version, you can use a notation like <code>lib_deps = esp32_https_server@0.3.0</code>. More information on this can be found in the <a href="https://docs.platformio.org/en/latest/projectconf/section_env_library.html">PlatformIO documentation</a>.</p>
<p>To use the current master of the library, don't add it to your <code>platform.ini</code> but go to your project's <code>libs</code> folder and run the following command to get a copy of repository:</p>
<div class="fragment"><div class="line">git clone https://github.com/fhessel/esp32_https_server.git</div></div><!-- fragment --><blockquote class="doxtable">
<p><b>Note:</b> While the <code>master</code> branch should contain a running version of the library at any time, the API might already have changes towards the next major release. So for a stable setup, it is recommended to use a published release. </p>
</blockquote>
<h3>Arduino IDE</h3>
<p>You can install the library using Arduino IDE's <a href="https://www.arduino.cc/en/Guide/Libraries">library manager</a>. In the <em>Sketch</em> menu, click on <em>Include Library</em> and select <em>Manage Libraries...</em> directly at the top of the menu. Then search for "ESP32 HTTPS Server" and click on the <em>Install</em> button.</p>
<p>Alternatively, you can download <a href="https://github.com/fhessel/esp32_https_server/releases">a release</a> and extract it into your <code>Arduino/libraries</code> folder. Then restart your IDE.</p>
<p>If you want to use the latest <code>master</code> branch, open a command line, navigate to the libraries folder and run:</p>
<div class="fragment"><div class="line">git clone https://github.com/fhessel/esp32_https_server.git</div></div><!-- fragment --><blockquote class="doxtable">
<p><b>Note:</b> While the <code>master</code> branch should contain a running version of the library at any time, the API might already have changes towards the next major release. So for a stable setup, it is recommended to use a published release. </p>
</blockquote>
<h2>Examples</h2>
<blockquote class="doxtable">
<p><b>Note:</b> To run the examples (except for the <em>Self-Signed-Certificates</em> example), you need to execute the script extras/create_cert.sh first (see <a href="https://github.com/fhessel/esp32_https_server/issues/26">Issue #26</a> for Windows). This script will create a simple CA to sign certificates that are used with the examples. Some notes on the usage can be found in the extras/README.md file. </p>
</blockquote>
<p>You will find several examples showing how you can use the library:</p>
<ul>
<li><a href="examples/Static-Page/Static-Page.ino">Static-Page</a>: Short example showing how to serve some static resources with the server. You should start with this sketch and get familiar with it before having a look at the more complex examples.</li>
<li><a href="examples/Parameters/Parameters.ino">Parameters</a>: Shows how you can access request parameters (the part after the question mark in the URL) or parameters in dynamic URLs (like /led/1, /led/2, ...)</li>
<li><a href="examples/Put-Post-Echo/Put-Post-Echo.ino">Put-Post-Echo</a>: Implements a simple echo service for PUT and POST requests that returns the request body as response body. Also shows how to differentiate between multiple HTTP methods for the same URL.</li>
<li><a href="examples/HTTPS-and-HTTP/HTTPS-and-HTTP.ino">HTTPS-and-HTTP</a>: Shows how to serve resources via HTTP and HTTPS in parallel and how to check if the user is using a secure connection during request handling</li>
<li><a href="examples/Middleware/Middleware.ino">Middleware</a>: Shows how to use the middleware API for logging. Middleware functions are defined very similar to webservers like Express.</li>
<li><a href="examples/Authentication/Authentication.ino">Authentication</a>: Implements a chain of two middleware functions to handle authentication and authorization using HTTP Basic Auth.</li>
<li><a href="examples/Async-Server/Async-Server.ino">Async-Server</a>: Like the Static-Page example, but the server runs in a separate task on the ESP32, so you do not need to call the loop() function in your main sketch.</li>
<li><a href="examples/Websocket-Chat/Websocket-Chat.ino">Websocket-Chat</a>: Provides a browser-based chat built on top of websockets. <b>Note:</b> Websockets are still under development!</li>
<li><a href="examples/Parameter-Validation/Parameter-Validation.ino">Parameter-Validation</a>: Shows how you can integrate validator functions to do formal checks on parameters in your URL.</li>
<li><a href="examples/Self-Signed-Certificate/Self-Signed-Certificate.ino">Self-Signed-Certificate</a>: Shows how to generate a self-signed certificate on the fly on the ESP when the sketch starts. You do not need to run <code>create_cert.sh</code> to use this example.</li>
<li><a href="examples/REST-API/REST-API.ino">REST-API</a>: Uses <a href="https://arduinojson.org/">ArduinoJSON</a> and <a href="https://github.com/me-no-dev/arduino-esp32fs-plugin">SPIFFS file upload</a> to serve a small web interface that provides a REST API.</li>
</ul>
<p>If you encounter error messages that cert.h or private_key.h are missing when running an example, make sure to run create_cert.sh first (see Setup Instructions).</p>
<p>You might also want to check out the (work-in-progress) <a href="https://fhessel.github.io/esp32_https_server/">Documentation</a>.</p>
<h2>Get Started</h2>
<p>The following includes are required to be able to setup the server.</p>
<div class="fragment"><div class="line">{C++}</div><div class="line">// Inlcudes for setting up the server</div><div class="line">#include &lt;HTTPSServer.hpp&gt;</div><div class="line"></div><div class="line">// Define the certificate data for the server (Certificate and private key)</div><div class="line">#include &lt;SSLCert.hpp&gt;</div><div class="line"></div><div class="line">// Includes to define request handler callbacks</div><div class="line">#include &lt;HTTPRequest.hpp&gt;</div><div class="line">#include &lt;HTTPResponse.hpp&gt;</div><div class="line"></div><div class="line">// Required do define ResourceNodes</div><div class="line">#include &lt;ResourceNode.hpp&gt;</div><div class="line"></div><div class="line">// Easier access to the classes of the server</div><div class="line">using namespace httpsserver</div></div><!-- fragment --> <h3>Create Server Instance</h3>
<p>You can create your server instance like shown below:</p>
<p><b>For HTTP:</b></p>
<div class="fragment"><div class="line">{C++}</div><div class="line">HTTPServer myServer = HTTPServer();</div></div><!-- fragment --><p><b>For HTTPS:</b></p>
<div class="fragment"><div class="line">{C++}</div><div class="line">// Create certificate data (see extras/README.md on how to create it)</div><div class="line">SSLCert cert = SSLCert(</div><div class="line"> crt_DER, // DER-formatted certificate data</div><div class="line"> crt_DER_len, // length of the certificate data</div><div class="line"> key_DER, // private key for that certificate</div><div class="line"> key_DER_len // Length of the private key</div><div class="line">);</div><div class="line"></div><div class="line">// Setup the server with default configuration and the</div><div class="line">// certificate that has been specified before</div><div class="line">HTTPSServer myServer = HTTPSServer(cert);</div></div><!-- fragment --><p>By default, the server will listen on port 443. If you want to change that (or some other options), you can have a look at the optional parameters of the <a href="https://fhessel.github.io/esp32_https_server/classhttpsserver_1_1HTTPServer.html"><code>HTTPServer</code></a> or <a href="https://fhessel.github.io/esp32_https_server/classhttpsserver_1_1HTTPSServer.html"><code>HTTPSServer</code></a> constructors.</p>
<p>The only difference between the HTTP and HTTPS version is the certificate which you have to configure. Keep in mind that each opened connection of the TLS-enabled <code>HTTPSServer</code> requires additional 40 to 50 kB of heap memory for the TLS connection itself. This has to be considered when increasing <code>maxConnections</code>.</p>
<h3>Add Resources to the Server</h3>
<p>Every <em>route</em> (or path) that should be accessible on the server has to be configured as a so-called <code>ResourceNode</code>. Such a node links a handler function to a specific route (like <code>/test</code>) and HTTP method (like <code>GET</code>). The handler function could look like this:</p>
<div class="fragment"><div class="line">{C++}</div><div class="line">void handleRoot(HTTPRequest * req, HTTPResponse * res) {</div><div class="line"> // We want to deliver an HTML page, so we set the content type</div><div class="line"> res-&gt;setHeader(&quot;Content-Type&quot;, &quot;text/html&quot;);</div><div class="line"> // The response implements the Print interface, so you can use it just like</div><div class="line"> // you would write to Serial etc.</div><div class="line"> res-&gt;println(&quot;&lt;!DOCTYPE html&gt;&quot;);</div><div class="line"> res-&gt;println(&quot;&lt;html&gt;&quot;);</div><div class="line"> res-&gt;println(&quot;&lt;head&gt;&lt;title&gt;Hello World!&lt;/title&gt;&lt;/head&gt;&quot;);</div><div class="line"> res-&gt;println(&quot;&lt;body&gt;&quot;);</div><div class="line"> res-&gt;println(&quot;&lt;h1&gt;Hello World!&lt;/h1&gt;&quot;);</div><div class="line"> res-&gt;print(&quot;&lt;p&gt;... from your ESP32!&lt;/p&gt;&quot;);</div><div class="line"> res-&gt;println(&quot;&lt;/body&gt;&quot;);</div><div class="line"> res-&gt;println(&quot;&lt;/html&gt;&quot;);</div><div class="line">}</div></div><!-- fragment --><p>As you can see, the function gets references to the <a href="https://fhessel.github.io/esp32_https_server/classhttpsserver_1_1HTTPRequest.html"><code>HTTPRequest</code></a> and <a href="https://fhessel.github.io/esp32_https_server/classhttpsserver_1_1HTTPResponse.html"><code>HTTPResponse</code></a>. You can use the request to read headers, parameters, authentication information etc. The response can be used to send data to the client, set headers or HTTP status codes.</p>
<p>Now we need to tell the server which URL should be served by this function. This can be done by creating a <a href="https://fhessel.github.io/esp32_https_server/classhttpsserver_1_1ResourceNode.html"><code>ResourceNode</code></a> (usually in your <code>setup()</code> function).</p>
<div class="fragment"><div class="line">{C++}</div><div class="line">ResourceNode * nodeRoot = new ResourceNode(&quot;/&quot;, &quot;GET&quot;, &amp;handleRoot);</div></div><!-- fragment --><p>The first parameter defines the route. It should always start with a slash, and using just a slash like in this example means that the function will be called for requests to the server's root (like <a href="https://10.0.x.x/">https://10.0.x.x/</a>).</p>
<p>The second parameter is the HTTP method, <code>"GET"</code> in this case.</p>
<p>Finally, you pass a reference to the request handler function to link it to the route and method.</p>
<p>Now you just need to register the created <a href="https://fhessel.github.io/esp32_https_server/classhttpsserver_1_1ResourceNode.html"><code>ResourceNode</code></a> at your server:</p>
<div class="fragment"><div class="line">{C++}</div><div class="line">myServer.registerNode(nodeRoot);</div></div><!-- fragment --><p>That's everything you need to do for a single web page on your server.</p>
<p>Note that you can define a single <a href="https://fhessel.github.io/esp32_https_server/classhttpsserver_1_1ResourceNode.html"><code>ResourceNode</code></a> via <code>HTTPServer::setDefaultNode()</code>, which will be called if no other node on the server matches. Method and route are ignored in this case. Most examples use this to define a 404-handler, which might be a good idea for most scenarios. In case no default node is specified, the server will return with a small error page if no matching route is found.</p>
<h3>Start the Server</h3>
<p>A call to <a href="https://fhessel.github.io/esp32_https_server/classhttpsserver_1_1HTTPServer.html#a1b1b6bce0b52348ca5b5664cf497e039"><code>HTTPServer::start()</code></a> will start the server so that it is listening on the previously specified port:</p>
<div class="fragment"><div class="line">{C++}</div><div class="line">myServer.start();</div></div><!-- fragment --><p>This code usually goes into your <code>setup()</code> function. You can use <code>HTTPServer::isRunning()</code> to check whether the server started successfully.</p>
<p>By default, you need to pass control to the server explicitly. This is done by calling the <a href="https://fhessel.github.io/esp32_https_server/classhttpsserver_1_1HTTPServer.html#af8f68f5ff6ad101827bcc52217249fe2"><code>HTTPServer::loop()</code></a> function, which you usually will put into your Arduino sketch's <code>loop()</code> function. Once called, the server will first check for incoming connection (up to the maximum connection count that has been defined in the constructor), and then handle every open connection if it has new data on the socket. So your request handler functions will be called during the call to <code>loop()</code>. Note that if one of your handler functions is blocking, it will block all other connections as well.</p>
<h3>Running the Server asynchronously</h3>
<p>If you want to have the server running in the background (and not calling <code>loop()</code> by yourself every few milliseconds), you can make use of the ESP32's task feature and put the whole server in a separate task.</p>
<p>See the <a href="https://github.com/fhessel/esp32_https_server/tree/master/examples/Async-Server">Async-Server example</a> to see how this can be done.</p>
<h2>Advanced Configuration</h2>
<p>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.</p>
<h3>Saving Space by Reducing Functionality</h3>
<p>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.</p>
<p>The following flags are currently available:</p>
<table class="doxtable">
<tr>
<th>Flag </th><th>Effect </th></tr>
<tr>
<td>HTTPS_DISABLE_SELFSIGNING </td><td>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 <code>HTTPSServer</code>. </td></tr>
</table>
<p>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 <code>#define HTTPS_SOMETHING</code> in your sketch will not work.</p>
<p><b>Example: Configuration with PlatformIO</b></p>
<p>To set these flags in PlatformIO, you can modify your <code>platformio.ini</code>. To disable for example the self-signed-certificates part of the library, the file could look like this:</p>
<div class="fragment"><div class="line">[env:wroom]</div><div class="line">platform = espressif32</div><div class="line">board = esp32dev</div><div class="line">framework = arduino</div><div class="line">lib_deps = esp32_https_server</div><div class="line">build_flags =</div><div class="line"> -DHTTPS_DISABLE_SELFSIGNING</div></div><!-- fragment --><p>Note the <code>-D</code> in front of the actual flag name, that passes this flag as a definition to the preprocessor. Multiple flags can be added one per line.</p>
<h3>Configure Logging</h3>
<p>The server provides some internal logging, which is activated on level <code>INFO</code> by default. This will look like this on your serial console:</p>
<div class="fragment"><div class="line">[HTTPS:I] New connection. SocketFID=55</div><div class="line">[HTTPS:I] Request: GET / (FID=55)</div><div class="line">[HTTPS:I] Connection closed. Socket FID=55</div></div><!-- fragment --><p>Logging output can also be controlled by using compiler flags. This requires an advanced development environment like explained in <a href="#saving-space-by-reducing-functionality">Saving Space by Reducing Functionality</a>.</p>
<p>There are two parameters that can be configured:</p>
<ul>
<li><code>HTTPS_LOGLEVEL</code> defines the log level to use</li>
<li><code>HTTPS_LOGTIMESTAMP</code> adds a timestamp (based on uptime) to each log entry</li>
</ul>
<table class="doxtable">
<tr>
<th>Value of <code>HTTPS_LOGLEVEL</code> </th><th>Error </th><th>Warning </th><th>Info </th><th>Debug </th></tr>
<tr>
<td>0 </td><td></td><td></td><td></td><td></td></tr>
<tr>
<td>1 </td><td></td><td></td><td></td><td></td></tr>
<tr>
<td>2 </td><td></td><td></td><td></td><td></td></tr>
<tr>
<td>3 </td><td></td><td></td><td></td><td></td></tr>
<tr>
<td>4 </td><td></td><td></td><td></td><td></td></tr>
</table>
<p><b>Example: Configuration with PlatformIO</b></p>
<p>To set these flags in PlatformIO, you can modify your <code>platformio.ini</code>. The following entries set the minimum log level to warning and enable timestamps</p>
<div class="fragment"><div class="line">[env:wroom]</div><div class="line">platform = espressif32</div><div class="line">board = esp32dev</div><div class="line">framework = arduino</div><div class="line">lib_deps = esp32_https_server</div><div class="line">build_flags =</div><div class="line"> -DHTTPS_LOGLEVEL=2</div><div class="line"> -DHTTPS_LOGTIMESTAMP</div></div><!-- fragment --> </div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.13 </li>
</ul>
</div>
</body>
</html>