atlet99/dtorrent_tracker_v2
[FEATURE] - Support binary tracker ID format;
Aperta
#15 aperta il 3 nov 2025
enhancementhelp wanted
Metriche repository
- Star
- (0 stelle)
- Metriche merge PR
- (Nessuna PR mergiata in 30 g)
Descrizione
Description
The HTTP tracker stores tracker id as a string, but according to BEP 0003, it can also be binary data. The current implementation may not handle binary tracker IDs correctly.
Location
File: lib/src/tracker/http_tracker.dart
Lines: 114-115, 89
Current Code
String? _trackerId; // ❌ Only stores as string
// In processResponseData:
if (result['tracker id'] != null) {
_trackerId = result['tracker id']; // Assumes string
}
// In generateQueryParameters:
if (currentTrackerId != null) params['trackerid'] = currentTrackerId!; // String
Problem:
tracker idin BEP 0003 can be either a string or binary data- Current code assumes it's always a string
- Binary tracker IDs may not be handled correctly
Expected Behavior
According to BEP 0003, tracker id can be:
- A string (UTF-8 encoded)
- Binary data (byte array)
The library should:
- Store tracker ID in a format that supports both (e.g.,
Uint8List?) - Convert to string only when needed for query parameters
- Handle both string and binary formats from responses
Proposed Implementation
class HttpTracker extends Tracker with HttpTrackerBase {
Uint8List? _trackerId; // ✅ Store as binary, convert when needed
// Getter that converts to string for query parameters
String? get currentTrackerId {
if (_trackerId == null) return null;
// Try to decode as UTF-8 string
try {
return utf8.decode(_trackerId!);
} catch (e) {
// If not valid UTF-8, encode as URL-safe base64 or hex
return base64.encode(_trackerId!);
}
}
// Store raw tracker ID (supports both string and binary)
Uint8List? get rawTrackerId => _trackerId;
@override
PeerEvent processResponseData(Uint8List data) {
var result = decode(data) as Map;
// Handle tracker ID (can be string or binary)
if (result['tracker id'] != null) {
var trackerIdValue = result['tracker id'];
if (trackerIdValue is Uint8List) {
// Binary format - store as-is
_trackerId = trackerIdValue;
} else if (trackerIdValue is String) {
// String format - encode to bytes
_trackerId = utf8.encode(trackerIdValue);
} else {
// Try to convert other types
_log.warning('Unexpected tracker id type: ${trackerIdValue.runtimeType}');
}
}
// ... rest of processing ...
}
@override
Map<String, String> generateQueryParameters(Map<String, dynamic> options) {
// ... existing code ...
if (_trackerId != null) {
var trackerIdStr = currentTrackerId;
if (trackerIdStr != null) {
// URL encode the tracker ID string
params['trackerid'] = Uri.encodeQueryComponent(trackerIdStr);
}
}
return params;
}
}
Alternative: Support Both Formats Explicitly
class HttpTracker extends Tracker with HttpTrackerBase {
Uint8List? _trackerIdBinary;
String? _trackerIdString;
String? get currentTrackerId {
return _trackerIdString ??
(_trackerIdBinary != null ? utf8.decode(_trackerIdBinary!) : null);
}
@override
PeerEvent processResponseData(Uint8List data) {
var result = decode(data) as Map;
if (result['tracker id'] != null) {
var trackerIdValue = result['tracker id'];
if (trackerIdValue is Uint8List) {
_trackerIdBinary = trackerIdValue;
try {
_trackerIdString = utf8.decode(trackerIdValue);
} catch (e) {
_trackerIdString = null; // Binary data, not UTF-8
}
} else if (trackerIdValue is String) {
_trackerIdString = trackerIdValue;
_trackerIdBinary = utf8.encode(trackerIdValue);
}
}
// ... rest of processing ...
}
}
Impact
- Severity: Low (Compatibility Improvement)
- Affected: HTTP tracker responses with binary tracker IDs
- Benefits:
- Full BEP 0003 compliance
- Support for trackers that send binary tracker IDs
- Better compatibility with various tracker implementations
Additional Context
Binary tracker IDs are:
- Allowed by BEP 0003 specification
- Used by some tracker implementations
- Should be handled gracefully
- Rare but important for full compliance