mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2026-01-31 23:01:05 +03:00
wip httpd implementation
This commit is contained in:
@@ -75,9 +75,6 @@ void CODE_RAM_LOCATION dns_server_stop(){
|
|||||||
|
|
||||||
|
|
||||||
void CODE_RAM_LOCATION dns_server(void *pvParameters) {
|
void CODE_RAM_LOCATION dns_server(void *pvParameters) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct sockaddr_in sa, ra;
|
struct sockaddr_in sa, ra;
|
||||||
|
|
||||||
/* Set redirection DNS hijack to the access point IP */
|
/* Set redirection DNS hijack to the access point IP */
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ static esp_err_t set_content_type_from_req(httpd_req_t *req)
|
|||||||
|
|
||||||
/* If name has trailing '/', respond with directory contents */
|
/* If name has trailing '/', respond with directory contents */
|
||||||
if (filename[strlen(filename) - 1] == '/') {
|
if (filename[strlen(filename) - 1] == '/') {
|
||||||
httpd_resp_send_err(req, HTTPD_405_METHOD_NOT_ALLOWED, "Browsing files forbidden.");
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Browsing files forbidden.");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@@ -240,7 +240,7 @@ esp_err_t resource_filehandler(httpd_req_t *req){
|
|||||||
|
|
||||||
/* If name has trailing '/', respond with directory contents */
|
/* If name has trailing '/', respond with directory contents */
|
||||||
if (filename[strlen(filename) - 1] == '/') {
|
if (filename[strlen(filename) - 1] == '/') {
|
||||||
httpd_resp_send_err(req, HTTPD_405_METHOD_NOT_ALLOWED, "Browsing files forbidden.");
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Browsing files forbidden.");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,7 +321,7 @@ esp_err_t ap_get_handler(httpd_req_t *req){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
httpd_resp_send_err(req, HTTPD_503_NOT_FOUND, "AP list unavailable");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "AP list unavailable");
|
||||||
ESP_LOGE(TAG, "GET /ap.json failed to obtain mutex");
|
ESP_LOGE(TAG, "GET /ap.json failed to obtain mutex");
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
@@ -338,7 +338,7 @@ esp_err_t config_get_handler(httpd_req_t *req){
|
|||||||
char * json = config_alloc_get_json(false);
|
char * json = config_alloc_get_json(false);
|
||||||
if(json==NULL){
|
if(json==NULL){
|
||||||
ESP_LOGD(TAG, "Error retrieving config json string. ");
|
ESP_LOGD(TAG, "Error retrieving config json string. ");
|
||||||
httpd_resp_send_err(req, HTTPD_503_NOT_FOUND, "Error retrieving configuration object");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Error retrieving configuration object");
|
||||||
err=ESP_FAIL;
|
err=ESP_FAIL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -358,14 +358,14 @@ esp_err_t post_handler_buff_receive(httpd_req_t * req){
|
|||||||
int received = 0;
|
int received = 0;
|
||||||
if (total_len >= SCRATCH_BUFSIZE) {
|
if (total_len >= SCRATCH_BUFSIZE) {
|
||||||
/* Respond with 500 Internal Server Error */
|
/* Respond with 500 Internal Server Error */
|
||||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "content too long");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Content too long");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
while (cur_len < total_len) {
|
while (cur_len < total_len) {
|
||||||
received = httpd_req_recv(req, buf + cur_len, total_len);
|
received = httpd_req_recv(req, buf + cur_len, total_len);
|
||||||
if (received <= 0) {
|
if (received <= 0) {
|
||||||
/* Respond with 500 Internal Server Error */
|
/* Respond with 500 Internal Server Error */
|
||||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to post control value");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Failed to post control value");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
cur_len += received;
|
cur_len += received;
|
||||||
@@ -379,7 +379,6 @@ esp_err_t config_post_handler(httpd_req_t *req){
|
|||||||
char * otaURL=NULL;
|
char * otaURL=NULL;
|
||||||
esp_err_t err = post_handler_buff_receive(req);
|
esp_err_t err = post_handler_buff_receive(req);
|
||||||
if(err!=ESP_OK){
|
if(err!=ESP_OK){
|
||||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "content too long");
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if(!is_user_authenticated(httpd_req_t *req)){
|
if(!is_user_authenticated(httpd_req_t *req)){
|
||||||
@@ -420,7 +419,7 @@ esp_err_t config_post_handler(httpd_req_t *req){
|
|||||||
else {
|
else {
|
||||||
if(config_set_value(item_type, last_parm_name , last_parm) != ESP_OK){
|
if(config_set_value(item_type, last_parm_name , last_parm) != ESP_OK){
|
||||||
ESP_LOGE(TAG,"Unable to store value for [%s]", prev_item->name);
|
ESP_LOGE(TAG,"Unable to store value for [%s]", prev_item->name);
|
||||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to store config value");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Unable to store config value");
|
||||||
err = ESP_FAIL;
|
err = ESP_FAIL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -471,7 +470,6 @@ esp_err_t connect_post_handler(httpd_req_t *req){
|
|||||||
set_content_type_from_req(req);
|
set_content_type_from_req(req);
|
||||||
esp_err_t err = post_handler_buff_receive(req);
|
esp_err_t err = post_handler_buff_receive(req);
|
||||||
if(err!=ESP_OK){
|
if(err!=ESP_OK){
|
||||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "content too long");
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch;
|
char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch;
|
||||||
@@ -482,7 +480,7 @@ esp_err_t connect_post_handler(httpd_req_t *req){
|
|||||||
cJSON *root = cJSON_Parse(buf);
|
cJSON *root = cJSON_Parse(buf);
|
||||||
|
|
||||||
if(root==NULL){
|
if(root==NULL){
|
||||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "content too long");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "JSON parsing error.");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,18 +590,126 @@ esp_err_t status_post_handler(httpd_req_t *req){
|
|||||||
free(buff);
|
free(buff);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
httpd_resp_send_err(req, HTTPD_503_NOT_FOUND, "Empty status object");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Empty status object");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
httpd_resp_send_err(req, HTTPD_503_NOT_FOUND, "Error retrieving status object");
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Error retrieving status object");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t err_handler(httpd_req_t *req, httpd_err_code_t error){
|
||||||
|
ESP_LOGI(TAG, "serving [%s]", req->uri);
|
||||||
|
char success[]="";
|
||||||
|
if(!is_user_authenticated(httpd_req_t *req)){
|
||||||
|
// todo: redirect to login page
|
||||||
|
// return ESP_OK;
|
||||||
|
}
|
||||||
|
if(error != HTTPD_404_NOT_FOUND){
|
||||||
|
return httpd_resp_send_err(req, error, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * ap_ip_address= config_alloc_get_default(NVS_TYPE_STR, "ap_ip_address", DEFAULT_AP_IP, 0);
|
||||||
|
if(ap_ip_address==NULL){
|
||||||
|
ESP_LOGE(TAG, "Unable to retrieve default AP IP Address");
|
||||||
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR , "Unable to retrieve default AP IP Address");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct httpd_req_aux *ra = req->aux;
|
||||||
|
//UF_HOST
|
||||||
|
|
||||||
|
|
||||||
|
// ip_addr_t remote_add;
|
||||||
|
// err_t err;
|
||||||
|
|
||||||
|
|
||||||
|
// u16_t buflen;
|
||||||
|
// u16_t port;
|
||||||
|
|
||||||
|
|
||||||
|
// ESP_LOGV(TAG, "Getting remote device IP address.");
|
||||||
|
// netconn_getaddr(conn, &remote_add, &port, 0);
|
||||||
|
// char * remote_address = strdup(ip4addr_ntoa(ip_2_ip4(&remote_add)));
|
||||||
|
// ESP_LOGD(TAG, "Local Access Point IP address is: %s. Remote device IP address is %s. Receiving request buffer", ap_ip_address, remote_address);
|
||||||
|
// err = netconn_recv(conn, &inbuf);
|
||||||
|
// if(err == ERR_OK) {
|
||||||
|
// ESP_LOGV(TAG, "Getting data buffer.");
|
||||||
|
// netbuf_data(inbuf, (void**)&buf, &buflen);
|
||||||
|
// dump_net_buffer(buf, buflen);
|
||||||
|
// int lenH = 0;
|
||||||
|
// /* extract the first line of the request */
|
||||||
|
// char *save_ptr = buf;
|
||||||
|
// char *line = strtok_r(save_ptr, new_line, &save_ptr);
|
||||||
|
// char *temphost = http_server_get_header(save_ptr, "Host: ", &lenH);
|
||||||
|
// char * host = malloc(lenH+1);
|
||||||
|
// memset(host,0x00,lenH+1);
|
||||||
|
// if(lenH>0){
|
||||||
|
// strlcpy(host,temphost,lenH+1);
|
||||||
|
// }
|
||||||
|
// ESP_LOGD(TAG, "http_server_netconn_serve Host: [%s], host: [%s], Processing line [%s]",remote_address,host,line);
|
||||||
|
//
|
||||||
|
// if(line) {
|
||||||
|
//
|
||||||
|
// /* captive portal functionality: redirect to access point IP for HOST that are not the access point IP OR the STA IP */
|
||||||
|
// const char * host_name=NULL;
|
||||||
|
// if((err=tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &host_name )) !=ESP_OK) {
|
||||||
|
// ESP_LOGE(TAG, "Unable to get host name. Error: %s",esp_err_to_name(err));
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// ESP_LOGI(TAG,"System host name %s, http requested host: %s.",host_name, host);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /* determine if Host is from the STA IP address */
|
||||||
|
// wifi_manager_lock_sta_ip_string(portMAX_DELAY);
|
||||||
|
// bool access_from_sta_ip = lenH > 0?strcasestr(host, wifi_manager_get_sta_ip_string()):false;
|
||||||
|
// wifi_manager_unlock_sta_ip_string();
|
||||||
|
// bool access_from_host_name = (host_name!=NULL) && strcasestr(host,host_name);
|
||||||
|
//
|
||||||
|
// if(lenH > 0 && !strcasestr(host, ap_ip_address) && !(access_from_sta_ip || access_from_host_name)) {
|
||||||
|
// ESP_LOGI(TAG, "Redirecting host [%s] to AP IP Address : %s",remote_address, ap_ip_address);
|
||||||
|
// netconn_write(conn, http_redirect_hdr_start, sizeof(http_redirect_hdr_start) - 1, NETCONN_NOCOPY);
|
||||||
|
// netconn_write(conn, ap_ip_address, strlen(ap_ip_address), NETCONN_NOCOPY);
|
||||||
|
// netconn_write(conn, http_redirect_hdr_end, sizeof(http_redirect_hdr_end) - 1, NETCONN_NOCOPY);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
set_content_type_from_req(req);
|
||||||
|
httpd_resp_send(req, (const char *)NULL, 0);
|
||||||
|
wifi_manager_reboot(RECOVERY);
|
||||||
|
FREE_AND_NULL(ap_ip_address);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ esp_err_t reboot_post_handler(httpd_req_t *req);
|
|||||||
esp_err_t recovery_post_handler(httpd_req_t *req);
|
esp_err_t recovery_post_handler(httpd_req_t *req);
|
||||||
esp_err_t status_post_handler(httpd_req_t *req);
|
esp_err_t status_post_handler(httpd_req_t *req);
|
||||||
esp_err_t ap_scan_handler(httpd_req_t *req);
|
esp_err_t ap_scan_handler(httpd_req_t *req);
|
||||||
|
esp_err_t err_handler(httpd_req_t *req, httpd_err_code_t error);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,43 @@ typedef struct rest_server_context {
|
|||||||
#define ESP_LOGD_LOC(t,str, ...) ESP_LOGD(t, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
#define ESP_LOGD_LOC(t,str, ...) ESP_LOGD(t, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void register_common_handlers(httpd_handle_t server){
|
||||||
|
httpd_uri_t res_get = { .uri = "/res/*", .method = HTTP_GET, .handler = resource_filehandler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &res_get);
|
||||||
|
|
||||||
|
}
|
||||||
|
void register_regular_handlers(httpd_handle_t server){
|
||||||
|
httpd_uri_t root_get = { .uri = "/", .method = HTTP_GET, .handler = root_get_handler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &root_get);
|
||||||
|
|
||||||
|
httpd_uri_t ap_get = { .uri = "/ap.json", .method = HTTP_GET, .handler = ap_get_handler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &ap_get);
|
||||||
|
httpd_uri_t scan_get = { .uri = "/scan.json", .method = HTTP_GET, .handler = ap_scan_handler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &scan_get);
|
||||||
|
httpd_uri_t config_get = { .uri = "/config.json", .method = HTTP_GET, .handler = config_get_handler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &config_get);
|
||||||
|
httpd_uri_t status_get = { .uri = "/status.json", .method = HTTP_GET, .handler = status_get_handler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &status_get);
|
||||||
|
|
||||||
|
httpd_uri_t config_post = { .uri = "/config.json", .method = HTTP_POST, .handler = config_post_handler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &config_post);
|
||||||
|
httpd_uri_t connect_post = { .uri = "/connect.json", .method = HTTP_POST, .handler = connect_post_handler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &connect_post);
|
||||||
|
|
||||||
|
httpd_uri_t reboot_ota_post = { .uri = "/reboot_ota.json", .method = HTTP_POST, .handler = reboot_ota_post_handler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &reboot_ota_post);
|
||||||
|
|
||||||
|
httpd_uri_t reboot_post = { .uri = "/reboot.json", .method = HTTP_POST, .handler = reboot_post_handler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &reboot_post);
|
||||||
|
|
||||||
|
httpd_uri_t recovery_post = { .uri = "/recovery.json", .method = HTTP_POST, .handler = recovery_post_handler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &recovery_post);
|
||||||
|
|
||||||
|
httpd_uri_t connect_delete = { .uri = "/connect.json", .method = HTTP_DELETE, .handler = connect_delete_handler, .user_ctx = rest_context };
|
||||||
|
httpd_register_uri_handler(server, &connect_delete);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t http_server_start()
|
esp_err_t http_server_start()
|
||||||
{
|
{
|
||||||
ESP_LOGI(REST_TAG, "Initializing HTTP Server");
|
ESP_LOGI(REST_TAG, "Initializing HTTP Server");
|
||||||
@@ -58,6 +95,8 @@ esp_err_t http_server_start()
|
|||||||
httpd_handle_t server = NULL;
|
httpd_handle_t server = NULL;
|
||||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||||
config.uri_match_fn = httpd_uri_match_wildcard;
|
config.uri_match_fn = httpd_uri_match_wildcard;
|
||||||
|
//todo: use this to configure session token?
|
||||||
|
// config.open_fn
|
||||||
|
|
||||||
ESP_LOGI(REST_TAG, "Starting HTTP Server");
|
ESP_LOGI(REST_TAG, "Starting HTTP Server");
|
||||||
esp_err_t err= httpd_start(&server, &config);
|
esp_err_t err= httpd_start(&server, &config);
|
||||||
@@ -66,39 +105,11 @@ esp_err_t http_server_start()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
httpd_uri_t root_get = { .uri = "/", .method = HTTP_GET, .handler = root_get_handler, .user_ctx = rest_context };
|
register_common_handlers(server);
|
||||||
httpd_register_uri_handler(server, &root_get);
|
register_regular_handlers(server);
|
||||||
httpd_uri_t res_get = { .uri = "/res/*", .method = HTTP_GET, .handler = resource_filehandler, .user_ctx = rest_context };
|
|
||||||
httpd_register_uri_handler(server, &res_get);
|
|
||||||
|
|
||||||
httpd_uri_t ap_get = { .uri = "/ap.json", .method = HTTP_GET, .handler = ap_get_handler, .user_ctx = rest_context };
|
|
||||||
httpd_register_uri_handler(server, &ap_get);
|
|
||||||
httpd_uri_t scan_get = { .uri = "/scan.json", .method = HTTP_GET, .handler = ap_scan_handler, .user_ctx = rest_context };
|
|
||||||
httpd_register_uri_handler(server, &scan_get);
|
|
||||||
httpd_uri_t config_get = { .uri = "/config.json", .method = HTTP_GET, .handler = config_get_handler, .user_ctx = rest_context };
|
|
||||||
httpd_register_uri_handler(server, &config_get);
|
|
||||||
httpd_uri_t status_get = { .uri = "/status.json", .method = HTTP_GET, .handler = status_get_handler, .user_ctx = rest_context };
|
|
||||||
httpd_register_uri_handler(server, &status_get);
|
|
||||||
|
|
||||||
|
|
||||||
httpd_uri_t config_post = { .uri = "/config.json", .method = HTTP_POST, .handler = config_post_handler, .user_ctx = rest_context };
|
|
||||||
httpd_register_uri_handler(server, &config_post);
|
|
||||||
httpd_uri_t connect_post = { .uri = "/connect.json", .method = HTTP_POST, .handler = connect_post_handler, .user_ctx = rest_context };
|
|
||||||
httpd_register_uri_handler(server, &connect_post);
|
|
||||||
|
|
||||||
httpd_uri_t reboot_ota_post = { .uri = "/reboot_ota.json", .method = HTTP_POST, .handler = reboot_ota_post_handler, .user_ctx = rest_context };
|
|
||||||
httpd_register_uri_handler(server, &reboot_ota_post);
|
|
||||||
|
|
||||||
httpd_uri_t reboot_post = { .uri = "/reboot.json", .method = HTTP_POST, .handler = reboot_post_handler, .user_ctx = rest_context };
|
|
||||||
httpd_register_uri_handler(server, &reboot_post);
|
|
||||||
|
|
||||||
httpd_uri_t recovery_post = { .uri = "/recovery.json", .method = HTTP_POST, .handler = recovery_post_handler, .user_ctx = rest_context };
|
|
||||||
httpd_register_uri_handler(server, &recovery_post);
|
|
||||||
|
|
||||||
httpd_uri_t connect_delete = { .uri = "/connect.json", .method = HTTP_DELETE, .handler = connect_delete_handler, .user_ctx = rest_context };
|
|
||||||
httpd_register_uri_handler(server, &connect_delete);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
register_err_handler(server, HTTPD_404_NOT_FOUND,&err_handler);
|
||||||
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user