Page 1 of 1

【已解决】file_server例程遇到的问题

Posted: Thu Aug 25, 2022 3:17 am
by linshc
我使用的IDF-4.4.2,使用file_server例程作为http server服务器。然后使用esp_http_client向file_server上传文件,使用的POST上传文件,上报时,报了一个405的警告。

Code: Select all

I (865851) esp_netif_lwip: DHCP server assigned IP to a station, IP is: 192.168.4.3
W (867401) wifi:<ba-add>idx:3 (ifx:1, 30:c6:f7:23:bd:2c), tid:0, ssn:0, winSize:64
I (867471) file_server: Sending file : /config.ini (206 bytes)...
I (867471) file_server: File sending complete
I (868061) file_server: Receiving file : /text.log...
I (868061) file_server: Remaining size : 19
I (868081) file_server: File reception complete
W (868361) httpd_uri: httpd_uri: Method '3' not allowed for URI '/'
W (868361) httpd_txrx: httpd_resp_send_err: 405 Method Not Allowed - Request method for this URI is not handled by server
file_server例程中配置了POST的方法,还出现了警告,应该怎么解决?

Code: Select all

    /* URI handler for uploading files to server */
    httpd_uri_t file_upload = {
        .uri       = "/upload/*",   // Match all URIs of type /upload/path/to/file
        .method    = HTTP_POST,
        .handler   = upload_post_handler,
        .user_ctx  = server_data    // Pass server data as context
    };
    httpd_register_uri_handler(server, &file_upload);

esp_http_client端就用了GET和POST两种

Code: Select all

char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
    /**
     * NOTE: All the configuration parameters for http_client must be spefied either in URL or as host and path parameters.
     * If host and path parameters are not set, query parameter will be ignored. In such cases,
     * query parameter should be specified in URL.
     *
     * If URL as well as host and path parameters are specified, values of host and path will be considered.
     */
    esp_http_client_config_t config = {
        // .host = "httpbin.org",
        // .path = "/get",
        // .query = "esp",
        .url = "http://192.168.4.1/config.ini",
        .event_handler = _http_event_handler,
        .user_data = local_response_buffer,        // Pass address of local buffer to get response
        //.disable_auto_redirect = true,
    };
    esp_http_client_handle_t client = esp_http_client_init(&config);

    // GET
    esp_err_t err = esp_http_client_perform(client);
    if (err == ESP_OK) {
        ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d",
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    } else {
        ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
    }
    ESP_LOG_BUFFER_HEX(TAG, local_response_buffer, strlen(local_response_buffer));

    // POST
    const char *post_data = "{\"field1\":\"value1\"}";
    esp_http_client_set_url(client, "http://192.168.4.1/upload/text.log");
    esp_http_client_set_method(client, HTTP_METHOD_POST);
    esp_http_client_set_header(client, "Content-Type", "application/json");
    esp_http_client_set_post_field(client, post_data, strlen(post_data));
    err = esp_http_client_perform(client);
    if (err == ESP_OK) {
        ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %d",
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    } else {
        ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
    }

Re: file_server例程遇到的问题

Posted: Thu Aug 25, 2022 3:25 am
by linshc
之前使用IDF-4.4.1时,没有出现上述的问题。是否是IDF-4.4.2做了一些什么改动?

Re: file_server例程遇到的问题

Posted: Thu Aug 25, 2022 8:48 am
by ESP_Gargamel
如果你确认 4.4.1 没有问题的话,可以用 4.4.1 的 server 和 client 和 4.4.2 的做个交叉验证,来排查是 server 的问题,还是 client 的问题。
方便的话,分别提供 server 和 client 的复现问题最小工程,可以看一下。

Re: file_server例程遇到的问题

Posted: Thu Sep 01, 2022 9:09 am
by linshc
交叉测试,发现是http_client的问题。
IDF4.4.2的client使用HTTP_METHOD_POST方法后,file_server会出现一个405警告。IDF4.4.1的client使用HTTP_METHOD_POST,file_server不会出现该警告。这里file_server使用的是IDF4.4.2,file_server注册了对HTTP_METHOD_POST方法的处理。
附件为对应的bin文件,使用的芯片为ESP32s3,flash为8M。分区表为默认的分区。
请您验证一下。

Re: file_server例程遇到的问题

Posted: Tue Sep 06, 2022 7:08 am
by linshc
经过代码的跟踪,发现是因为http 重定向引起的。在file server示例中注册了HTTP_POST,在upload_post_handler函数中,最后设置了303,后进行了重定向。然后新更新的IDF4.4.2添加了303和308的支持,所以才会出现两个版本的http client运行同样的程序,出不同的结果。由于对http协议不是很了解,没有及时发现这个问题。

Code: Select all

/* Redirect onto root to see the updated file list */
    httpd_resp_set_status(req, "303 See Other");
    httpd_resp_set_hdr(req, "Location", "/");
#ifdef CONFIG_EXAMPLE_HTTPD_CONN_CLOSE_HEADER
    httpd_resp_set_hdr(req, "Connection", "close");
#endif
    httpd_resp_sendstr(req, "File uploaded successfully");