1 |
|
---|
2 | #include "lwip/opt.h"
|
---|
3 | #include "lwip/arch.h"
|
---|
4 | #include "lwip/api.h"
|
---|
5 |
|
---|
6 | #include "httpserver-netconn.h"
|
---|
7 |
|
---|
8 | #if LWIP_NETCONN
|
---|
9 |
|
---|
10 | #ifndef HTTPD_DEBUG
|
---|
11 | #define HTTPD_DEBUG LWIP_DBG_OFF
|
---|
12 | #endif
|
---|
13 |
|
---|
14 | static const char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";
|
---|
15 | 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>";
|
---|
16 |
|
---|
17 | /** Serve one HTTP connection accepted in the http thread */
|
---|
18 | static void
|
---|
19 | http_server_netconn_serve(struct netconn *conn)
|
---|
20 | {
|
---|
21 | struct netbuf *inbuf;
|
---|
22 | char *buf;
|
---|
23 | u16_t buflen;
|
---|
24 | err_t err;
|
---|
25 |
|
---|
26 | /* Read the data from the port, blocking if nothing yet there.
|
---|
27 | We assume the request (the part we care about) is in one netbuf */
|
---|
28 | err = netconn_recv(conn, &inbuf);
|
---|
29 |
|
---|
30 | if (err == ERR_OK) {
|
---|
31 | netbuf_data(inbuf, (void**)&buf, &buflen);
|
---|
32 |
|
---|
33 | /* Is this an HTTP GET command? (only check the first 5 chars, since
|
---|
34 | there are other formats for GET, and we're keeping it very simple )*/
|
---|
35 | if (buflen>=5 &&
|
---|
36 | buf[0]=='G' &&
|
---|
37 | buf[1]=='E' &&
|
---|
38 | buf[2]=='T' &&
|
---|
39 | buf[3]==' ' &&
|
---|
40 | buf[4]=='/' ) {
|
---|
41 |
|
---|
42 | /* Send the HTML header
|
---|
43 | * subtract 1 from the size, since we dont send the \0 in the string
|
---|
44 | * NETCONN_NOCOPY: our data is const static, so no need to copy it
|
---|
45 | */
|
---|
46 | netconn_write(conn, http_html_hdr, sizeof(http_html_hdr)-1, NETCONN_NOCOPY);
|
---|
47 |
|
---|
48 | /* Send our HTML page */
|
---|
49 | netconn_write(conn, http_index_html, sizeof(http_index_html)-1, NETCONN_NOCOPY);
|
---|
50 | }
|
---|
51 | }
|
---|
52 | /* Close the connection (server closes in HTTP) */
|
---|
53 | netconn_close(conn);
|
---|
54 |
|
---|
55 | /* Delete the buffer (netconn_recv gives us ownership,
|
---|
56 | so we have to make sure to deallocate the buffer) */
|
---|
57 | netbuf_delete(inbuf);
|
---|
58 | }
|
---|
59 |
|
---|
60 | /** The main function, never returns! */
|
---|
61 | static void
|
---|
62 | http_server_netconn_thread(void *arg)
|
---|
63 | {
|
---|
64 | struct netconn *conn, *newconn;
|
---|
65 | err_t err;
|
---|
66 | LWIP_UNUSED_ARG(arg);
|
---|
67 |
|
---|
68 | /* Create a new TCP connection handle */
|
---|
69 | /* Bind to port 80 (HTTP) with default IP address */
|
---|
70 | #if LWIP_IPV6
|
---|
71 | conn = netconn_new(NETCONN_TCP_IPV6);
|
---|
72 | netconn_bind(conn, IP6_ADDR_ANY, 80);
|
---|
73 | #else /* LWIP_IPV6 */
|
---|
74 | conn = netconn_new(NETCONN_TCP);
|
---|
75 | netconn_bind(conn, IP_ADDR_ANY, 80);
|
---|
76 | #endif /* LWIP_IPV6 */
|
---|
77 | LWIP_ERROR("http_server: invalid conn", (conn != NULL), return;);
|
---|
78 |
|
---|
79 | /* Put the connection into LISTEN state */
|
---|
80 | netconn_listen(conn);
|
---|
81 |
|
---|
82 | do {
|
---|
83 | err = netconn_accept(conn, &newconn);
|
---|
84 | if (err == ERR_OK) {
|
---|
85 | http_server_netconn_serve(newconn);
|
---|
86 | netconn_delete(newconn);
|
---|
87 | }
|
---|
88 | } while(err == ERR_OK);
|
---|
89 | LWIP_DEBUGF(HTTPD_DEBUG,
|
---|
90 | ("http_server_netconn_thread: netconn_accept received error %d, shutting down",
|
---|
91 | err));
|
---|
92 | netconn_close(conn);
|
---|
93 | netconn_delete(conn);
|
---|
94 | }
|
---|
95 |
|
---|
96 | /** Initialize the HTTP server (start its thread) */
|
---|
97 | void
|
---|
98 | http_server_netconn_init(void)
|
---|
99 | {
|
---|
100 | sys_thread_new("http_server_netconn", http_server_netconn_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
|
---|
101 | }
|
---|
102 |
|
---|
103 | #endif /* LWIP_NETCONN*/
|
---|