1717 * You should have received a copy of the GNU General Public License
1818 * along with this program; if not, write to the Free Software
1919 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+ *
21+ *
22+ * This is a simple HTTP server module for wolfIP.
23+ *
24+ * This file contains a basic implementation of a HTTP server
25+ * that can be used with wolfIP.
26+ *
27+ * The HTTP server supports:
28+ * - GET requests
29+ * - POST requests
30+ * - Basic file serving
31+ * - Basic error handling
32+ *
33+ * Usage:
34+ * - Initialize via httpd_init()
35+ * - Add static pages via httpd_register_static_page()
36+ * - Add request handlers via httpd_register_handler()
37+ *
38+ * Note:
39+ * - Responses are sent immediately after generation. No buffering is done.
40+ * If the output socket is flooded, extra responses will be discarded.
41+ *
42+ *
2043 */
2144#include "wolfip.h"
2245#include "httpd.h"
@@ -43,16 +66,6 @@ static const char *http_status_text(int status_code) {
4366 return "Unknown" ;
4467 }
4568}
46- /*
47- static struct http_client *http_client_find(struct httpd *httpd, int sd) {
48- for (int i = 0; i < HTTPD_MAX_CLIENTS; i++) {
49- if (httpd->clients[i].client_sd == sd) {
50- return &httpd->clients[i];
51- }
52- }
53- return NULL;
54- }
55- */
5669
5770int httpd_register_handler (struct httpd * httpd , const char * path , int (* handler )(struct httpd * httpd , struct http_client * hc , struct http_request * req )) {
5871 for (int i = 0 ; i < HTTPD_MAX_URLS ; i ++ ) {
@@ -125,75 +138,63 @@ void http_send_response_headers(struct http_client *hc, int status_code, const c
125138}
126139
127140void http_send_response_body (struct http_client * hc , const void * body , size_t len ) {
128- if (!hc ) return ;
129- if (hc -> ssl ) {
130- int rc = wolfSSL_write (hc -> ssl , body , len );
131- if (rc <= 0 ) {
132- wolfSSL_free (hc -> ssl );
133- hc -> ssl = NULL ;
134- wolfIP_sock_close (hc -> httpd -> ipstack , hc -> client_sd );
135- hc -> client_sd = 0 ;
136- }
137- } else {
138- int rc = wolfIP_sock_send (hc -> httpd -> ipstack , hc -> client_sd , body , len , 0 );
139- if (rc <= 0 ) {
140- wolfIP_sock_close (hc -> httpd -> ipstack , hc -> client_sd );
141- hc -> client_sd = 0 ;
142- }
141+ int rc ;
142+ if (!hc )
143+ return ;
144+ if (hc -> ssl )
145+ rc = wolfSSL_write (hc -> ssl , body , len );
146+ else
147+ rc = wolfIP_sock_send (hc -> httpd -> ipstack , hc -> client_sd , body , len , 0 );
148+
149+ if (rc <= 0 ) {
150+ wolfSSL_free (hc -> ssl );
151+ hc -> ssl = NULL ;
152+ wolfIP_sock_close (hc -> httpd -> ipstack , hc -> client_sd );
153+ hc -> client_sd = 0 ;
143154 }
144155}
145156
157+ static int http_write_response (struct http_client * hc , const void * buf , size_t len )
158+ {
159+ struct wolfIP * s ;
160+ if (!hc )
161+ return -1 ;
162+ s = hc -> httpd -> ipstack ;
163+ if (hc -> ssl )
164+ return wolfSSL_write (hc -> ssl , buf , len );
165+ else
166+ return wolfIP_sock_send (s , hc -> client_sd , buf , len , 0 );
167+ }
168+
146169void http_send_response_chunk (struct http_client * hc , const void * chunk , size_t len ) {
147170 char txt_chunk [8 ];
148171 memset (txt_chunk , 0 , sizeof (txt_chunk ));
149- if (!hc ) return ;
172+ if (!hc )
173+ return ;
150174 snprintf (txt_chunk , sizeof (txt_chunk ), "%zx\r\n" , len );
151- if (hc -> ssl ) {
152- int rc = wolfSSL_write (hc -> ssl , txt_chunk , strlen (txt_chunk ));
153- if (rc <= 0 )
154- goto close_conn ;
155- rc = wolfSSL_write (hc -> ssl , chunk , len );
156- if (rc <= 0 )
157- goto close_conn ;
158- rc = wolfSSL_write (hc -> ssl , "\r\n" , 2 );
159- if (rc <= 0 )
160- goto close_conn ;
161- } else {
162- struct wolfIP * s = hc -> httpd -> ipstack ;
163- int rc = wolfIP_sock_send (s , hc -> client_sd , txt_chunk , strlen (txt_chunk ), 0 );
164- if (rc <= 0 )
165- goto close_conn ;
166- rc = wolfIP_sock_send (s , hc -> client_sd , chunk , len , 0 );
167- if (rc <= 0 )
168- goto close_conn ;
169- rc = wolfIP_sock_send (s , hc -> client_sd , "\r\n" , 2 , 0 );
170- if (rc <= 0 )
171- goto close_conn ;
172- }
173- return ;
174- close_conn :
175- if (hc -> ssl ) {
175+ if ((http_write_response (hc , txt_chunk , strlen (txt_chunk )) <= 0 ) ||
176+ (http_write_response (hc , chunk , len ) <= 0 ) ||
177+ (http_write_response (hc , "\r\n" , 2 ) <= 0 )) {
176178 wolfSSL_free (hc -> ssl );
177179 hc -> ssl = NULL ;
180+ wolfIP_sock_close (hc -> httpd -> ipstack , hc -> client_sd );
181+ hc -> client_sd = 0 ;
178182 }
179- wolfIP_sock_close (hc -> httpd -> ipstack , hc -> client_sd );
180- hc -> client_sd = 0 ;
181183}
182184
183185void http_send_response_chunk_end (struct http_client * hc ) {
184- if (!hc ) return ;
185- if (hc -> ssl ) {
186- if (wolfSSL_write (hc -> ssl , "0\r\n\r\n" , 5 ) <= 0 ) {
187- wolfSSL_free (hc -> ssl );
188- hc -> ssl = NULL ;
189- wolfIP_sock_close (hc -> httpd -> ipstack , hc -> client_sd );
190- hc -> client_sd = 0 ;
191- }
192- } else {
193- if (wolfIP_sock_send (hc -> httpd -> ipstack , hc -> client_sd , "0\r\n\r\n" , 5 , 0 ) <= 0 ) {
194- wolfIP_sock_close (hc -> httpd -> ipstack , hc -> client_sd );
195- hc -> client_sd = 0 ;
196- }
186+ int rc ;
187+ if (!hc )
188+ return ;
189+ if (hc -> ssl )
190+ rc = wolfSSL_write (hc -> ssl , "0\r\n\r\n" , 5 );
191+ else
192+ rc = wolfIP_sock_send (hc -> httpd -> ipstack , hc -> client_sd , "0\r\n\r\n" , 5 , 0 );
193+ if (rc <= 0 ) {
194+ wolfSSL_free (hc -> ssl );
195+ hc -> ssl = NULL ;
196+ wolfIP_sock_close (hc -> httpd -> ipstack , hc -> client_sd );
197+ hc -> client_sd = 0 ;
197198 }
198199}
199200
@@ -369,7 +370,7 @@ static int parse_http_request(struct http_client *hc, uint8_t *buf, size_t len)
369370 url = http_find_url (hc -> httpd , req .path );
370371 if (!url )
371372 goto not_found ;
372-
373+
373374 if ((url -> handler == NULL ) && (url -> static_content == NULL ))
374375 goto service_unavailable ;
375376 if (url -> handler == NULL ) {
0 commit comments