19 KiB
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:
NextcloudErrorenumUploadProgressstructFileInfostructFolderInfostruct
- 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.hppinterface - 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
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<uint8_t>& data);
Response delete_(const std::string& path);
// WebDAV operations
std::vector<FileInfo> 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.hppinterface - 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
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.hppinterface - 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
class UploadManager {
public:
using ProgressCallback = std::function<void(const UploadProgress&)>;
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.hppinterface - 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
class FolderManager {
public:
FolderManager(WebDAVClient& client, AuthManager& auth);
// Folder operations
std::vector<FileInfo> 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<std::string> 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.hppinterface - 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
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<FolderInfo> getFavorites() const;
// Recent folders
void addRecentFolder(const std::string& path);
std::vector<std::string> 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_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
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
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
{
"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
- Review this plan - Adjust scope, estimates, priorities
- Create Gitea issues - One for scaffolding, update existing issues
- Start Phase 1 - Set up project structure
- Implement phases sequentially - Each phase depends on previous
- Test continuously - Don't defer testing to the end
Ready to proceed? Let's create the issues and start building!