genfiles_example.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /**
  2. * @file
  3. * HTTPD custom file system example for runtime generated files
  4. *
  5. * This file demonstrates how to add support for generated files to httpd.
  6. */
  7. /*
  8. * Copyright (c) 2017 Simon Goldschmidt
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without modification,
  12. * are permitted provided that the following conditions are met:
  13. *
  14. * 1. Redistributions of source code must retain the above copyright notice,
  15. * this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright notice,
  17. * this list of conditions and the following disclaimer in the documentation
  18. * and/or other materials provided with the distribution.
  19. * 3. The name of the author may not be used to endorse or promote products
  20. * derived from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  23. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  24. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  25. * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  26. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  27. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  28. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  29. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  30. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  31. * OF SUCH DAMAGE.
  32. *
  33. * This file is part of the lwIP TCP/IP stack.
  34. *
  35. * Author: Simon Goldschmidt <goldsimon@gmx.de>
  36. *
  37. */
  38. #include "lwip/opt.h"
  39. #include "genfiles_example.h"
  40. #include "lwip/apps/fs.h"
  41. #include "lwip/def.h"
  42. #include "lwip/mem.h"
  43. #include <stdio.h>
  44. #include <string.h>
  45. /** define LWIP_HTTPD_EXAMPLE_GENERATEDFILES to 1 to enable this file system */
  46. #ifndef LWIP_HTTPD_EXAMPLE_GENERATEDFILES
  47. #define LWIP_HTTPD_EXAMPLE_GENERATEDFILES 0
  48. #endif
  49. #if LWIP_HTTPD_EXAMPLE_GENERATEDFILES
  50. #if !LWIP_HTTPD_CUSTOM_FILES
  51. #error This needs LWIP_HTTPD_CUSTOM_FILES
  52. #endif
  53. #if !LWIP_HTTPD_FILE_EXTENSION
  54. #error This needs LWIP_HTTPD_FILE_EXTENSION
  55. #endif
  56. #if !LWIP_HTTPD_DYNAMIC_HEADERS
  57. #error This needs LWIP_HTTPD_DYNAMIC_HEADERS
  58. #endif
  59. /* This is the page we send. It's not generated, as you see.
  60. * Generating custom things instead of memcpy is left to your imagination :-)
  61. */
  62. const char generated_html[] =
  63. "<html>\n"
  64. "<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>\n"
  65. " <body bgcolor=\"white\" text=\"black\">\n"
  66. " <table width=\"100%\">\n"
  67. " <tr valign=\"top\">\n"
  68. " <td width=\"80\">\n"
  69. " <a href=\"http://www.sics.se/\"><img src=\"/img/sics.gif\"\n"
  70. " border=\"0\" alt=\"SICS logo\" title=\"SICS logo\"></a>\n"
  71. " </td>\n"
  72. " <td width=\"500\">\n"
  73. " <h1>lwIP - A Lightweight TCP/IP Stack</h1>\n"
  74. " <h2>Generated page</h2>\n"
  75. " <p>This page might be generated in-memory at runtime</p>\n"
  76. " </td>\n"
  77. " <td>\n"
  78. " &nbsp;\n"
  79. " </td>\n"
  80. " </tr>\n"
  81. " </table>\n"
  82. " </body>\n"
  83. "</html>";
  84. void
  85. genfiles_ex_init(void)
  86. {
  87. /* nothing to do here yet */
  88. }
  89. int
  90. fs_open_custom(struct fs_file *file, const char *name)
  91. {
  92. /* this example only provides one file */
  93. if (!strcmp(name, "/generated.html")) {
  94. /* initialize fs_file correctly */
  95. memset(file, 0, sizeof(struct fs_file));
  96. file->pextension = mem_malloc(sizeof(generated_html));
  97. if (file->pextension != NULL) {
  98. /* instead of doing memcpy, you would generate e.g. a JSON here */
  99. memcpy(file->pextension, generated_html, sizeof(generated_html));
  100. file->data = (const char *)file->pextension;
  101. file->len = sizeof(generated_html) - 1; /* don't send the trailing 0 */
  102. file->index = file->len;
  103. /* allow persisteng connections */
  104. file->flags = FS_FILE_FLAGS_HEADER_PERSISTENT;
  105. return 1;
  106. }
  107. }
  108. return 0;
  109. }
  110. void
  111. fs_close_custom(struct fs_file *file)
  112. {
  113. if (file && file->pextension) {
  114. mem_free(file->pextension);
  115. file->pextension = NULL;
  116. }
  117. }
  118. #if LWIP_HTTPD_FS_ASYNC_READ
  119. u8_t
  120. fs_canread_custom(struct fs_file *file)
  121. {
  122. LWIP_UNUSED_ARG(file);
  123. /* This example does not use delayed/async reading */
  124. return 1;
  125. }
  126. u8_t
  127. fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg)
  128. {
  129. LWIP_ASSERT("not implemented in this example configuration", 0);
  130. LWIP_UNUSED_ARG(file);
  131. LWIP_UNUSED_ARG(callback_fn);
  132. LWIP_UNUSED_ARG(callback_arg);
  133. /* Return
  134. - 1 if ready to read (at least one byte)
  135. - 0 if reading should be delayed (call 'tcpip_callback(callback_fn, callback_arg)' when ready) */
  136. return 1;
  137. }
  138. int
  139. fs_read_async_custom(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg)
  140. {
  141. LWIP_ASSERT("not implemented in this example configuration", 0);
  142. LWIP_UNUSED_ARG(file);
  143. LWIP_UNUSED_ARG(buffer);
  144. LWIP_UNUSED_ARG(count);
  145. LWIP_UNUSED_ARG(callback_fn);
  146. LWIP_UNUSED_ARG(callback_arg);
  147. /* Return
  148. - FS_READ_EOF if all bytes have been read
  149. - FS_READ_DELAYED if reading is delayed (call 'tcpip_callback(callback_fn, callback_arg)' when done) */
  150. /* all bytes read already */
  151. return FS_READ_EOF;
  152. }
  153. #else /* LWIP_HTTPD_FS_ASYNC_READ */
  154. int
  155. fs_read_custom(struct fs_file *file, char *buffer, int count)
  156. {
  157. LWIP_ASSERT("not implemented in this example configuration", 0);
  158. LWIP_UNUSED_ARG(file);
  159. LWIP_UNUSED_ARG(buffer);
  160. LWIP_UNUSED_ARG(count);
  161. /* Return
  162. - FS_READ_EOF if all bytes have been read
  163. - FS_READ_DELAYED if reading is delayed (call 'tcpip_callback(callback_fn, callback_arg)' when done) */
  164. /* all bytes read already */
  165. return FS_READ_EOF;
  166. }
  167. #endif /* LWIP_HTTPD_FS_ASYNC_READ */
  168. #endif /* LWIP_HTTPD_EXAMPLE_GENERATEDFILES */