source: rtems/testsuites/libtests/mghttpd01/init.c @ f42d429

4.115
Last change on this file since f42d429 was f42d429, checked in by Nick Withers <nick.withers@…>, on Dec 15, 2014 at 2:26:31 AM

Enable WebSocket? support in the Mongoose HTTP server

  • Property mode set to 100644
File size: 7.4 KB
Line 
1/*
2 * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems.h>
20
21#include <tmacros.h>
22
23#include <rtems/rtems_bsdnet.h>
24
25#include <stdio.h>
26#include <string.h>
27#include <mghttpd/mongoose.h>
28
29#include <rtems/imfs.h>
30#include <rtems/error.h>
31#include "init_fs.h"
32
33#include "test-http-client.h"
34
35const char rtems_test_name[] = "MGHTTPD 1";
36
37#define TARFILE_START init_fs_tar
38#define TARFILE_SIZE  init_fs_tar_size
39
40#define CBACKTEST_URI   "/callbacktest.txt"
41#define CBACKTEST_TXT   "HTTP/1.1 200 OK\r\n" \
42                        "Content-Type: text/plain\r\n" \
43                        "Content-Length: 47\r\n" \
44                        "\r\n" \
45                        "This is a message from the callback function.\r\n"
46
47#define WSTEST_REQ      "Test request"
48#define WSTEST_RESP     "This is a message from the WebSocket callback function."
49
50#define INDEX_HTML      "HTTP/1.1 200 OK\r\n" \
51                        "Date: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n" \
52                        "Last-Modified: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n" \
53                        "Etag: \"21dae500.162\"\r\n" \
54                        "Content-Type: text/html\r\n" \
55                        "Content-Length: 162\r\n" \
56                        "Connection: close\r\n" \
57                        "Accept-Ranges: bytes\r\n" \
58                        "\r\n" \
59                        "<html>\r\n" \
60                        "<head>\r\n" \
61                        "<title>Second Instance</title>\r\n" \
62                        "</head>\r\n" \
63                        "\r\n" \
64                        "<body>\r\n" \
65                        "<h1>Second Instance</h1>\r\n" \
66                        "A test page for the Mongoose web server on RTEMS.\r\n" \
67                        "</body>\r\n" \
68                        "</html>\r\n"
69
70#define DATE_TAG        "Date: "
71#define LASTMOD_TAG     "Last-Modified: "
72#define TIMESTAMP_SIZE  (sizeof("Fri, 01 Jan 1988 00:00:26 GMT") - 1)
73
74#define BUFFERSIZE      1024
75
76static void test_tarfs_load(void)
77{
78  rtems_status_code sc;
79
80  printf("Loading tarfs image ... ");
81  sc = rtems_tarfs_load("/",(void *)TARFILE_START, TARFILE_SIZE);
82  if (sc != RTEMS_SUCCESSFUL) {
83    printf ("error: untar failed: %s\n", rtems_status_text (sc));
84    rtems_test_exit(1);
85  }
86  printf ("successful\n");
87}
88
89static int callback(struct mg_connection *conn)
90{
91  int cbacktest = strncmp(mg_get_request_info(conn)->uri, CBACKTEST_URI, sizeof(CBACKTEST_URI));
92  if (cbacktest == 0)
93  {
94    mg_write(conn, CBACKTEST_TXT, sizeof(CBACKTEST_TXT));
95
96    /* Mark as processed */
97    return 1;
98  }
99
100  return 0;
101}
102
103static int callback_websocket(struct mg_connection *connection,
104                              int                  bits,
105                              char                 *data,
106                              size_t               data_len)
107{
108  if (data_len == strlen(WSTEST_REQ) && strncmp(data, WSTEST_REQ, data_len) == 0)
109  {
110    mg_websocket_write(connection, WEBSOCKET_OPCODE_TEXT, WSTEST_RESP, strlen(WSTEST_RESP));
111
112    /* Don't close the WebSocket */
113    return 1;
114  }
115
116  return 0;
117}
118
119static void test_mg_index_html(void)
120{
121  httpc_context httpc_ctx;
122  char *buffer = malloc(BUFFERSIZE);
123  char *workpos = buffer;
124  bool brv = false;
125  int rv = 0;
126
127  rtems_test_assert(buffer != NULL);
128
129  puts("=== Get the index.html from second Mongoose instance:");
130
131  httpc_init_context(&httpc_ctx);
132  brv = httpc_open_connection(&httpc_ctx, "127.0.0.1", 8080);
133  rtems_test_assert(brv);
134  brv = httpc_send_request(&httpc_ctx, "GET /index.html", buffer, BUFFERSIZE);
135  rtems_test_assert(brv);
136  brv = httpc_close_connection(&httpc_ctx);
137  rtems_test_assert(brv);
138  puts(buffer);
139
140  /* remove timestamps from html-header */
141  workpos = strstr(buffer, DATE_TAG);
142  rtems_test_assert(workpos != NULL);
143  workpos += sizeof(DATE_TAG) - 1;
144  memset(workpos, 'x', TIMESTAMP_SIZE);
145
146  workpos = strstr(buffer, LASTMOD_TAG);
147  rtems_test_assert(workpos != NULL);
148  workpos += sizeof(LASTMOD_TAG) - 1;
149  memset(workpos, 'x', TIMESTAMP_SIZE);
150
151  rv = strcmp(buffer, INDEX_HTML);
152  rtems_test_assert(rv == 0);
153
154  puts("=== OK");
155
156  free(buffer);
157}
158
159static void test_mg_callback(void)
160{
161  httpc_context httpc_ctx;
162  char *buffer = malloc(BUFFERSIZE);
163  bool brv = false;
164  int rv = 0;
165
166  rtems_test_assert(buffer != NULL);
167
168  puts("=== Get a page generated from a callback function from" \
169      " first Mongoose instance:");
170
171  httpc_init_context(&httpc_ctx);
172  brv = httpc_open_connection(&httpc_ctx, "127.0.0.1", 80);
173  rtems_test_assert(brv);
174  brv = httpc_send_request(&httpc_ctx, "GET " CBACKTEST_URI, buffer, BUFFERSIZE);
175  rtems_test_assert(brv);
176  brv = httpc_close_connection(&httpc_ctx);
177  rtems_test_assert(brv);
178  puts(buffer);
179  rv = strcmp(buffer, CBACKTEST_TXT);
180  rtems_test_assert(rv == 0);
181
182  puts("=== OK");
183
184  free(buffer);
185}
186
187static void test_mg_websocket(void)
188{
189  httpc_context httpc_ctx;
190  char *buffer = malloc(BUFFERSIZE);
191  bool brv = false;
192  int rv = 0;
193
194  rtems_test_assert(buffer != NULL);
195
196  puts("=== Get a WebSocket response generated from a callback function" \
197      " from first Mongoose instance:");
198
199  httpc_init_context(&httpc_ctx);
200  brv = httpc_open_connection(&httpc_ctx, "127.0.0.1", 80);
201  rtems_test_assert(brv);
202  brv = httpc_ws_open_connection(&httpc_ctx);
203  rtems_test_assert(brv);
204  brv = httpc_ws_send_request(&httpc_ctx, WSTEST_REQ, buffer, BUFFERSIZE);
205  rtems_test_assert(brv);
206  brv = httpc_close_connection(&httpc_ctx);
207  rtems_test_assert(brv);
208  puts(buffer);
209  rv = strcmp(buffer, WSTEST_RESP);
210  rtems_test_assert(rv == 0);
211
212  puts("=== OK");
213
214  free(buffer);
215}
216
217static void test_mongoose(void)
218{
219  const struct mg_callbacks callbacks = {
220    .begin_request = callback,
221    .websocket_data = callback_websocket
222  };
223  const char *options[] = {
224    "listening_ports", "80",
225    "document_root", "/www",
226    "num_threads", "1",
227    "thread_stack_size", "16384",
228    "thread_priority", "250",
229    "thread_policy", "o",
230    NULL};
231  const struct mg_callbacks callbacks2 = {
232    NULL
233  };
234  const char *options2[] = {
235    "listening_ports", "8080",
236    "document_root", "/www2",
237    "num_threads", "1",
238    "thread_stack_size", "16384",
239    NULL};
240
241  struct mg_context *mg1 = mg_start(&callbacks, NULL, options);
242  struct mg_context *mg2 = mg_start(&callbacks2, NULL, options2);
243
244  test_mg_index_html();
245  test_mg_callback();
246  test_mg_websocket();
247
248  mg_stop(mg1);
249  mg_stop(mg2);
250}
251
252static void Init(rtems_task_argument arg)
253{
254  int rv = 0;
255
256  TEST_BEGIN();
257
258  rv = rtems_bsdnet_initialize_network();
259  rtems_test_assert(rv == 0);
260
261  test_tarfs_load();
262
263  test_mongoose();
264
265  TEST_END();
266
267  rtems_test_exit(0); 
268}
269
270#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
271#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
272
273#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
274
275#define CONFIGURE_FILESYSTEM_IMFS
276
277#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 16
278
279#define CONFIGURE_UNLIMITED_OBJECTS
280
281#define CONFIGURE_UNIFIED_WORK_AREAS
282
283#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
284
285#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
286
287#define CONFIGURE_INIT_TASK_STACK_SIZE (16 * 1024)
288
289#define CONFIGURE_INIT
290
291#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.