/* Opens the default index html file */ struct fs_file *fs_open_default(void) { int hlen; struct file_ds *fds; struct fs_file *fs; fds = malloc(sizeof(*fds)); if (fds == NULL) { DEBUGSTR("Malloc Failure, Out of Memory!\r\n"); return NULL; } memset(fds, 0, sizeof(*fds)); fs = &fds->fs; fs->pextension = (void *) fds; /* Store this for later use */ hlen = get_http_headers("default.htm", (char *) fds->scratch); fs->data = (const char *) fds->scratch; memcpy((void *) &fs->data[hlen], (void *) http_index_html, sizeof(http_index_html) - 1); fs->len = hlen + sizeof(http_index_html) - 1; fs->index = fs->len; fs->http_header_included = 1; return fs; }
/* File open function */ struct fs_file *fs_open(const char *name) { FRESULT res; int hlen; struct file_ds *fds; struct fs_file *fs; if (!ipcex_getGblVal(SHGBL_USBDISKADDR)) return NULL; if (!Fatfs) { /* One time allocation not to be freed! */ Fatfs = malloc(sizeof(*Fatfs)); if (Fatfs == NULL) return NULL; f_mount(0, Fatfs); /* Never fails */ } /* Allocate file descriptor */ fds = malloc(sizeof(*fds)); if (fds == NULL) { DEBUGSTR("Malloc Failure, Out of Memory!\r\n"); return NULL; } res = f_open(&fds->fi, name, FA_READ); if (res) { LWIP_DEBUGF(HTTPD_DEBUG, ("DFS: OPEN: File %s does not exist\r\n", name)); free(fds); return NULL; } fs = &fds->fs; fds->fi_valid = 1; fs->pextension = (void *) fds; /* Store this for later use */ hlen = get_http_headers(name, (char *) fds->scratch); fs->data = (const char *) fds->scratch; fs->index = hlen; fs->len = f_size(&fds->fi) + hlen; fs->http_header_included = 1; return fs; }
/*..........................................................................*/ static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { int i; int loop; char *data; char const *uri; struct fs_file *file; struct http_state *hs = arg; #ifdef INCLUDE_HTTPD_CGI int count; char *params; #endif DEBUG_PRINT("http_recv 0x%08x\n", pcb); if (err == ERR_OK && p != NULL) { /* Inform TCP that we have taken the data. */ tcp_recved(pcb, p->tot_len); if (hs->handle == NULL) { data = p->payload; uri = &data[4]; DEBUG_PRINT("Request:\n%s\n", data); if (strncmp(data, "GET ", 4) == 0) { /* * We have a GET request. Find the end of the URI by looking * for the HTTP marker. We can't just use strstr to find this * since the request came from an outside source and we can't * be sure that it is correctly formed. We need to make sure * that our search is bounded by the packet length so we do it * manually. If we don't find " HTTP", assume the request is * invalid and close the connection. */ for (i = 4; i < (p->len - 5); i++) { if ((data[i] == ' ') && (data[i + 1] == 'H') && (data[i + 2] == 'T') && (data[i + 3] == 'T') && (data[i + 4] == 'P')) { data[i] = 0; break; } } if (i == (p->len - 5)) { /* We failed to find " HTTP" in the request so assume it * is invalid */ DEBUG_PRINT("Invalid GET request. Closing.\n"); pbuf_free(p); close_conn(pcb, hs); return (ERR_OK); } #ifdef INCLUDE_HTTPD_SSI /* * By default, assume we will not be processing * server-side-includes tags */ hs->tag_check = FALSE; #endif /* * Have we been asked for the default root file? */ if ((uri[0] == '/') && (uri[1] == 0)) { /* * Try each of the configured default filenames until * we find one that exists. */ for (loop = 0; loop < NUM_DEFAULT_FILENAMES; loop++) { DEBUG_PRINT("Looking for %s...\n", g_psDefaultFilenames[loop].name); file = fs_open((char *)g_psDefaultFilenames[loop] .name); uri = (char *)g_psDefaultFilenames[loop].name; if (file != NULL) { DEBUG_PRINT("Opened.\n"); #ifdef INCLUDE_HTTPD_SSI hs->tag_check = g_psDefaultFilenames[loop].shtml; #endif break; } } if (file == NULL) { /* None of the default filenames exist so send back * a 404 page */ file = get_404_file(&uri); #ifdef INCLUDE_HTTPD_SSI hs->tag_check = FALSE; #endif } } else { /* No - we've been asked for a specific file. */ #ifdef INCLUDE_HTTPD_CGI /* First, isolate the base URI (without any parameters) */ params = strchr(uri, '?'); if (params) { *params = '\0'; params++; } /* Does the base URI we have isolated correspond to * a CGI handler? */ if (g_iNumCGIs && g_pCGIs) { for (i = 0; i < g_iNumCGIs; i++) { if (strcmp(uri, g_pCGIs[i].pcCGIName) == 0) { /* * We found a CGI that handles this URI so * extract the parameters and call the handler */ count = extract_uri_parameters(hs, params); uri = (*g_pCGIs[i].pfnCGIHandler)(i, count, hs->params, hs->param_vals); break; } } /* Did we handle this URL as a CGI? If not, reinstate * the original URL and pass it to the file system * directly */ if (i == g_iNumCGIs) { /* Replace the ? marker at the beginning of the * parameters */ if (params) { params--; *params = '?'; } } } #endif DEBUG_PRINT("Opening %s\n", uri); file = fs_open(uri); if (file == NULL) { file = get_404_file(&uri); } #ifdef INCLUDE_HTTPD_SSI else { /* * See if we have been asked for an shtml file and, * if so, enable tag checking. */ hs->tag_check = FALSE; for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) { if (strstr(uri, g_pcSSIExtensions[loop])) { hs->tag_check = TRUE; break; } } } #endif /* INCLUDE_HTTP_SSI */ } if (file) { #ifdef INCLUDE_HTTPD_SSI hs->tag_index = 0; hs->tag_state = TAG_NONE; hs->parsed = file->data; hs->parse_left = file->len; hs->tag_end = file->data; #endif hs->handle = file; hs->file = file->data; LWIP_ASSERT("File length must be positive!", (file->len >= 0)); hs->left = file->len; hs->retries = 0; pbuf_free(p); } else { hs->handle = NULL; hs->file = NULL; hs->left = 0; hs->retries = 0; } #ifdef DYNAMIC_HTTP_HEADERS /* Determine the HTTP headers to send based on the file * extension of the requested URI. */ get_http_headers(hs, uri); #endif /* Tell TCP that we wish be to informed of data that has been * successfully sent by a call to the http_sent() function. */ tcp_sent(pcb, http_sent); /* Start sending the headers and file data. */ send_data(pcb, hs); } else { pbuf_free(p); close_conn(pcb, hs); } } else { pbuf_free(p); } } if (err == ERR_OK && p == NULL) { close_conn(pcb, hs); } return ERR_OK; }
/* Read http header information into a string */ int GetHTTP_Header(const char *fName, char *buff) { return get_http_headers(fName, buff); }