123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- #define INCLUDE_FROM_HTTPSERVERAPP_C
- #include "HTTPServerApp.h"
- const char PROGMEM HTTP200Header[] = "HTTP/1.1 200 OK\r\n"
- "Server: LUFA " LUFA_VERSION_STRING "\r\n"
- "Connection: close\r\n"
- "MIME-version: 1.0\r\n"
- "Content-Type: ";
- const char PROGMEM HTTP404Header[] = "HTTP/1.1 404 Not Found\r\n"
- "Server: LUFA " LUFA_VERSION_STRING "\r\n"
- "Connection: close\r\n"
- "MIME-version: 1.0\r\n"
- "Content-Type: text/plain\r\n\r\n"
- "Error 404: File Not Found: /";
- const char PROGMEM DefaultDirFileName[] = "index.htm";
- const char PROGMEM DefaultMIMEType[] = "text/plain";
- const MIME_Type_t MIMETypes[] =
- {
- {.Extension = "htm", .MIMEType = "text/html"},
- {.Extension = "jpg", .MIMEType = "image/jpeg"},
- {.Extension = "gif", .MIMEType = "image/gif"},
- {.Extension = "bmp", .MIMEType = "image/bmp"},
- {.Extension = "png", .MIMEType = "image/png"},
- {.Extension = "ico", .MIMEType = "image/x-icon"},
- {.Extension = "exe", .MIMEType = "application/octet-stream"},
- {.Extension = "gz", .MIMEType = "application/x-gzip"},
- {.Extension = "zip", .MIMEType = "application/zip"},
- {.Extension = "pdf", .MIMEType = "application/pdf"},
- };
- FATFS DiskFATState;
- void HTTPServerApp_Init(void)
- {
-
- uip_listen(HTONS(HTTP_SERVER_PORT));
-
- f_mount(0, &DiskFATState);
- }
- void HTTPServerApp_Callback(void)
- {
- uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
- if (uip_aborted() || uip_timedout() || uip_closed())
- {
-
- AppState->HTTPServer.CurrentState = WEBSERVER_STATE_Closing;
- AppState->HTTPServer.NextState = WEBSERVER_STATE_Closing;
- }
- if (uip_connected())
- {
-
- AppState->HTTPServer.CurrentState = WEBSERVER_STATE_OpenRequestedFile;
- AppState->HTTPServer.NextState = WEBSERVER_STATE_OpenRequestedFile;
- AppState->HTTPServer.FileOpen = false;
- AppState->HTTPServer.ACKedFilePos = 0;
- AppState->HTTPServer.SentChunkSize = 0;
- }
- if (uip_acked())
- {
-
- AppState->HTTPServer.ACKedFilePos += AppState->HTTPServer.SentChunkSize;
-
- AppState->HTTPServer.CurrentState = AppState->HTTPServer.NextState;
- }
- if (uip_rexmit())
- {
-
- f_lseek(&AppState->HTTPServer.FileHandle, AppState->HTTPServer.ACKedFilePos);
- }
- if (uip_rexmit() || uip_acked() || uip_newdata() || uip_connected() || uip_poll())
- {
- switch (AppState->HTTPServer.CurrentState)
- {
- case WEBSERVER_STATE_OpenRequestedFile:
- HTTPServerApp_OpenRequestedFile();
- break;
- case WEBSERVER_STATE_SendResponseHeader:
- HTTPServerApp_SendResponseHeader();
- break;
- case WEBSERVER_STATE_SendData:
- HTTPServerApp_SendData();
- break;
- case WEBSERVER_STATE_Closing:
-
- f_close(&AppState->HTTPServer.FileHandle);
- AppState->HTTPServer.FileOpen = false;
-
- uip_close();
- AppState->HTTPServer.CurrentState = WEBSERVER_STATE_Closed;
- AppState->HTTPServer.NextState = WEBSERVER_STATE_Closed;
- break;
- }
- }
- }
- static void HTTPServerApp_OpenRequestedFile(void)
- {
- uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
- char* const AppData = (char*)uip_appdata;
-
- if (!(uip_newdata()))
- return;
- char* RequestToken = strtok(AppData, " ");
- char* RequestedFileName = strtok(NULL, " ");
-
- if (strcmp_P(RequestToken, PSTR("GET")) != 0)
- {
- uip_abort();
- return;
- }
-
- strlcpy(AppState->HTTPServer.FileName, &RequestedFileName[1], sizeof(AppState->HTTPServer.FileName));
-
- uint8_t FileNameLen = strlen(AppState->HTTPServer.FileName);
-
- if ((AppState->HTTPServer.FileName[FileNameLen - 1] == '/') || !(FileNameLen))
- {
- strlcpy_P(&AppState->HTTPServer.FileName[FileNameLen], DefaultDirFileName,
- (sizeof(AppState->HTTPServer.FileName) - FileNameLen));
- }
-
- AppState->HTTPServer.FileOpen = (f_open(&AppState->HTTPServer.FileHandle, AppState->HTTPServer.FileName,
- (FA_OPEN_EXISTING | FA_READ)) == FR_OK);
-
- AppState->HTTPServer.CurrentState = WEBSERVER_STATE_SendResponseHeader;
- AppState->HTTPServer.NextState = WEBSERVER_STATE_SendResponseHeader;
- }
- static void HTTPServerApp_SendResponseHeader(void)
- {
- uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
- char* const AppData = (char*)uip_appdata;
- char* Extension = strpbrk(AppState->HTTPServer.FileName, ".");
- bool FoundMIMEType = false;
-
- if (!(AppState->HTTPServer.FileOpen))
- {
-
- strcpy_P(AppData, HTTP404Header);
- strcat(AppData, AppState->HTTPServer.FileName);
- uip_send(AppData, strlen(AppData));
- AppState->HTTPServer.NextState = WEBSERVER_STATE_Closing;
- return;
- }
-
- strcpy_P(AppData, HTTP200Header);
-
- if (Extension != NULL)
- {
-
- for (uint8_t i = 0; i < (sizeof(MIMETypes) / sizeof(MIMETypes[0])); i++)
- {
- if (strcmp(&Extension[1], MIMETypes[i].Extension) == 0)
- {
- strcat(AppData, MIMETypes[i].MIMEType);
- FoundMIMEType = true;
- break;
- }
- }
- }
-
- if (!(FoundMIMEType))
- {
-
- strcat_P(AppData, DefaultMIMEType);
- }
-
- strcat_P(AppData, PSTR("\r\n\r\n"));
-
- uip_send(AppData, strlen(AppData));
-
- AppState->HTTPServer.NextState = WEBSERVER_STATE_SendData;
- }
- static void HTTPServerApp_SendData(void)
- {
- uip_tcp_appstate_t* const AppState = &uip_conn->appstate;
- char* const AppData = (char*)uip_appdata;
-
- uint16_t MaxChunkSize = uip_mss();
-
- f_read(&AppState->HTTPServer.FileHandle, AppData, MaxChunkSize, &AppState->HTTPServer.SentChunkSize);
-
- uip_send(AppData, AppState->HTTPServer.SentChunkSize);
-
- if (MaxChunkSize != AppState->HTTPServer.SentChunkSize)
- AppState->HTTPServer.NextState = WEBSERVER_STATE_Closing;
- }
|