Oops - PDI handshake delay was too long, causing the device's /RESET functionality...
[pub/USBasp.git] / Projects / Webserver / Lib / HTTPServerApp.c
index 78c1b13..5f0b2cf 100644 (file)
@@ -112,9 +112,10 @@ void WebserverApp_Callback(void)
        }\r
        else if (uip_connected())\r
        {\r
-               /* New connection - initialize connection state and data pointer to the appropriate HTTP header */\r
+               /* New connection - initialize connection state values */\r
                AppState->PrevState    = WEBSERVER_STATE_OpenRequestedFile;\r
                AppState->CurrentState = WEBSERVER_STATE_OpenRequestedFile;\r
+               AppState->FileOpen     = false;\r
        }\r
        else if (uip_rexmit())\r
        {\r
@@ -128,31 +129,25 @@ void WebserverApp_Callback(void)
                        /* Wait for the packet containing the request header */\r
                        if (uip_newdata())\r
                        {\r
+                               char* RequestToken = strtok(AppData, " ");\r
+                       \r
                                /* Must be a GET request, abort otherwise */\r
-                               if (strncmp(AppData, "GET ", (sizeof("GET ") - 1)) != 0)\r
+                               if (strcmp(RequestToken, "GET") != 0)\r
                                {\r
                                        uip_abort();\r
                                        break;\r
                                }\r
                \r
-                               /* Copy over the requested filename from the GET request as all-lowercase */\r
-                               for (uint8_t i = 0; i < (sizeof(AppState->FileName) - 1); i++)\r
-                               {\r
-                                       AppState->FileName[i] = tolower(AppData[sizeof("GET ") + i]);\r
-                                       \r
-                                       if (AppState->FileName[i] == ' ')\r
-                                       {\r
-                                               AppState->FileName[i] = 0x00;\r
-                                               break;\r
-                                       }\r
-                               }\r
-                               \r
-                               /* Ensure requested filename is null-terminated */\r
-                               AppState->FileName[(sizeof(AppState->FileName) - 1)] = 0x00;\r
+                               char* RequestedFileName = strtok(NULL, " ");\r
                                \r
-                               /* If no filename specified, assume the default of index.htm */\r
-                               if (AppState->FileName[0] == 0x00)\r
+                               /* If the requested filename has more that just the leading '/' path in it, copy it over */\r
+                               if (strlen(RequestedFileName) > 1)\r
+                                 strncpy(AppState->FileName, &RequestedFileName[1], (sizeof(AppState->FileName) - 1));\r
+                               else\r
                                  strcpy(AppState->FileName, "index.htm");\r
+\r
+                               /* Ensure filename is null-terminated */\r
+                               AppState->FileName[(sizeof(AppState->FileName) - 1)] = 0x00;\r
                                \r
                                /* Try to open the file from the Dataflash disk */\r
                                AppState->FileOpen       = (f_open(&AppState->FileHandle, AppState->FileName, FA_OPEN_EXISTING | FA_READ) == FR_OK);\r
@@ -176,8 +171,6 @@ void WebserverApp_Callback(void)
                                strncpy_P(AppData, HTTP404Header, AppDataSize);\r
                        }\r
                        \r
-                       uip_send(AppData, AppDataSize);\r
-                       \r
                        AppState->PrevState    = WEBSERVER_STATE_SendResponseHeader;\r
                        AppState->CurrentState = WEBSERVER_STATE_SendMIMETypeHeader;\r
                        break;\r
@@ -213,8 +206,6 @@ void WebserverApp_Callback(void)
                                /* Add the end-of line terminator and end-of-headers terminator after the MIME type */\r
                                strncpy(&AppData[AppDataSize], "\r\n\r\n", sizeof("\r\n\r\n"));\r
                                AppDataSize += (sizeof("\r\n\r\n") - 1);\r
-                               \r
-                               uip_send(AppData, AppDataSize);\r
                        }\r
                                \r
                        AppState->PrevState    = WEBSERVER_STATE_SendMIMETypeHeader;\r
@@ -234,25 +225,26 @@ void WebserverApp_Callback(void)
 \r
                        uint16_t MaxSegSize = uip_mss();\r
                        \r
-                       /* Return file pointer to the last ACKed position if retransmitting */\r
+                       /* Return file pointer to the last ACKed position */\r
                        f_lseek(&AppState->FileHandle, AppState->CurrentFilePos);\r
 \r
                        /* Read the next chunk of data from the open file */\r
                        f_read(&AppState->FileHandle, AppData, MaxSegSize, &AppDataSize);\r
-                       AppState->FileOpen = (AppDataSize > 0);\r
 \r
-                       /* If data was read, send it to the client */\r
-                       if (AppDataSize)\r
+                       /* If we are not re-transmitting a lost segment, advance file position */\r
+                       if (uip_acked() && !(uip_rexmit()))\r
                        {\r
-                               /* If we are not re-transmitting a lost segment, advance file position */\r
-                               if (!(uip_rexmit()))\r
-                                 AppState->CurrentFilePos += AppDataSize;\r
-\r
-                               uip_send(AppData, AppDataSize);\r
+                               AppState->FileOpen = (AppDataSize > 0);\r
+                               AppState->CurrentFilePos += AppDataSize;\r
                        }\r
                        \r
+                       /* Stay in the SendData state if retransmission is required until all data sent */\r
                        AppState->PrevState = WEBSERVER_STATE_SendData;\r
 \r
                        break;\r
        }\r
+\r
+       /* If data has been loaded into the application buffer by the server, send it to the client */\r
+       if (AppDataSize)\r
+         uip_send(AppData, AppDataSize);\r
 }\r