59 * @param mod_since The date/time of the file, or NULL. |
59 * @param mod_since The date/time of the file, or NULL. |
60 * @param ipstr The IP address of the remote. |
60 * @param ipstr The IP address of the remote. |
61 */ |
61 */ |
62 static void http_sendfile(struct netconn *conn, char *url, char *mod_since, char *ipstr) |
62 static void http_sendfile(struct netconn *conn, char *url, char *mod_since, char *ipstr) |
63 { |
63 { |
64 char temp_url[128], temp_url_gz[128], header[128], c_type[32]; |
64 char temp_url[128], temp_url_gz[132], header[256], c_type[32]; |
65 struct stat st; |
65 struct stat st; |
66 off_t filesize; |
66 off_t filesize; |
67 size_t sentsize; |
67 size_t sentsize; |
68 char strftime_buf[64]; |
68 char strftime_buf[64]; |
69 err_t err; |
69 err_t err; |
83 temp_url[i] = '\0'; |
83 temp_url[i] = '\0'; |
84 if (temp_url[i] == '\0') |
84 if (temp_url[i] == '\0') |
85 break; |
85 break; |
86 } |
86 } |
87 } |
87 } |
88 sprintf(temp_url_gz, "%s.gz", temp_url); |
88 snprintf(temp_url_gz, 131, "%s.gz", temp_url); |
89 |
89 |
90 /* |
90 /* |
91 * Get filesize and date for the response headers. |
91 * Get filesize and date for the response headers. |
92 * Note that the /spiffs filesystem doesn't support file timestamps |
92 * Note that the /spiffs filesystem doesn't support file timestamps |
93 * and returns the epoch for each file. Therefore we cannot use |
93 * and returns the epoch for each file. Therefore we cannot use |
129 } else { |
129 } else { |
130 f = fopen(temp_url, "r"); |
130 f = fopen(temp_url, "r"); |
131 } |
131 } |
132 if (f == NULL) { |
132 if (f == NULL) { |
133 ESP_LOGI(TAG, "%s url \'%s\' file \'%s\' not found", ipstr, url, temp_url); |
133 ESP_LOGI(TAG, "%s url \'%s\' file \'%s\' not found", ipstr, url, temp_url); |
134 http_error(conn, 404, "Not found", "Not found"); |
134 http_error(conn, 404, (char *)"Not found", (char *)"Not found"); |
135 return; |
135 return; |
136 } |
136 } |
137 |
137 |
138 if (strcmp(".html", &temp_url[strlen(temp_url) - 5]) == 0) { |
138 if (strcmp(".html", &temp_url[strlen(temp_url) - 5]) == 0) { |
139 sprintf(c_type, "text/html"); |
139 sprintf(c_type, "text/html"); |
166 sprintf(header, "HTTP/1.1 200 OK\r\nLast-Modified: %s\r\nContent-Length: %ld\r\nContent-type: %s\r\n", strftime_buf, filesize, c_type); |
166 sprintf(header, "HTTP/1.1 200 OK\r\nLast-Modified: %s\r\nContent-Length: %ld\r\nContent-type: %s\r\n", strftime_buf, filesize, c_type); |
167 } else { |
167 } else { |
168 sprintf(header, "HTTP/1.1 200 OK\r\nContent-type: %s\r\n", c_type); |
168 sprintf(header, "HTTP/1.1 200 OK\r\nContent-type: %s\r\n", c_type); |
169 } |
169 } |
170 if (send_gz) { |
170 if (send_gz) { |
171 sprintf(header, "%sContent-Encoding: gzip\r\n", header); |
171 strncat(header, "Content-Encoding: gzip\r\n", 255 - strlen(header)); |
172 } |
172 } |
173 sprintf(header, "%s\r\n", header); // Add last empty line. |
173 strncat(header, "\r\n", 255 - strlen(header)); // Add last empty line. |
174 err = netconn_write(conn, header, strlen(header), NETCONN_NOCOPY); |
174 err = netconn_write(conn, header, strlen(header), NETCONN_NOCOPY); |
175 if (err != ERR_OK) { |
175 if (err != ERR_OK) { |
176 ESP_LOGE(TAG, "%s sendfile %s%s err=%d on header write", ipstr, temp_url, (send_gz) ? ".gz":"", err); |
176 ESP_LOGE(TAG, "%s sendfile %s%s err=%d on header write", ipstr, temp_url, (send_gz) ? ".gz":"", err); |
177 fclose(f); |
177 fclose(f); |
178 return; |
178 return; |
371 if (dir) { |
371 if (dir) { |
372 struct dirent* de = readdir(dir); |
372 struct dirent* de = readdir(dir); |
373 struct stat st; |
373 struct stat st; |
374 bool comma = false; |
374 bool comma = false; |
375 while (de) { |
375 while (de) { |
376 sprintf(temp, "/sdcard/w/log/%s", de->d_name); |
376 snprintf(temp, 63, "/sdcard/w/log/"); |
|
377 strncat(temp, de->d_name, 63 - strlen(temp)); |
377 if (stat(temp, &st) == ESP_OK) { |
378 if (stat(temp, &st) == ESP_OK) { |
378 fprintf(dest, "%s{\"File\":\"%s\",\"Size\":%ld,\"Date\":%ld}", (comma)?",":"", de->d_name, st.st_size, st.st_mtime); |
379 fprintf(dest, "%s{\"File\":\"%s\",\"Size\":%ld,\"Date\":%ld}", (comma)?",":"", de->d_name, st.st_size, st.st_mtime); |
379 comma = true; |
380 comma = true; |
380 } |
381 } |
381 de = readdir(dir); |
382 de = readdir(dir); |
388 fprintf(dest, "]}]}"); |
389 fprintf(dest, "]}]}"); |
389 fclose(dest); |
390 fclose(dest); |
390 } else { |
391 } else { |
391 ESP_LOGE(TAG, "Error %d write /spiffs/w/logfiles.json", errno); |
392 ESP_LOGE(TAG, "Error %d write /spiffs/w/logfiles.json", errno); |
392 } |
393 } |
393 http_sendfile(conn, "/logfiles.json", NULL, ipstr); |
394 http_sendfile(conn, (char *)"/logfiles.json", NULL, ipstr); |
394 netconn_close(conn); |
395 netconn_close(conn); |
395 netconn_delete(conn); |
396 netconn_delete(conn); |
396 netbuf_delete(inbuf); |
397 netbuf_delete(inbuf); |
397 unlink("/spiffs/w/logfiles.json"); |
398 unlink("/spiffs/w/logfiles.json"); |
398 return; |
399 return; |
419 return; |
420 return; |
420 } |
421 } |
421 |
422 |
422 // websocket for web UI. |
423 // websocket for web UI. |
423 if ((strstr(buf,"GET /ws ") && strstr(buf,"Upgrade: websocket"))) { |
424 if ((strstr(buf,"GET /ws ") && strstr(buf,"Upgrade: websocket"))) { |
424 int nr = ws_server_add_client_protocol(conn, buf, buflen, "/ws", "binary", websock_callback); |
425 int nr = ws_server_add_client_protocol(conn, buf, buflen, (char *)"/ws", (char *)"binary", websock_callback); |
425 ESP_LOGI(TAG, "%s new websocket on /ws client: %d", ipstr, nr); |
426 ESP_LOGI(TAG, "%s new websocket on /ws client: %d", ipstr, nr); |
426 netbuf_delete(inbuf); |
427 netbuf_delete(inbuf); |
427 TFTstartWS(nr); |
428 TFTstartWS(nr); |
428 // Startup something? Init webscreen? |
429 // Startup something? Init webscreen? |
429 return; |
430 return; |
433 dump_buf(buf, buflen); |
434 dump_buf(buf, buflen); |
434 #endif |
435 #endif |
435 |
436 |
436 if (strstr(buf, "GET /")) { |
437 if (strstr(buf, "GET /")) { |
437 ESP_LOGI(TAG, "%s request: %s", ipstr, buf); |
438 ESP_LOGI(TAG, "%s request: %s", ipstr, buf); |
438 http_error(conn, 404, "Not found", "Not found"); |
439 http_error(conn, 404, (char *)"Not found", (char *)"Not found"); |
439 } else { |
440 } else { |
440 http_error(conn, 405, "Invalid method", "Invalid method"); |
441 http_error(conn, 405, (char *)"Invalid method", (char *)"Invalid method"); |
441 } |
442 } |
442 } |
443 } |
443 |
444 |
444 netconn_close(conn); |
445 netconn_close(conn); |
445 netconn_delete(conn); |
446 netconn_delete(conn); |