David Fletcher
/
CC3000WebServer
A Port of TI's Webserver for the CC3000
WebServer/HttpDynamic.cpp@0:6ad60d78b315, 2013-09-14 (annotated)
- Committer:
- dflet
- Date:
- Sat Sep 14 17:38:41 2013 +0000
- Revision:
- 0:6ad60d78b315
Mostly working will serve the default pages index.html and config.html, but config.html is not woring at present.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dflet | 0:6ad60d78b315 | 1 | /***************************************************************************** |
dflet | 0:6ad60d78b315 | 2 | * |
dflet | 0:6ad60d78b315 | 3 | * HttpDynamic.c |
dflet | 0:6ad60d78b315 | 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ |
dflet | 0:6ad60d78b315 | 5 | * |
dflet | 0:6ad60d78b315 | 6 | * Redistribution and use in source and binary forms, with or without |
dflet | 0:6ad60d78b315 | 7 | * modification, are permitted provided that the following conditions |
dflet | 0:6ad60d78b315 | 8 | * are met: |
dflet | 0:6ad60d78b315 | 9 | * |
dflet | 0:6ad60d78b315 | 10 | * Redistributions of source code must retain the above copyright |
dflet | 0:6ad60d78b315 | 11 | * notice, this list of conditions and the following disclaimer. |
dflet | 0:6ad60d78b315 | 12 | * |
dflet | 0:6ad60d78b315 | 13 | * Redistributions in binary form must reproduce the above copyright |
dflet | 0:6ad60d78b315 | 14 | * notice, this list of conditions and the following disclaimer in the |
dflet | 0:6ad60d78b315 | 15 | * documentation and/or other materials provided with the |
dflet | 0:6ad60d78b315 | 16 | * distribution. |
dflet | 0:6ad60d78b315 | 17 | * |
dflet | 0:6ad60d78b315 | 18 | * Neither the name of Texas Instruments Incorporated nor the names of |
dflet | 0:6ad60d78b315 | 19 | * its contributors may be used to endorse or promote products derived |
dflet | 0:6ad60d78b315 | 20 | * from this software without specific prior written permission. |
dflet | 0:6ad60d78b315 | 21 | * |
dflet | 0:6ad60d78b315 | 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
dflet | 0:6ad60d78b315 | 23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
dflet | 0:6ad60d78b315 | 24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
dflet | 0:6ad60d78b315 | 25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
dflet | 0:6ad60d78b315 | 26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
dflet | 0:6ad60d78b315 | 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
dflet | 0:6ad60d78b315 | 28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
dflet | 0:6ad60d78b315 | 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
dflet | 0:6ad60d78b315 | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
dflet | 0:6ad60d78b315 | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
dflet | 0:6ad60d78b315 | 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
dflet | 0:6ad60d78b315 | 33 | * |
dflet | 0:6ad60d78b315 | 34 | *****************************************************************************/ |
dflet | 0:6ad60d78b315 | 35 | #include "HttpDynamic.h" |
dflet | 0:6ad60d78b315 | 36 | #include "HttpDynamicHandler.h" |
dflet | 0:6ad60d78b315 | 37 | #include "HttpRequest.h" |
dflet | 0:6ad60d78b315 | 38 | #include "HttpResponse.h" |
dflet | 0:6ad60d78b315 | 39 | #include "HttpCore.h" |
dflet | 0:6ad60d78b315 | 40 | #include "string.h" |
dflet | 0:6ad60d78b315 | 41 | |
dflet | 0:6ad60d78b315 | 42 | #ifdef HTTP_CORE_ENABLE_DYNAMIC |
dflet | 0:6ad60d78b315 | 43 | |
dflet | 0:6ad60d78b315 | 44 | /** |
dflet | 0:6ad60d78b315 | 45 | * @defgroup HttpDynamic Dynamic request handler module |
dflet | 0:6ad60d78b315 | 46 | * This module implements dynamic content processing for HTTP requests. |
dflet | 0:6ad60d78b315 | 47 | * All requests are handled by C code functions, and the response contents is returned via HttpResopnse routines |
dflet | 0:6ad60d78b315 | 48 | * Note this module is only compiled if HTTP_CORE_ENABLE_DYNAMIC is defined in HttpConfig.h |
dflet | 0:6ad60d78b315 | 49 | * |
dflet | 0:6ad60d78b315 | 50 | * @{ |
dflet | 0:6ad60d78b315 | 51 | */ |
dflet | 0:6ad60d78b315 | 52 | |
dflet | 0:6ad60d78b315 | 53 | char dynamicResourceName[HTTP_DYNAMIC_NUM_OF_RESOURCES][HTTP_DYNAMIC_MAX_RESOURCE_LEN] = {{"led"}, |
dflet | 0:6ad60d78b315 | 54 | {"wheel"}, |
dflet | 0:6ad60d78b315 | 55 | }; |
dflet | 0:6ad60d78b315 | 56 | |
dflet | 0:6ad60d78b315 | 57 | |
dflet | 0:6ad60d78b315 | 58 | char dynamicLedParam1[5] = {"num="}; |
dflet | 0:6ad60d78b315 | 59 | char dynamicLedParam2[8] = {"action="}; |
dflet | 0:6ad60d78b315 | 60 | |
dflet | 0:6ad60d78b315 | 61 | /* text/html is currently the blob for content type */ |
dflet | 0:6ad60d78b315 | 62 | uint8 uDynamicContentType[10] = "text/html"; |
dflet | 0:6ad60d78b315 | 63 | |
dflet | 0:6ad60d78b315 | 64 | uint8 uDynamicContentBody[HTTP_DYNAMIC_NUM_OF_RESOURCES][HTTP_DYNAMIC_CONTENT_BODY_LEN]; |
dflet | 0:6ad60d78b315 | 65 | |
dflet | 0:6ad60d78b315 | 66 | PerConnDynamicContent dynamicContent[HTTP_CORE_MAX_CONNECTIONS]; |
dflet | 0:6ad60d78b315 | 67 | |
dflet | 0:6ad60d78b315 | 68 | |
dflet | 0:6ad60d78b315 | 69 | /** |
dflet | 0:6ad60d78b315 | 70 | * Initialize HttpDynamic module state for a new request, and identify the request |
dflet | 0:6ad60d78b315 | 71 | * This function must examine the specified resource string and determine whether it can commit to process this request |
dflet | 0:6ad60d78b315 | 72 | * Also, if the resource string includes any information that this module needs in order to process the request (such as the contents of the query string) |
dflet | 0:6ad60d78b315 | 73 | * then it is the responsibility of this function to parse this information and store it in a connection-specific struct. |
dflet | 0:6ad60d78b315 | 74 | * If this function returns nonzero, then the core will call HttpDynamic_ProcessRequest() with the rest of the request details. |
dflet | 0:6ad60d78b315 | 75 | * @param uConnection The number of the connection. This value is guaranteed to satisfy: 0 <= uConnection < HTTP_CORE_MAX_CONNECTIONS |
dflet | 0:6ad60d78b315 | 76 | * @param resource The resource part of the URL, as specified by the browser in the request, including any query string (and hash) |
dflet | 0:6ad60d78b315 | 77 | * Note: The resource string exists ONLY during the call to this function. The string pointer should not be copied by this function. |
dflet | 0:6ad60d78b315 | 78 | * @return nonzero if request is to be handled by this module. zero if not. |
dflet | 0:6ad60d78b315 | 79 | */ |
dflet | 0:6ad60d78b315 | 80 | int HttpDynamic_InitRequest(uint16 uConnection, struct HttpBlob resource) |
dflet | 0:6ad60d78b315 | 81 | { |
dflet | 0:6ad60d78b315 | 82 | /* Resource parsing follows the below assumptions: |
dflet | 0:6ad60d78b315 | 83 | 1. resource name is expected prior to query sign (just like a static page) |
dflet | 0:6ad60d78b315 | 84 | 2. query sign is expected. If not present, 0 is returned |
dflet | 0:6ad60d78b315 | 85 | 3. parameter name followed by a '=' sign is searched for. If not fully present, 0 is returned. |
dflet | 0:6ad60d78b315 | 86 | 4. parameters may arrive unordered */ |
dflet | 0:6ad60d78b315 | 87 | |
dflet | 0:6ad60d78b315 | 88 | uint16 uLoopCounter; |
dflet | 0:6ad60d78b315 | 89 | uint8 *cStr; |
dflet | 0:6ad60d78b315 | 90 | struct HttpBlob subBlob; |
dflet | 0:6ad60d78b315 | 91 | |
dflet | 0:6ad60d78b315 | 92 | /* look for known resource names according to dynamicResourceName[][]*/ |
dflet | 0:6ad60d78b315 | 93 | for (uLoopCounter = 0; uLoopCounter < HTTP_DYNAMIC_NUM_OF_RESOURCES; uLoopCounter++) |
dflet | 0:6ad60d78b315 | 94 | { |
dflet | 0:6ad60d78b315 | 95 | if (HttpString_nextToken(dynamicResourceName[uLoopCounter], strlen(dynamicResourceName[uLoopCounter]), resource) != NULL) |
dflet | 0:6ad60d78b315 | 96 | break; |
dflet | 0:6ad60d78b315 | 97 | } |
dflet | 0:6ad60d78b315 | 98 | |
dflet | 0:6ad60d78b315 | 99 | /* dynamic resource not found */ |
dflet | 0:6ad60d78b315 | 100 | if (uLoopCounter == HTTP_DYNAMIC_NUM_OF_RESOURCES) |
dflet | 0:6ad60d78b315 | 101 | return 0; |
dflet | 0:6ad60d78b315 | 102 | |
dflet | 0:6ad60d78b315 | 103 | /* if got here, resource name is found on uLoopCounter index */ |
dflet | 0:6ad60d78b315 | 104 | /* find "query" sign */ |
dflet | 0:6ad60d78b315 | 105 | if (NULL == HttpString_nextToken("?", 1, resource)) |
dflet | 0:6ad60d78b315 | 106 | return 0; |
dflet | 0:6ad60d78b315 | 107 | |
dflet | 0:6ad60d78b315 | 108 | /* find "=" signs preceded by the parameter name */ |
dflet | 0:6ad60d78b315 | 109 | switch ((enum HttpDynamicNumOfResources)uLoopCounter) |
dflet | 0:6ad60d78b315 | 110 | { |
dflet | 0:6ad60d78b315 | 111 | case LED: |
dflet | 0:6ad60d78b315 | 112 | { |
dflet | 0:6ad60d78b315 | 113 | /* search the LED number */ |
dflet | 0:6ad60d78b315 | 114 | if ((cStr = HttpString_nextToken(dynamicLedParam1, HTTP_DYNAMIC_LED_NUM_LEN, resource)) != NULL) |
dflet | 0:6ad60d78b315 | 115 | { |
dflet | 0:6ad60d78b315 | 116 | dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedNumber = (enum HttpDynamicLedNumber)(*(cStr + HTTP_DYNAMIC_LED_NUM_LEN) - '0'); |
dflet | 0:6ad60d78b315 | 117 | } |
dflet | 0:6ad60d78b315 | 118 | else |
dflet | 0:6ad60d78b315 | 119 | { |
dflet | 0:6ad60d78b315 | 120 | return 0; |
dflet | 0:6ad60d78b315 | 121 | } |
dflet | 0:6ad60d78b315 | 122 | |
dflet | 0:6ad60d78b315 | 123 | /* search the LED action */ |
dflet | 0:6ad60d78b315 | 124 | if ((cStr = HttpString_nextToken(dynamicLedParam2, HTTP_DYNAMIC_LED_ACTION_LEN, resource)) != NULL) |
dflet | 0:6ad60d78b315 | 125 | { |
dflet | 0:6ad60d78b315 | 126 | /* try to match LED action to the expected value exactly! */ |
dflet | 0:6ad60d78b315 | 127 | subBlob.pData = cStr + HTTP_DYNAMIC_LED_ACTION_LEN; |
dflet | 0:6ad60d78b315 | 128 | subBlob.uLength = 6; |
dflet | 0:6ad60d78b315 | 129 | if (HttpString_nextToken("toggle", 6, subBlob) != NULL) |
dflet | 0:6ad60d78b315 | 130 | dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedAction = toggle; |
dflet | 0:6ad60d78b315 | 131 | else |
dflet | 0:6ad60d78b315 | 132 | { |
dflet | 0:6ad60d78b315 | 133 | subBlob.uLength = 2; |
dflet | 0:6ad60d78b315 | 134 | if (HttpString_nextToken("on", 2, subBlob) != NULL) |
dflet | 0:6ad60d78b315 | 135 | dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedAction = ON; |
dflet | 0:6ad60d78b315 | 136 | else |
dflet | 0:6ad60d78b315 | 137 | { |
dflet | 0:6ad60d78b315 | 138 | subBlob.uLength = 3; |
dflet | 0:6ad60d78b315 | 139 | if (HttpString_nextToken("off", 3, subBlob) != NULL) |
dflet | 0:6ad60d78b315 | 140 | dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedAction = OFF; |
dflet | 0:6ad60d78b315 | 141 | else |
dflet | 0:6ad60d78b315 | 142 | return 0; |
dflet | 0:6ad60d78b315 | 143 | } |
dflet | 0:6ad60d78b315 | 144 | } |
dflet | 0:6ad60d78b315 | 145 | } |
dflet | 0:6ad60d78b315 | 146 | else |
dflet | 0:6ad60d78b315 | 147 | { |
dflet | 0:6ad60d78b315 | 148 | return 0; |
dflet | 0:6ad60d78b315 | 149 | } |
dflet | 0:6ad60d78b315 | 150 | |
dflet | 0:6ad60d78b315 | 151 | dynamicContent[uConnection].pDynamicHandler = HttpDynamicHandler_ActOnLED; |
dflet | 0:6ad60d78b315 | 152 | dynamicContent[uConnection].resourceType = LED; |
dflet | 0:6ad60d78b315 | 153 | break; |
dflet | 0:6ad60d78b315 | 154 | } |
dflet | 0:6ad60d78b315 | 155 | |
dflet | 0:6ad60d78b315 | 156 | case WHEEL: |
dflet | 0:6ad60d78b315 | 157 | { |
dflet | 0:6ad60d78b315 | 158 | if ((cStr = HttpString_nextToken(dynamicLedParam2, HTTP_DYNAMIC_LED_ACTION_LEN, resource)) != NULL) |
dflet | 0:6ad60d78b315 | 159 | { |
dflet | 0:6ad60d78b315 | 160 | subBlob.pData = cStr + HTTP_DYNAMIC_LED_ACTION_LEN; |
dflet | 0:6ad60d78b315 | 161 | subBlob.uLength = 9; |
dflet | 0:6ad60d78b315 | 162 | if (HttpString_nextToken("getstatus", 9 , subBlob) == NULL) |
dflet | 0:6ad60d78b315 | 163 | { |
dflet | 0:6ad60d78b315 | 164 | return 0; |
dflet | 0:6ad60d78b315 | 165 | } |
dflet | 0:6ad60d78b315 | 166 | } |
dflet | 0:6ad60d78b315 | 167 | else |
dflet | 0:6ad60d78b315 | 168 | return 0; |
dflet | 0:6ad60d78b315 | 169 | |
dflet | 0:6ad60d78b315 | 170 | dynamicContent[uConnection].pDynamicHandler = HttpDynamicHandler_GetWheelValue; |
dflet | 0:6ad60d78b315 | 171 | dynamicContent[uConnection].resourceType = WHEEL; |
dflet | 0:6ad60d78b315 | 172 | break; |
dflet | 0:6ad60d78b315 | 173 | } |
dflet | 0:6ad60d78b315 | 174 | } |
dflet | 0:6ad60d78b315 | 175 | |
dflet | 0:6ad60d78b315 | 176 | return 1; |
dflet | 0:6ad60d78b315 | 177 | } |
dflet | 0:6ad60d78b315 | 178 | |
dflet | 0:6ad60d78b315 | 179 | /** |
dflet | 0:6ad60d78b315 | 180 | * Process a dynamic-content HTTP request |
dflet | 0:6ad60d78b315 | 181 | * This function is only be called by the core, if HttpDynamic_InitRequest() returns nonzero. |
dflet | 0:6ad60d78b315 | 182 | * This function processes the specified HTTP request, and send the response on the connection specified by request->uConnection. |
dflet | 0:6ad60d78b315 | 183 | * This function must call the HttpResponse_*() functions in order to send data back to the browser. |
dflet | 0:6ad60d78b315 | 184 | * Please refer to HttpResponse.h for more information. |
dflet | 0:6ad60d78b315 | 185 | * @param request Pointer to all data available about the request |
dflet | 0:6ad60d78b315 | 186 | */ |
dflet | 0:6ad60d78b315 | 187 | void HttpDynamic_ProcessRequest(struct HttpRequest* request) |
dflet | 0:6ad60d78b315 | 188 | { |
dflet | 0:6ad60d78b315 | 189 | struct HttpBlob contentType, nullBlob = {0, NULL}; |
dflet | 0:6ad60d78b315 | 190 | struct HttpBlob contentBody; |
dflet | 0:6ad60d78b315 | 191 | int count; |
dflet | 0:6ad60d78b315 | 192 | |
dflet | 0:6ad60d78b315 | 193 | |
dflet | 0:6ad60d78b315 | 194 | /* if HTTP_REQUEST_FLAG_AUTHENTICATED is not set and FLASHDB_FLAG_REQUIRE_AUTH is set then |
dflet | 0:6ad60d78b315 | 195 | call HttpResponse_CannedError() with status HTTP_STATUS_ERROR_UNAUTHORIZED */ |
dflet | 0:6ad60d78b315 | 196 | if (((request->uFlags & HTTP_REQUEST_FLAG_AUTHENTICATED) == 0)) |
dflet | 0:6ad60d78b315 | 197 | { |
dflet | 0:6ad60d78b315 | 198 | /* call HttpResponse_CannedError with 500 ERROR_INTERNAL */ |
dflet | 0:6ad60d78b315 | 199 | HttpResponse_CannedError(request->uConnection, HTTP_STATUS_ERROR_UNAUTHORIZED); |
dflet | 0:6ad60d78b315 | 200 | return; |
dflet | 0:6ad60d78b315 | 201 | } |
dflet | 0:6ad60d78b315 | 202 | |
dflet | 0:6ad60d78b315 | 203 | /* intialize the content body */ |
dflet | 0:6ad60d78b315 | 204 | contentBody.pData =uDynamicContentBody[request->uConnection]; |
dflet | 0:6ad60d78b315 | 205 | contentBody.uLength = 0; |
dflet | 0:6ad60d78b315 | 206 | |
dflet | 0:6ad60d78b315 | 207 | contentType.pData = uDynamicContentType; |
dflet | 0:6ad60d78b315 | 208 | contentType.uLength = 9; |
dflet | 0:6ad60d78b315 | 209 | |
dflet | 0:6ad60d78b315 | 210 | /* 1. call the dynamic handler as parsed in the init phase */ |
dflet | 0:6ad60d78b315 | 211 | dynamicContent[request->uConnection].pDynamicHandler(dynamicContent[request->uConnection].dynamicHandlerInParam, &dynamicContent[request->uConnection].dynamicHandlerOutParam); |
dflet | 0:6ad60d78b315 | 212 | /* config the ContentLength according to the resource type */ |
dflet | 0:6ad60d78b315 | 213 | switch (dynamicContent[request->uConnection].resourceType) |
dflet | 0:6ad60d78b315 | 214 | { |
dflet | 0:6ad60d78b315 | 215 | case LED: |
dflet | 0:6ad60d78b315 | 216 | { |
dflet | 0:6ad60d78b315 | 217 | contentBody.pData = (uint8*)"Done"; |
dflet | 0:6ad60d78b315 | 218 | contentBody.uLength = 4; |
dflet | 0:6ad60d78b315 | 219 | |
dflet | 0:6ad60d78b315 | 220 | |
dflet | 0:6ad60d78b315 | 221 | break; |
dflet | 0:6ad60d78b315 | 222 | } |
dflet | 0:6ad60d78b315 | 223 | case WHEEL: |
dflet | 0:6ad60d78b315 | 224 | { |
dflet | 0:6ad60d78b315 | 225 | char tempdata[6]; |
dflet | 0:6ad60d78b315 | 226 | struct HttpBlob tempContent; |
dflet | 0:6ad60d78b315 | 227 | tempContent.pData = (uint8 *)tempdata; |
dflet | 0:6ad60d78b315 | 228 | HttpString_utoa((uint32)dynamicContent[request->uConnection].dynamicHandlerOutParam.sWheelParam.uWheelPosition, &contentBody); |
dflet | 0:6ad60d78b315 | 229 | *(contentBody.pData + contentBody.uLength) = ':'; |
dflet | 0:6ad60d78b315 | 230 | contentBody.uLength +=1; |
dflet | 0:6ad60d78b315 | 231 | HttpString_utoa((uint32)dynamicContent[request->uConnection].dynamicHandlerOutParam.sWheelParam.uWheelValue, &tempContent); |
dflet | 0:6ad60d78b315 | 232 | for(count=0; count<tempContent.uLength; count++) |
dflet | 0:6ad60d78b315 | 233 | { |
dflet | 0:6ad60d78b315 | 234 | *(contentBody.pData + (count+contentBody.uLength)) = *tempContent.pData; |
dflet | 0:6ad60d78b315 | 235 | tempContent.pData++; |
dflet | 0:6ad60d78b315 | 236 | } |
dflet | 0:6ad60d78b315 | 237 | contentBody.uLength += tempContent.uLength; |
dflet | 0:6ad60d78b315 | 238 | *(contentBody.pData + contentBody.uLength) = ':'; |
dflet | 0:6ad60d78b315 | 239 | *(contentBody.pData + contentBody.uLength + 1) = dynamicContent[request->uConnection].dynamicHandlerOutParam.sWheelParam.uLedDummyOut; |
dflet | 0:6ad60d78b315 | 240 | contentBody.uLength += 2; |
dflet | 0:6ad60d78b315 | 241 | break; |
dflet | 0:6ad60d78b315 | 242 | } |
dflet | 0:6ad60d78b315 | 243 | } |
dflet | 0:6ad60d78b315 | 244 | |
dflet | 0:6ad60d78b315 | 245 | /* 2. fill the header response (HTTP_RESPONSE_FLAG_COMPRESSED is not set for dynamic) */ |
dflet | 0:6ad60d78b315 | 246 | HttpResponse_Headers(request->uConnection, HTTP_STATUS_OK, 0, contentBody.uLength, contentType, nullBlob); |
dflet | 0:6ad60d78b315 | 247 | |
dflet | 0:6ad60d78b315 | 248 | /* 3. fill the content response (if exists) */ |
dflet | 0:6ad60d78b315 | 249 | if (contentBody.uLength != 0) |
dflet | 0:6ad60d78b315 | 250 | { |
dflet | 0:6ad60d78b315 | 251 | HttpResponse_Content(request->uConnection, contentBody); |
dflet | 0:6ad60d78b315 | 252 | } |
dflet | 0:6ad60d78b315 | 253 | |
dflet | 0:6ad60d78b315 | 254 | } |
dflet | 0:6ad60d78b315 | 255 | |
dflet | 0:6ad60d78b315 | 256 | |
dflet | 0:6ad60d78b315 | 257 | /// @} |
dflet | 0:6ad60d78b315 | 258 | |
dflet | 0:6ad60d78b315 | 259 | #endif // HTTP_CORE_ENABLE_DYNAMIC |
dflet | 0:6ad60d78b315 | 260 |