2018-10-02 10:17:31 +00:00
# include "lwip/opt.h"
# include "lwip/arch.h"
# include "lwip/api.h"
# include "httpserver-netconn.h"
# if LWIP_NETCONN
# ifndef HTTPD_DEBUG
# define HTTPD_DEBUG LWIP_DBG_OFF
# endif
static const char http_html_hdr [ ] = " HTTP/1.1 200 OK \r \n Content-type: text/html \r \n \r \n " ;
static const char http_index_html [ ] = " <html><head><title>Congrats!</title></head><body><h1>Welcome to our lwIP HTTP server!</h1><p>This is a small test page, served by httpserver-netconn.</body></html> " ;
/** Serve one HTTP connection accepted in the http thread */
static void
http_server_netconn_serve ( struct netconn * conn )
{
struct netbuf * inbuf ;
char * buf ;
u16_t buflen ;
err_t err ;
2018-10-22 18:33:35 +00:00
/* Read the data from the port, blocking if nothing yet there.
2018-10-02 10:17:31 +00:00
We assume the request ( the part we care about ) is in one netbuf */
err = netconn_recv ( conn , & inbuf ) ;
2018-10-22 18:33:35 +00:00
2018-10-02 10:17:31 +00:00
if ( err = = ERR_OK ) {
netbuf_data ( inbuf , ( void * * ) & buf , & buflen ) ;
2018-10-22 18:33:35 +00:00
2018-10-02 10:17:31 +00:00
/* Is this an HTTP GET command? (only check the first 5 chars, since
there are other formats for GET , and we ' re keeping it very simple ) */
if ( buflen > = 5 & &
buf [ 0 ] = = ' G ' & &
buf [ 1 ] = = ' E ' & &
buf [ 2 ] = = ' T ' & &
buf [ 3 ] = = ' ' & &
buf [ 4 ] = = ' / ' ) {
2018-10-22 18:33:35 +00:00
/* Send the HTML header
2020-02-15 20:44:02 +00:00
* subtract 1 from the size , since we don ' t send the \ 0 in the string
2018-10-02 10:17:31 +00:00
* NETCONN_NOCOPY : our data is const static , so no need to copy it
*/
netconn_write ( conn , http_html_hdr , sizeof ( http_html_hdr ) - 1 , NETCONN_NOCOPY ) ;
2018-10-22 18:33:35 +00:00
2018-10-02 10:17:31 +00:00
/* Send our HTML page */
netconn_write ( conn , http_index_html , sizeof ( http_index_html ) - 1 , NETCONN_NOCOPY ) ;
}
}
/* Close the connection (server closes in HTTP) */
netconn_close ( conn ) ;
2018-10-22 18:33:35 +00:00
2018-10-02 10:17:31 +00:00
/* Delete the buffer (netconn_recv gives us ownership,
so we have to make sure to deallocate the buffer ) */
netbuf_delete ( inbuf ) ;
}
/** The main function, never returns! */
static void
http_server_netconn_thread ( void * arg )
{
struct netconn * conn , * newconn ;
err_t err ;
LWIP_UNUSED_ARG ( arg ) ;
2018-10-22 18:33:35 +00:00
2018-10-02 10:17:31 +00:00
/* Create a new TCP connection handle */
/* Bind to port 80 (HTTP) with default IP address */
# if LWIP_IPV6
conn = netconn_new ( NETCONN_TCP_IPV6 ) ;
netconn_bind ( conn , IP6_ADDR_ANY , 80 ) ;
# else /* LWIP_IPV6 */
conn = netconn_new ( NETCONN_TCP ) ;
netconn_bind ( conn , IP_ADDR_ANY , 80 ) ;
# endif /* LWIP_IPV6 */
LWIP_ERROR ( " http_server: invalid conn " , ( conn ! = NULL ) , return ; ) ;
2018-10-22 18:33:35 +00:00
2018-10-02 10:17:31 +00:00
/* Put the connection into LISTEN state */
netconn_listen ( conn ) ;
2018-10-22 18:33:35 +00:00
2018-10-02 10:17:31 +00:00
do {
err = netconn_accept ( conn , & newconn ) ;
if ( err = = ERR_OK ) {
http_server_netconn_serve ( newconn ) ;
netconn_delete ( newconn ) ;
}
} while ( err = = ERR_OK ) ;
LWIP_DEBUGF ( HTTPD_DEBUG ,
( " http_server_netconn_thread: netconn_accept received error %d, shutting down " ,
err ) ) ;
netconn_close ( conn ) ;
netconn_delete ( conn ) ;
}
/** Initialize the HTTP server (start its thread) */
void
http_server_netconn_init ( void )
{
sys_thread_new ( " http_server_netconn " , http_server_netconn_thread , NULL , DEFAULT_THREAD_STACKSIZE , DEFAULT_THREAD_PRIO ) ;
}
# endif /* LWIP_NETCONN*/