A Port of TI's Webserver for the CC3000

Dependencies:   mbed

Committer:
dflet
Date:
Mon Sep 16 18:37:14 2013 +0000
Revision:
2:e6a185df9e4c
Parent:
0:6ad60d78b315
ADC and Leds now work on board and config.html page.

Who changed what in which revision?

UserRevisionLine numberNew 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