# libnextcloud Shared Library Plan **Created**: 2026-01-27 **Status**: 📋 Planning **Target**: Cross-platform C++17 shared library for Nextcloud connectivity **Branch**: `create-libnextcloud` --- ## Overview Create `libnextcloud` - a cross-platform C++17 shared library that provides Nextcloud connectivity for embedded devices and homebrew platforms. The library will handle all Nextcloud communication, authentication, file operations, and settings management through a clean, platform-agnostic API. **Design Philosophy**: - **Platform-agnostic**: Works on 3DS, Switch, Wii U, Vita, PC, etc. - **Minimal dependencies**: Only libcurl, mbedTLS, and tinyxml2 - **Header-only where possible**: nlohmann/json for configuration - **Modern C++17**: Using standard library features - **Testable**: Mock-friendly design with dependency injection - **Documented**: Doxygen API documentation --- ## Project Structure ``` shared/ ├── include/ │ └── nextcloud/ │ ├── client.hpp # Main client interface │ ├── webdav_client.hpp # WebDAV protocol implementation │ ├── auth.hpp # Authentication manager │ ├── upload_manager.hpp # File upload with chunking │ ├── folder_manager.hpp # Remote folder operations │ ├── config.hpp # Configuration management │ ├── types.hpp # Common types and enums │ └── version.hpp # Library version info ├── src/ │ ├── webdav_client.cpp │ ├── auth.cpp │ ├── upload_manager.cpp │ ├── folder_manager.cpp │ └── config.cpp ├── tests/ │ ├── webdav_client_test.cpp │ ├── auth_test.cpp │ ├── upload_manager_test.cpp │ ├── folder_manager_test.cpp │ ├── config_test.cpp │ └── mocks/ │ ├── mock_http_client.hpp │ └── mock_xml_parser.hpp ├── examples/ │ ├── simple_upload.cpp │ ├── folder_listing.cpp │ └── authentication.cpp ├── docs/ │ ├── api.md # API documentation │ ├── architecture.md # Design overview │ └── Doxyfile # Doxygen configuration ├── CMakeLists.txt └── README.md ``` --- ## Dependencies ### Required - **libcurl** (7.68+): HTTP/HTTPS client - **mbedTLS** (2.16+): SSL/TLS support (works on embedded) - **tinyxml2** (9.0+): Lightweight XML parsing ### Header-Only - **nlohmann/json** (3.10+): JSON parsing/serialization ### Testing - **Google Test** (1.11+): Unit testing framework - **Google Mock** (1.11+): Mocking framework ### Build Tools - **CMake** (3.15+): Build system - **C++17 compiler**: GCC 7+, Clang 5+, MSVC 2017+ --- ## Implementation Phases ## Phase 1: Project Scaffolding (Issue #??) **Goal**: Set up the library project structure and build system. ### Tasks - [ ] Create `shared/` directory structure - [ ] Set up CMakeLists.txt with: - Library target (static/shared) - C++17 standard - Include directories - Dependency linking (curl, mbedtls, tinyxml2) - Install rules - Export config for downstream projects - [ ] Create version.hpp with semantic versioning - [ ] Create types.hpp with common enums and structures: - `NextcloudError` enum - `UploadProgress` struct - `FileInfo` struct - `FolderInfo` struct - [ ] Set up Google Test framework - [ ] Create basic README for the library - [ ] Add pkg-config file generation - [ ] Verify library compiles as standalone project ### Acceptance Criteria - [ ] CMake builds library successfully - [ ] Can link against library from test project - [ ] Version info accessible at runtime - [ ] Ready for component implementation **Estimated Time**: 4-6 hours **Priority**: Critical (blocks all other work) --- ## Phase 2: WebDAV Client (Issue #8) **Goal**: Implement HTTP/WebDAV communication layer. ### Tasks - [ ] Create `webdav_client.hpp` interface - [ ] Implement HTTP wrapper around libcurl: - GET, PUT, POST, DELETE, custom methods - Request/response headers - Request body (string, stream) - Response body handling - Timeout configuration - User-Agent setting - [ ] Add SSL/TLS support with mbedTLS - [ ] Implement WebDAV methods: - PROPFIND (list files/folders) - MKCOL (create folder) - PUT (upload file) - DELETE (remove file/folder) - MOVE (rename/move) - COPY (duplicate) - [ ] Parse WebDAV XML responses (using tinyxml2): - Multi-status responses - File properties (size, mtime, type) - Error responses - [ ] Implement error handling: - HTTP status codes - Network errors - XML parsing errors - Error code mapping - [ ] Add timeout and retry logic - [ ] Write unit tests with mocked HTTP - [ ] Document API in Doxygen format ### API Design ```cpp class WebDAVClient { public: WebDAVClient(const std::string& baseUrl); // Core HTTP Response get(const std::string& path); Response put(const std::string& path, const std::vector& data); Response delete_(const std::string& path); // WebDAV operations std::vector propfind(const std::string& path, int depth = 1); bool mkcol(const std::string& path); bool move(const std::string& from, const std::string& to); bool copy(const std::string& from, const std::string& to); // Configuration void setTimeout(int seconds); void setAuthHeader(const std::string& header); }; ``` ### Acceptance Criteria - [ ] All WebDAV methods implemented - [ ] SSL/TLS connections working - [ ] XML responses correctly parsed - [ ] Error handling comprehensive - [ ] Unit tests with >80% coverage - [ ] API documented - [ ] Works with test Nextcloud servers **Estimated Time**: 12-16 hours **Priority**: Critical (foundation for all features) **Dependencies**: Phase 1 complete --- ## Phase 3: Authentication System (Issue #9) **Goal**: Handle authentication with Nextcloud servers. ### Tasks - [ ] Create `auth.hpp` interface - [ ] Implement HTTP Basic Authentication: - Base64 encoding - Authorization header generation - Credential storage - [ ] Add authentication verification: - Test connection to server - Validate credentials - Return meaningful error codes - [ ] Secure credential handling: - In-memory only (no disk storage by default) - Platform-specific secure storage hooks - [ ] Session management: - Keep-alive connections - Connection pooling - Timeout handling - [ ] Future: OAuth2 support (stubbed for now) - [ ] Write unit tests for auth flows - [ ] Document security considerations ### API Design ```cpp class AuthManager { public: // Basic Auth void setBasicAuth(const std::string& username, const std::string& password); std::string getAuthHeader() const; // Verification bool verifyConnection(WebDAVClient& client); // Session management void clearCredentials(); bool hasCredentials() const; }; ``` ### Acceptance Criteria - [ ] Basic auth working with real Nextcloud - [ ] Credentials never logged or leaked - [ ] Connection verification works - [ ] Error messages helpful - [ ] Unit tests cover edge cases - [ ] API documented **Estimated Time**: 6-8 hours **Priority**: High **Dependencies**: Phase 2 complete --- ## Phase 4: Upload Manager (Issue #10) **Goal**: Implement file upload with chunking and progress tracking. ### Tasks - [ ] Create `upload_manager.hpp` interface - [ ] Implement streaming upload: - Read file in chunks - Send via PUT requests - Handle large files (>1GB) - [ ] Add chunking support: - Configurable chunk size (default: 10MB) - Resume capability (future) - Parallel chunks (future) - [ ] Progress tracking: - Callback interface - Bytes uploaded / total - Transfer speed - Time remaining estimate - [ ] Error handling and retry: - Network failures - Server errors (503, 507) - Automatic retry with backoff - Partial upload cleanup - [ ] Path handling: - URL encoding - Special characters - Nested folders - [ ] Write unit tests with mock uploads - [ ] Document upload best practices ### API Design ```cpp class UploadManager { public: using ProgressCallback = std::function; UploadManager(WebDAVClient& client, AuthManager& auth); // Upload operations bool uploadFile( const std::string& localPath, const std::string& remotePath, ProgressCallback callback = nullptr ); // Configuration void setChunkSize(size_t bytes); void setRetryCount(int count); void setTimeout(int seconds); }; struct UploadProgress { std::string filename; size_t bytesUploaded; size_t totalBytes; float percentComplete; float bytesPerSecond; int secondsRemaining; }; ``` ### Acceptance Criteria - [ ] Uploads files successfully - [ ] Chunking works for large files - [ ] Progress callback accurate - [ ] Handles network failures gracefully - [ ] Retries work correctly - [ ] Unit tests with various file sizes - [ ] API documented **Estimated Time**: 10-12 hours **Priority**: High **Dependencies**: Phases 2, 3 complete --- ## Phase 5: Folder Management (Issue #11) **Goal**: Remote folder operations and navigation. ### Tasks - [ ] Create `folder_manager.hpp` interface - [ ] Implement folder listing: - List contents of remote folder - Parse file metadata (size, mtime, type) - Recursive listing support - Filtering (files only, folders only) - [ ] Folder creation: - Create single folder - Create nested folders (mkdir -p) - Validate folder names - [ ] Folder navigation: - Path normalization - Parent folder detection - Breadcrumb generation - [ ] Caching (optional): - Cache folder contents - TTL-based invalidation - Memory limits - [ ] Write unit tests - [ ] Document folder operations ### API Design ```cpp class FolderManager { public: FolderManager(WebDAVClient& client, AuthManager& auth); // Folder operations std::vector listFolder(const std::string& path); bool createFolder(const std::string& path); bool createFolders(const std::string& path); // mkdir -p bool deleteFolder(const std::string& path); bool folderExists(const std::string& path); // Navigation helpers std::string getParentFolder(const std::string& path); std::vector getBreadcrumbs(const std::string& path); }; struct FileInfo { std::string name; std::string path; bool isDirectory; size_t size; time_t modifiedTime; std::string contentType; }; ``` ### Acceptance Criteria - [ ] Lists folders correctly - [ ] Creates folders successfully - [ ] Handles nested paths - [ ] Metadata parsing accurate - [ ] Unit tests comprehensive - [ ] API documented **Estimated Time**: 8-10 hours **Priority**: Medium **Dependencies**: Phases 2, 3 complete --- ## Phase 6: Favorites and Recent Folders (Issue #12) **Goal**: Persistence layer for user preferences. ### Tasks - [ ] Create `config.hpp` interface - [ ] Implement favorites management: - Add favorite folder - Remove favorite folder - List favorites - Reorder favorites - [ ] Implement recent folders tracking: - Auto-track used folders - Configurable limit (default: 5) - LRU eviction - Duplicate detection - [ ] JSON persistence: - Save to file - Load from file - Handle missing/corrupt files - Migration support - [ ] Platform-specific paths: - Linux: ~/.config/nextcloud-share/ - 3DS: /nextcloud-share/ - Switch: /switch/nextcloud-share/ - [ ] Write unit tests - [ ] Document config format ### API Design ```cpp class Config { public: Config(const std::string& configPath = ""); // Favorites void addFavorite(const std::string& path, const std::string& name = ""); void removeFavorite(const std::string& path); std::vector getFavorites() const; // Recent folders void addRecentFolder(const std::string& path); std::vector getRecentFolders() const; void setMaxRecentFolders(int count); // Persistence bool load(); bool save(); }; struct FolderInfo { std::string path; std::string displayName; time_t lastUsed; }; ``` ### Acceptance Criteria - [ ] Favorites persist across restarts - [ ] Recent folders tracked correctly - [ ] JSON format clean and readable - [ ] Handles missing config gracefully - [ ] Unit tests cover edge cases - [ ] API documented **Estimated Time**: 6-8 hours **Priority**: Low **Dependencies**: None (standalone) --- ## Phase 7: Testing and Documentation (Issue #13) **Goal**: Comprehensive test coverage and documentation. ### Tasks - [ ] Achieve >80% code coverage - [ ] Integration tests with real Nextcloud: - Test against cloud.tomusan.com - Test against disobedient.cloud - Verify all operations work - [ ] Mock server for offline testing: - Mock HTTP responses - Simulate errors - Test edge cases - [ ] Performance testing: - Large file uploads - Many small files - Concurrent operations - [ ] Generate Doxygen documentation - [ ] Write architecture document - [ ] Create usage examples - [ ] Document build process - [ ] Add API reference ### Documentation Structure ``` docs/ ├── api.md # Full API reference ├── architecture.md # Library design and internals ├── building.md # Build instructions ├── examples.md # Usage examples ├── testing.md # How to run tests ├── contributing.md # Contribution guidelines └── changelog.md # Version history ``` ### Acceptance Criteria - [ ] All classes have Doxygen comments - [ ] Code coverage >80% - [ ] Integration tests pass - [ ] Documentation complete - [ ] Examples compile and run - [ ] Ready for platform integration **Estimated Time**: 10-12 hours **Priority**: High **Dependencies**: All phases complete --- ## Issues to Create Based on this plan, create the following Gitea issues: ### Issue: Initialize libnextcloud Project Structure **Labels**: library, setup, priority:critical **Description**: ``` Set up the shared library project structure and build system for libnextcloud. ## Tasks - [ ] Create `shared/` directory structure - [ ] Set up CMakeLists.txt for library - [ ] Create version.hpp and types.hpp - [ ] Set up Google Test framework - [ ] Create basic README - [ ] Add pkg-config file generation - [ ] Verify library compiles standalone ## Dependencies - libcurl 7.68+ - mbedTLS 2.16+ - tinyxml2 9.0+ - Google Test 1.11+ ## Acceptance Criteria - [ ] CMake builds library successfully - [ ] Can link against library from test project - [ ] Version info accessible at runtime - [ ] Ready for component implementation Estimated: 4-6 hours Blocks: #8, #9, #10, #11, #12, #13 ``` ### Keep Existing Issues (Update Dependencies) **Issue #8**: Design and implement WebDAV client - Add dependency: "Requires libnextcloud scaffolding (new issue)" - Priority: High - Estimated: 12-16 hours **Issue #9**: Implement authentication system - Add dependency: "Requires #8" - Priority: High - Estimated: 6-8 hours **Issue #10**: Implement file upload functionality - Add dependency: "Requires #8, #9" - Priority: High - Estimated: 10-12 hours **Issue #11**: Implement folder management - Add dependency: "Requires #8, #9" - Priority: Medium - Estimated: 8-10 hours **Issue #12**: Implement favorites and recent folders - Priority: Low - Estimated: 6-8 hours **Issue #13**: Write unit tests for shared library - Add dependency: "Requires #8-#12" - Priority: High - Estimated: 10-12 hours --- ## Build System Design ### CMakeLists.txt Structure ```cmake cmake_minimum_required(VERSION 3.15) project(libnextcloud VERSION 0.1.0 LANGUAGES CXX) # C++17 required set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Library sources add_library(nextcloud src/webdav_client.cpp src/auth.cpp src/upload_manager.cpp src/folder_manager.cpp src/config.cpp ) # Include directories target_include_directories(nextcloud PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Dependencies find_package(CURL REQUIRED) find_package(MbedTLS REQUIRED) find_package(tinyxml2 REQUIRED) target_link_libraries(nextcloud PUBLIC CURL::libcurl MbedTLS::mbedtls tinyxml2::tinyxml2 ) # Testing if(BUILD_TESTING) enable_testing() add_subdirectory(tests) endif() # Install rules install(TARGETS nextcloud EXPORT nextcloudTargets) install(DIRECTORY include/ DESTINATION include) install(EXPORT nextcloudTargets FILE nextcloudTargets.cmake NAMESPACE nextcloud:: DESTINATION lib/cmake/nextcloud ) ``` ### Platform-Specific Considerations **Nintendo 3DS**: - Static library only (no shared objects) - mbedTLS available via dkp-pacman - libcurl with 3DS patches - Filesystem: `/nextcloud-share/config.json` **Nintendo Switch**: - Static library - Standard libcurl and mbedTLS - Filesystem: `/switch/nextcloud-share/config.json` **Linux/PC**: - Shared library (.so) or static - System libcurl and mbedTLS - Filesystem: `~/.config/nextcloud-share/config.json` --- ## Testing Strategy ### Unit Tests - Mock all external dependencies (HTTP, filesystem) - Test each class in isolation - Cover edge cases and error conditions - Fast execution (<1 second total) ### Integration Tests - Real HTTP requests to test Nextcloud servers - Require valid credentials from config.json - Test full workflows end-to-end - Can be skipped if credentials not available ### Performance Tests - Upload 1GB file and measure time - Upload 1000 small files - Concurrent uploads - Memory usage profiling ### Test Configuration ```json { "test": { "servers": [ { "name": "tomusan", "url": "https://cloud.tomusan.com", "username": "test", "password": "xxx" }, { "name": "disobedient", "url": "https://disobedient.cloud/nextcloud", "username": "test", "password": "xxx" } ] } } ``` --- ## Timeline Estimate **Total Estimated Time**: 56-74 hours | Phase | Tasks | Estimated Time | |-------|-------|----------------| | 1. Scaffolding | Project setup | 4-6 hours | | 2. WebDAV Client | HTTP/WebDAV implementation | 12-16 hours | | 3. Authentication | Auth system | 6-8 hours | | 4. Upload Manager | File uploads | 10-12 hours | | 5. Folder Management | Folder operations | 8-10 hours | | 6. Favorites/Recent | Config persistence | 6-8 hours | | 7. Testing/Docs | Tests and docs | 10-12 hours | **Realistic Timeline**: 2-3 weeks working part-time (15-20 hrs/week) --- ## Success Criteria The library is complete when: - ✅ All phases implemented and tested - ✅ Code coverage >80% - ✅ Integration tests pass with real Nextcloud - ✅ API documentation complete - ✅ Examples compile and run - ✅ Can be integrated into 3DS app - ✅ Ready for additional platforms (Switch, Wii U, etc.) --- ## Next Steps 1. **Review this plan** - Adjust scope, estimates, priorities 2. **Create Gitea issues** - One for scaffolding, update existing issues 3. **Start Phase 1** - Set up project structure 4. **Implement phases sequentially** - Each phase depends on previous 5. **Test continuously** - Don't defer testing to the end --- **Ready to proceed?** Let's create the issues and start building!