Git Product home page Git Product logo

Comments (12)

zonque avatar zonque commented on July 3, 2024

It's been a while since I last tried it, but in my tests things worked very well. There were some corner cases with moving files between folders, but plain read and write was not an issue. I used edpídf 4.x tho.

You seem to have dug deep enough already to find the root cause :) If you do and the bug is in this library, please file a PR!

from webdavserver.

zonque avatar zonque commented on July 3, 2024

You could also give the libsoup example a spin. It uses the exact same DAV implementation and was quite helpful during development on a desktop PC.

from webdavserver.

idolpx avatar idolpx commented on July 3, 2024

Will do. If you get a moment and can check it on esp32 to confirm it is or not working that would be great.
Maybe I'm doing something wrong.

I'm not familiar with libsoup. I will try that too.

I did find that I have to strip the trailing slash off of paths to get a directory listing from the sd card mounted into the vfs at "/sd". That was easy enough though.

from webdavserver.

zonque avatar zonque commented on July 3, 2024

What might be relevant is that I only tested this with the Linux gvfs implementation. I didn't have a Mac around when I hacked on that. Could you try a Linux machine?

from webdavserver.

idolpx avatar idolpx commented on July 3, 2024

I could try that but am most interested in getting it working on ESP32.

I do have a Linux VM on my macbook though.

from webdavserver.

zonque avatar zonque commented on July 3, 2024

No what I meant was: I had an esp32 as server, but used Linux as DAV client.

from webdavserver.

idolpx avatar idolpx commented on July 3, 2024

Oh... ok. I did try cadaver but it does not like the chunked encoding.

What client did you use on Linux?

from webdavserver.

idolpx avatar idolpx commented on July 3, 2024

Oh.. I see gvfs? I will check and see if that is on my Linux server. I run Linux Mint on my home dev server.

from webdavserver.

idolpx avatar idolpx commented on July 3, 2024

I did try mounting it with the file manager and it didn't like that either. I will try again.

from webdavserver.

idolpx avatar idolpx commented on July 3, 2024

Well my theory about the bug with httpd_resp_send_chunk() was wrong. I wrote a small test program and it works just fine. It doesn't do anything except return a list of 20 fake files but it works without issue. I will update when I have more info.

Here's the test program btw.

#include <driver/timer.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <nvs_flash.h>
#include <stdio.h>
#include <esp_log.h>

#include <esp_http_server.h>
#include <esp_wifi.h>

#include <string>
#include <sstream>

#define CONFIG_WIFI_SSID       "WIFI_SSID"
#define CONFIG_WIFI_PASSWORD   "password"

static const char *TAG = "httpd chunk test";

static httpd_handle_t server = NULL;

static esp_err_t sendHEAD(httpd_req_t *req)
{
    httpd_resp_set_status(req, "200 OK");

    httpd_resp_send_chunk(req, NULL, 0);
    return ESP_OK;
}

static esp_err_t sendPROPFIND(httpd_req_t *req)
{
    httpd_resp_set_status(req, "207 Multi-Status");
    httpd_resp_set_type(req, "application/xml; charset=\"utf-8\"");
    httpd_resp_set_hdr(req, "DAV", "2");
    httpd_resp_set_hdr(req, "Allow", "PROPFIND,OPTIONS,DELETE,COPY,MOVE,HEAD,POST,PUT,GET");

    httpd_resp_send_chunk(req, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n", HTTPD_RESP_USE_STRLEN);
    httpd_resp_send_chunk(req, "<multistatus xmlns=\"DAV:\">\n", HTTPD_RESP_USE_STRLEN);

    // s << "<response>\n";
    // s << "<href>/</href>";
    // s << "<propstat><prop>\n";

    // s << "<displayname></displayname>";
    // s << "<getlastmodified>Wed, 16 Nov 02:14:28 GMT</getlastmodified>";
    // s << "<getetag>0</getetag>";
    // s << "<resourcetype>";
    // s << "<collection/>";
    // s << "</resourcetype>";

    // s << "</prop>\n";
    // s << "<status>HTTP/1.1 200 OK</status>";
    // s << "</propstat></response>\n";

    // httpd_resp_send_chunk(req, s.str().c_str(), HTTPD_RESP_USE_STRLEN);

    int i = 0;
    while ( i++ < 20)
    {
        //httpd_resp_send_chunk(req, ("This is chunck #" + std::to_string(i) + "<br/>\n").c_str(), -1);

        std::ostringstream s;
        s << "<response>\n";
        s << "<href>file" << std::to_string(i) << ".txt</href>";
        s << "<propstat><prop>\n";

        s << "<displayname>file" << std::to_string(i) << ".txt</displayname>";
        s << "<getlastmodified>Wed, 16 Nov 02:14:28 GMT</getlastmodified>";
        s << "<getetag>0</getetag>";
        s << "<resourcetype>";
        // s << "<collection/>";
        s << "</resourcetype>";

        s << "</prop>\n";
        s << "<status>HTTP/1.1 200 OK</status>";
        s << "</propstat></response>\n";

        httpd_resp_send_chunk(req, s.str().c_str(), HTTPD_RESP_USE_STRLEN);
    }

    httpd_resp_send_chunk(req, "</multistatus>\n", HTTPD_RESP_USE_STRLEN);

    httpd_resp_send_chunk(req, NULL, 0);
    return ESP_OK;
}

static httpd_uri_t http_head = {
    .uri        = "/",
    .method     = HTTP_HEAD,
    .handler    = sendHEAD,
    .user_ctx   = NULL
};

static httpd_uri_t http_propfind = {
    .uri        = "/",
    .method     = HTTP_PROPFIND,
    .handler    = sendPROPFIND,
    .user_ctx   = NULL
};

httpd_handle_t http_start_webserver(void)
{
    httpd_handle_t server = NULL;
    httpd_config_t config = HTTPD_DEFAULT_CONFIG();

    // Start the httpd server
    ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
    if (httpd_start(&server, &config) == ESP_OK) {
        // Set URI handlers
        ESP_LOGI(TAG, "Registering URI handlers");
        httpd_register_uri_handler(server, &http_head);
        httpd_register_uri_handler(server, &http_propfind);
        return server;
    }

    ESP_LOGI(TAG, "Error starting server!");
    return NULL;
}

void http_stop_webserver(httpd_handle_t server)
{
    // Stop the httpd server
    httpd_stop(server);
}

static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
{
    switch(event->event_id) {
    case SYSTEM_EVENT_STA_START:
        ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START");
        ESP_ERROR_CHECK(esp_wifi_connect());
        break;
    case SYSTEM_EVENT_STA_GOT_IP:

        ip4_addr_t ip4;
        ip4.addr = event->event_info.got_ip.ip_info.ip.addr;

        ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
        ESP_LOGI(TAG, "Got IP: '%s'", ip4addr_ntoa(&ip4));

        /* Start the web server */
        if (server == NULL) {
            server = http_start_webserver();
        }
        break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
        ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED");
        ESP_ERROR_CHECK(esp_wifi_connect());

        /* Stop the web server */
        if (server) {
            http_stop_webserver(server);
            server = NULL;
        }
        break;
    default:
        break;
    }
    return ESP_OK;
}

void wifi_initialise()
{
    tcpip_adapter_init();
    ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL));
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));

    wifi_config_t wifi_config;
    memset(&wifi_config, 0, sizeof(wifi_config));

    strlcpy((char *)wifi_config.sta.ssid, CONFIG_WIFI_SSID, sizeof(wifi_config.sta.ssid));
    strlcpy((char *)wifi_config.sta.password, CONFIG_WIFI_PASSWORD, sizeof(wifi_config.sta.password));

    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());
}

extern "C"
{
    void app_main()
    {
        ESP_ERROR_CHECK(nvs_flash_init());
        wifi_initialise();
    }
}

from webdavserver.

idolpx avatar idolpx commented on July 3, 2024

Screen Shot 2022-12-17 at 1 36 58 AM

from webdavserver.

idolpx avatar idolpx commented on July 3, 2024

Finally revisiting this and discovered what was going on. In your example "webdav_handler()" was returning the http status code rather than ESP_OK. That was causing the connection to immediately close and the last few chunks didn't get sent.

Fixing that resolves the issue I was describing here.

I found some other issues as well but I will bundle them up in a PR to submit later.
I still haven't quite got it working correctly when mounting it as a network location in Windows Explorer.
The date format didn't include the year and that was throwing it off initially but there are other inconsistencies.
Your code gave me a starting point. Thanks. :)

You can see it in action here. https://github.com/idolpx/meatloaf-specialty

from webdavserver.

Related Issues (1)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.