Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
HttpDynamic.cpp
00001 /***************************************************************************** 00002 * 00003 * HttpDynamic.c 00004 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 00013 * Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in the 00015 * documentation and/or other materials provided with the 00016 * distribution. 00017 * 00018 * Neither the name of Texas Instruments Incorporated nor the names of 00019 * its contributors may be used to endorse or promote products derived 00020 * from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00025 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00026 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00027 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00028 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00029 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00030 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00031 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00032 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 * 00034 *****************************************************************************/ 00035 #include "HttpDynamic.h" 00036 #include "HttpDynamicHandler.h" 00037 #include "HttpRequest.h" 00038 #include "HttpResponse.h" 00039 #include "HttpCore.h" 00040 #include "string.h" 00041 00042 #ifdef HTTP_CORE_ENABLE_DYNAMIC 00043 00044 /** 00045 * @defgroup HttpDynamic Dynamic request handler module 00046 * This module implements dynamic content processing for HTTP requests. 00047 * All requests are handled by C code functions, and the response contents is returned via HttpResopnse routines 00048 * Note this module is only compiled if HTTP_CORE_ENABLE_DYNAMIC is defined in HttpConfig.h 00049 * 00050 * @{ 00051 */ 00052 00053 char dynamicResourceName[HTTP_DYNAMIC_NUM_OF_RESOURCES][HTTP_DYNAMIC_MAX_RESOURCE_LEN] = {{"led"}, 00054 {"wheel"}, 00055 }; 00056 00057 00058 char dynamicLedParam1[5] = {"num="}; 00059 char dynamicLedParam2[8] = {"action="}; 00060 00061 /* text/html is currently the blob for content type */ 00062 uint8 uDynamicContentType[10] = "text/html"; 00063 00064 uint8 uDynamicContentBody[HTTP_DYNAMIC_NUM_OF_RESOURCES][HTTP_DYNAMIC_CONTENT_BODY_LEN]; 00065 00066 PerConnDynamicContent dynamicContent[HTTP_CORE_MAX_CONNECTIONS]; 00067 00068 00069 /** 00070 * Initialize HttpDynamic module state for a new request, and identify the request 00071 * This function must examine the specified resource string and determine whether it can commit to process this request 00072 * 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) 00073 * then it is the responsibility of this function to parse this information and store it in a connection-specific struct. 00074 * If this function returns nonzero, then the core will call HttpDynamic_ProcessRequest() with the rest of the request details. 00075 * @param uConnection The number of the connection. This value is guaranteed to satisfy: 0 <= uConnection < HTTP_CORE_MAX_CONNECTIONS 00076 * @param resource The resource part of the URL, as specified by the browser in the request, including any query string (and hash) 00077 * Note: The resource string exists ONLY during the call to this function. The string pointer should not be copied by this function. 00078 * @return nonzero if request is to be handled by this module. zero if not. 00079 */ 00080 int HttpDynamic_InitRequest(uint16 uConnection, struct HttpBlob resource) 00081 { 00082 /* Resource parsing follows the below assumptions: 00083 1. resource name is expected prior to query sign (just like a static page) 00084 2. query sign is expected. If not present, 0 is returned 00085 3. parameter name followed by a '=' sign is searched for. If not fully present, 0 is returned. 00086 4. parameters may arrive unordered */ 00087 00088 uint16 uLoopCounter; 00089 uint8 *cStr; 00090 struct HttpBlob subBlob; 00091 00092 /* look for known resource names according to dynamicResourceName[][]*/ 00093 for (uLoopCounter = 0; uLoopCounter < HTTP_DYNAMIC_NUM_OF_RESOURCES; uLoopCounter++) 00094 { 00095 if (HttpString_nextToken(dynamicResourceName[uLoopCounter], strlen(dynamicResourceName[uLoopCounter]), resource) != NULL) 00096 break; 00097 } 00098 00099 /* dynamic resource not found */ 00100 if (uLoopCounter == HTTP_DYNAMIC_NUM_OF_RESOURCES) 00101 return 0; 00102 00103 /* if got here, resource name is found on uLoopCounter index */ 00104 /* find "query" sign */ 00105 if (NULL == HttpString_nextToken("?", 1, resource)) 00106 return 0; 00107 00108 /* find "=" signs preceded by the parameter name */ 00109 switch ((enum HttpDynamicNumOfResources)uLoopCounter) 00110 { 00111 case LED: 00112 { 00113 /* search the LED number */ 00114 if ((cStr = HttpString_nextToken(dynamicLedParam1, HTTP_DYNAMIC_LED_NUM_LEN, resource)) != NULL) 00115 { 00116 dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedNumber = (enum HttpDynamicLedNumber)(*(cStr + HTTP_DYNAMIC_LED_NUM_LEN) - '0'); 00117 } 00118 else 00119 { 00120 return 0; 00121 } 00122 00123 /* search the LED action */ 00124 if ((cStr = HttpString_nextToken(dynamicLedParam2, HTTP_DYNAMIC_LED_ACTION_LEN, resource)) != NULL) 00125 { 00126 /* try to match LED action to the expected value exactly! */ 00127 subBlob.pData = cStr + HTTP_DYNAMIC_LED_ACTION_LEN; 00128 subBlob.uLength = 6; 00129 if (HttpString_nextToken("toggle", 6, subBlob) != NULL) 00130 dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedAction = toggle; 00131 else 00132 { 00133 subBlob.uLength = 2; 00134 if (HttpString_nextToken("on", 2, subBlob) != NULL) 00135 dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedAction = ON; 00136 else 00137 { 00138 subBlob.uLength = 3; 00139 if (HttpString_nextToken("off", 3, subBlob) != NULL) 00140 dynamicContent[uConnection].dynamicHandlerInParam.uLedParam.uLedAction = OFF; 00141 else 00142 return 0; 00143 } 00144 } 00145 } 00146 else 00147 { 00148 return 0; 00149 } 00150 00151 dynamicContent[uConnection].pDynamicHandler = HttpDynamicHandler_ActOnLED; 00152 dynamicContent[uConnection].resourceType = LED; 00153 break; 00154 } 00155 00156 case WHEEL: 00157 { 00158 if ((cStr = HttpString_nextToken(dynamicLedParam2, HTTP_DYNAMIC_LED_ACTION_LEN, resource)) != NULL) 00159 { 00160 subBlob.pData = cStr + HTTP_DYNAMIC_LED_ACTION_LEN; 00161 subBlob.uLength = 9; 00162 if (HttpString_nextToken("getstatus", 9 , subBlob) == NULL) 00163 { 00164 return 0; 00165 } 00166 } 00167 else 00168 return 0; 00169 00170 dynamicContent[uConnection].pDynamicHandler = HttpDynamicHandler_GetWheelValue; 00171 dynamicContent[uConnection].resourceType = WHEEL; 00172 break; 00173 } 00174 } 00175 00176 return 1; 00177 } 00178 00179 /** 00180 * Process a dynamic-content HTTP request 00181 * This function is only be called by the core, if HttpDynamic_InitRequest() returns nonzero. 00182 * This function processes the specified HTTP request, and send the response on the connection specified by request->uConnection. 00183 * This function must call the HttpResponse_*() functions in order to send data back to the browser. 00184 * Please refer to HttpResponse.h for more information. 00185 * @param request Pointer to all data available about the request 00186 */ 00187 void HttpDynamic_ProcessRequest(struct HttpRequest* request) 00188 { 00189 struct HttpBlob contentType, nullBlob = {0, NULL}; 00190 struct HttpBlob contentBody; 00191 int count; 00192 00193 00194 /* if HTTP_REQUEST_FLAG_AUTHENTICATED is not set and FLASHDB_FLAG_REQUIRE_AUTH is set then 00195 call HttpResponse_CannedError() with status HTTP_STATUS_ERROR_UNAUTHORIZED */ 00196 if (((request->uFlags & HTTP_REQUEST_FLAG_AUTHENTICATED) == 0)) 00197 { 00198 /* call HttpResponse_CannedError with 500 ERROR_INTERNAL */ 00199 HttpResponse_CannedError(request->uConnection, HTTP_STATUS_ERROR_UNAUTHORIZED); 00200 return; 00201 } 00202 00203 /* intialize the content body */ 00204 contentBody.pData =uDynamicContentBody[request->uConnection]; 00205 contentBody.uLength = 0; 00206 00207 contentType.pData = uDynamicContentType; 00208 contentType.uLength = 9; 00209 00210 /* 1. call the dynamic handler as parsed in the init phase */ 00211 dynamicContent[request->uConnection].pDynamicHandler(dynamicContent[request->uConnection].dynamicHandlerInParam, &dynamicContent[request->uConnection].dynamicHandlerOutParam); 00212 /* config the ContentLength according to the resource type */ 00213 switch (dynamicContent[request->uConnection].resourceType) 00214 { 00215 case LED: 00216 { 00217 contentBody.pData = (uint8*)"Done"; 00218 contentBody.uLength = 4; 00219 00220 00221 break; 00222 } 00223 case WHEEL: 00224 { 00225 char tempdata[6]; 00226 struct HttpBlob tempContent; 00227 tempContent.pData = (uint8 *)tempdata; 00228 HttpString_utoa((uint32)dynamicContent[request->uConnection].dynamicHandlerOutParam.sWheelParam.uWheelPosition, &contentBody); 00229 *(contentBody.pData + contentBody.uLength) = ':'; 00230 contentBody.uLength +=1; 00231 HttpString_utoa((uint32)dynamicContent[request->uConnection].dynamicHandlerOutParam.sWheelParam.uWheelValue, &tempContent); 00232 for(count=0; count<tempContent.uLength; count++) 00233 { 00234 *(contentBody.pData + (count+contentBody.uLength)) = *tempContent.pData; 00235 tempContent.pData++; 00236 } 00237 contentBody.uLength += tempContent.uLength; 00238 *(contentBody.pData + contentBody.uLength) = ':'; 00239 *(contentBody.pData + contentBody.uLength + 1) = dynamicContent[request->uConnection].dynamicHandlerOutParam.sWheelParam.uLedDummyOut; 00240 contentBody.uLength += 2; 00241 break; 00242 } 00243 } 00244 00245 /* 2. fill the header response (HTTP_RESPONSE_FLAG_COMPRESSED is not set for dynamic) */ 00246 HttpResponse_Headers(request->uConnection, HTTP_STATUS_OK, 0, contentBody.uLength, contentType, nullBlob); 00247 00248 /* 3. fill the content response (if exists) */ 00249 if (contentBody.uLength != 0) 00250 { 00251 HttpResponse_Content(request->uConnection, contentBody); 00252 } 00253 00254 } 00255 00256 00257 /// @} 00258 00259 #endif // HTTP_CORE_ENABLE_DYNAMIC 00260
Generated on Wed Jul 13 2022 13:30:51 by
1.7.2