Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,17 @@

## Quick Start

The demo application can be compiled using the **POSIX port**, allowing you to evaluate it directly in a **GitHub Codespace** or on your PC! For embedded targets, the following RTOS options are supported: **ChibiOS, FreeRTOS, and ThreadX** (provided you have an IP stack like **LwIP**).
The demo application can be compiled using the **POSIX port**, allowing you to evaluate it directly in a **GitHub Codespace** or on your PC! For embedded targets, the following RTOS options are supported: **ChibiOS, FreeRTOS, and ThreadX** (provided you have an IP stack like **LwIP**).

### Zephyr RTOS

Initial Zephyr support is now available. The existing POSIX abstractions can be reused by enabling Zephyr's BSD socket stack. When building under Zephyr ensure the following Kconfig options are selected:

- `CONFIG_NET_SOCKETS=y`
- `CONFIG_DNS_RESOLVER=y`
- `CONFIG_NET_HOSTNAME_ENABLE=y` (optional but recommended if hostname resolution is required)

No additional source changes are required beyond including this module in your Zephyr CMake build and linking it against your Zephyr application target.

⚠️ **Note:** If running in **GitHub Codespaces**, the application will use **port forwarding**. Once the server starts on port 8080, you'll get a browser link for accessing the web interface on that port.

Expand Down
4 changes: 2 additions & 2 deletions include/qoraal-http/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/* CFG_JSON_DISABLE
If defined, littlefs filesystem will be disabled.
*/
// #define CFG_JSON_DISABLE 1
#define CFG_JSON_DISABLE 1


/* CFG_HTTPSERVER_TLS_DISABLE
Expand All @@ -17,7 +17,7 @@
/* CFG_HTTPCLIENT_TLS_DISABLE
If defined, the http server will enable mbedtls.
*/
#define CFG_HTTPCLIENT_TLS_DISABLE 1
// #define CFG_HTTPCLIENT_TLS_DISABLE 1

/* CFG_MBEDTLS_PLATFORM_INIT_ENABLE
If defined, the mbedtls platform init function will be called.
Expand Down
34 changes: 30 additions & 4 deletions include/qoraal-http/qoraal.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,38 @@
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
typedef int socklen_t;
#elif defined(CONFIG_ZEPHYR)
#include <zephyr/kernel.h>
#include <zephyr/net/socket.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/hostname.h>
#include <zephyr/sys/fdtable.h>

#define closesocket zsock_close
#define ioctlsocket zsock_ioctl

#ifndef getaddrinfo
#define getaddrinfo zsock_getaddrinfo
#endif

#ifndef freeaddrinfo
#define freeaddrinfo zsock_freeaddrinfo
#endif

#ifndef gai_strerror
#define gai_strerror zsock_gai_strerror
#endif

#ifndef addrinfo
#define addrinfo zsock_addrinfo
#endif

#elif __has_include(<lwip/inet.h>) || (defined QORAAL_CFG_USE_LWIP && QORAAL_CFG_USE_LWIP)
// Looks like LWIP is present
#include <lwip/opt.h>
#include <lwip/def.h>
#include <lwip/mem.h>
#include <lwip/pbuf.h>
#include <lwip/opt.h>
#include <lwip/def.h>
#include <lwip/mem.h>
#include <lwip/pbuf.h>
#include <lwip/sys.h>
#include <lwip/stats.h>
#include <lwip/snmp.h>
Expand Down
20 changes: 17 additions & 3 deletions src/httpclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,28 @@
*/


#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include "qoraal/qoraal.h"
#include "qoraal-http/config.h"
#include "qoraal-http/qoraal.h"
#include "qoraal-http/httpclient.h"
#include "qoraal-http/httpparse.h"
#include "qoraal-http/httpserver.h"
#if !defined CFG_HTTPSERVER_TLS_DISABLE
#include "qoraal-http/mbedtls/mbedtlsutils.h"
#endif


#include <string.h>
#include <stdio.h>
#include "qoraal/qoraal.h"
#include "qoraal-http/config.h"
#include "qoraal-http/qoraal.h"
#include "qoraal-http/httpclient.h"
#include "qoraal-http/httpparse.h"
#if !defined CFG_HTTPCLIENT_TLS_DISABLE
#if !defined CFG_HTTPCLIENT_TLS_DISABLE
#include "qoraal-http/mbedtls/mbedtlsutils.h"
#endif

Expand Down Expand Up @@ -237,8 +251,8 @@ httpclient_connect (HTTP_CLIENT_T* client, const struct sockaddr_in* addr, void
#if !defined CFG_HTTPCLIENT_TLS_DISABLE
if (client->ssl) {
do {
struct fd_set fdread;
struct fd_set fdex;
fd_set fdread;
fd_set fdex;
struct timeval tv;

status = mbedtls_ssl_handshake((mbedtls_ssl_context *)client->ssl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
SOFTWARE.
*/

#include "../config.h"
#include "qoraal-http/config.h"
#if !defined CFG_HTTPSERVER_TLS_DISABLE || !defined CFG_HTTPCLIENT_TLS_DISABLE
#include <time.h>
#include "mbedtlsutils.h"
#include "qoraal-http/mbedtls/mbedtlsutils.h"
#include "threading_alt.h"
#include "qoraal/qoraal.h"
#include "qoraal-http/qoraal.h"
Expand Down Expand Up @@ -122,13 +122,15 @@ mbedtls_debug_cb ( void *ctx, int level, const char *file, int line,
"TLS : : %s:%d: %s",file,line,str) ;
}

#if 0
static mbedtls_time_t
mbedtls_time_cb ( mbedtls_time_t* time )
{
return rtc_time () ;
}
#endif

#if defined(MBEDTLS_THREADING_ALT)
#if 0 // defined(MBEDTLS_THREADING_ALT)
static void
mutex_init( mbedtls_threading_mutex_t * mtx)
{
Expand Down Expand Up @@ -231,7 +233,7 @@ mbedtlsutils_start (void)
mbedtls_free_cb ) ;
#endif

#if defined(MBEDTLS_THREADING_ALT)
#if 0 //defined(MBEDTLS_THREADING_ALT)
mbedtls_threading_set_alt(mutex_init, mutex_free, mutex_lock, mutex_unlock );
#endif

Expand All @@ -255,7 +257,7 @@ mbedtlsutils_start (void)
mbedtls_debug_set_threshold( 1 );
#endif

mbedtls_platform_set_time (mbedtls_time_cb) ;
// mbedtls_platform_set_time (mbedtls_time_cb) ;

#if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_cache_set_max_entries( &_ssl_cache, 5 );
Expand Down Expand Up @@ -472,14 +474,14 @@ mbedtls_release_server_config (void)
}
}

#if defined QORAAL_CFG_USE_LWIP
#if 1 // defined QORAAL_CFG_USE_LWIP
int
mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, uint32_t timeout)
{
int ret = 0 ;
int fd = (int)ctx;
struct fd_set readSet;
struct fd_set exceptSet;
fd_set readSet;
fd_set exceptSet;
struct timeval tv;

if( fd < 0 ) {
Expand All @@ -496,7 +498,7 @@ mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, uint32_t ti
tv.tv_sec = timeout/1000 ; // TIMEOUT_PER_IDLE_SELECT_SEC;
tv.tv_usec = timeout%1000 ;

lwip_select(fd+1, &readSet, NULL, &exceptSet, &tv) ;
select(fd+1, &readSet, NULL, &exceptSet, &tv) ;

if (FD_ISSET(fd, &readSet)) {
break ;
Expand Down Expand Up @@ -528,52 +530,50 @@ mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, uint32_t ti
int
mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len)
{
int ret = 0 ;
int fd = (int)ctx;

if( fd < 0 ) {
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
int fd = (int)(intptr_t)ctx;
if (fd < 0) {
return MBEDTLS_ERR_NET_INVALID_CONTEXT;
}

ret = (int) lwip_recv( fd, buf, len, MSG_DONTWAIT);
if (ret <= 0) {
if (errno == EWOULDBLOCK) {
DBG_MESSAGE_MBEDTLS(DBG_MESSAGE_SEVERITY_INFO, "mbedtls_net_recv WANT_READ") ;
return MBEDTLS_ERR_SSL_WANT_READ ;
}
else {
DBG_MESSAGE_MBEDTLS(DBG_MESSAGE_SEVERITY_REPORT, "TLS : : mbedtls_net_recv CONN_EOF (%d)", ret) ;
return ret == 0 ? MBEDTLS_ERR_NET_RECV_FAILED : MBEDTLS_ERR_NET_CONN_RESET ;
}

} else {
DBG_MESSAGE_MBEDTLS(DBG_MESSAGE_SEVERITY_INFO, "TLS : : mbedtls_net_recv read %d!", ret) ;
int r = (int)zsock_recv(fd, buf, len, MSG_DONTWAIT);
if (r > 0) {
return r;
}
if (r == 0) {
return MBEDTLS_ERR_NET_RECV_FAILED; /* peer closed */
}

/* r < 0 */
if (errno == EAGAIN || errno == EWOULDBLOCK) {
return MBEDTLS_ERR_SSL_WANT_READ;
}
if (errno == ECONNRESET) {
return MBEDTLS_ERR_NET_CONN_RESET;
}
return MBEDTLS_ERR_NET_RECV_FAILED;

return( ret );
}

int
mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
{
int ret;
int fd = (int)ctx;

if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );

ret = (int) lwip_write( fd, buf, len );

if( ret < 0 )
{
//if( net_would_block( ctx ) != 0 )
return( MBEDTLS_ERR_SSL_CONN_EOF );
int fd = (int)(intptr_t)ctx;
if (fd < 0) {
return MBEDTLS_ERR_NET_INVALID_CONTEXT;
}

//return( MBEDTLS_ERR_NET_SEND_FAILED );
int r = (int)zsock_send(fd, buf, len, 0);
if (r >= 0) {
return r;
}

return( ret );
if (errno == EAGAIN || errno == EWOULDBLOCK) {
return MBEDTLS_ERR_SSL_WANT_WRITE;
}
if (errno == ECONNRESET) {
return MBEDTLS_ERR_NET_CONN_RESET;
}
return MBEDTLS_ERR_NET_SEND_FAILED;
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,4 @@ gethostbyname_timeout (const char* hostname, uint32_t *ip4_address,

}

#endif
#endif
13 changes: 8 additions & 5 deletions src/qshell/httpcmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
SOFTWARE.
*/

#if 0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "config.h"
#include "qoraal/config.h"
#include "qoraal/qoraal.h"
#include "qoraal-http/qoraal.h"
Expand All @@ -34,7 +36,7 @@


SVC_SHELL_CMD_DECL("wsource", qshell_wsource, "<url>");
#ifdef CFG_OS_POSIX
#if defined(CFG_OS_POSIX) || defined(CONFIG_ZEPHYR)
SVC_SHELL_CMD_DECL("wget", qshell_wget, "<url>");
#endif

Expand Down Expand Up @@ -81,7 +83,7 @@ qshell_wsource (SVC_SHELL_IF_T * pif, char** argv, int argc)

}

#ifdef CFG_OS_POSIX
#if defined(CFG_OS_POSIX) || defined(CONFIG_ZEPHYR)
int resolve_hostname(const char *hostname, uint32_t *ip) {
struct addrinfo hints, *res = NULL;
memset(&hints, 0, sizeof(hints));
Expand All @@ -100,7 +102,7 @@ int resolve_hostname(const char *hostname, uint32_t *ip) {
}


int32_t qshell_wget(SVC_SHELL_IF_T *pif, char **argv, int argc)
int32_t qshell_wget(SVC_SHELL_IF_T *pif, char **argv, int argc)
{
HTTP_CLIENT_T client;
int32_t status;
Expand Down Expand Up @@ -217,8 +219,9 @@ int32_t qshell_wget(SVC_SHELL_IF_T *pif, char **argv, int argc)
void
keep_httpcmds (void)
{
(void)qshell_wsource ;
#ifdef CFG_OS_POSIX
(void)qshell_wsource ;
#if defined(CFG_OS_POSIX) || defined(CONFIG_ZEPHYR)
(void)qshell_wget ;
#endif
}
#endif // 0
2 changes: 1 addition & 1 deletion src/wserver_m.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ typedef struct HTTPSERVER_INST_S {
#define HTTPSERVER_USE_KEEPALIVE 1
#define HTTPSERVER_USER_MAX 96
#ifndef CFG_UTILS_HTTP_SERVER_THREADS
#define CFG_UTILS_HTTP_SERVER_THREADS 6
#define CFG_UTILS_HTTP_SERVER_THREADS 4
#endif

/**
Expand Down
6 changes: 4 additions & 2 deletions test/services/www/wserver_inst.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ wserver_authenticate (const char * user, const char * passwd)
int32_t
wserver_start (uintptr_t arg)
{
uint32_t port = 8080 ; //registry_get ("www.port", 80) ;
uint32_t port = 80 ; //registry_get ("www.port", 80) ;
bool ssl = false ; // registry_get ("www.ssl", false) ;

static const WSERVER_FRAMEWORK wserver_std_headers[] = {
Expand All @@ -313,7 +313,9 @@ wserver_start (uintptr_t arg)
static WSERVER_HANDLERS_START(handlers)
WSERVER_HANDLER ("rtlog", wrtlog_handler, WSERVER_ENDPOINT_ACCESS_OPEN, WSERVER_ENDPOINT_FLAGS_DISABLE_WDT)
WSERVER_HANDLER ("memlog", wnlog_memlog_handler, WSERVER_ENDPOINT_ACCESS_OPEN, 0)
WSERVER_HANDLER ("webapi", wwebapi_handler, WSERVER_ENDPOINT_ACCESS_ADMIN, 0)
#if !defined(CFG_JSON_DISABLE)
WSERVER_HANDLER ("webapi", wwebapi_handler, WSERVER_ENDPOINT_ACCESS_ADMIN, 0)
#endif
WSERVER_HANDLER ("about2", wserver_handler_about2, WSERVER_ENDPOINT_ACCESS_ADMIN, 0)
WSERVER_HANDLER ("about3", wserver_handler_about3, WSERVER_ENDPOINT_ACCESS_OPEN, 0)
WSERVER_HANDLER ("image", wimage_handler, WSERVER_ENDPOINT_ACCESS_OPEN, 0)
Expand Down