A Port of TI's Webserver for the CC3000
Embed:
(wiki syntax)
Show/hide line numbers
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