@@ -89,24 +89,59 @@ - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)ur
89
89
return ;
90
90
}
91
91
92
+ NSInteger statusCode = 200 ; // Default to 200 OK status
92
93
NSString *mimeType = [self getMimeType: fileURL] ?: @" application/octet-stream" ;
93
94
NSNumber *fileLength;
94
95
[fileURL getResourceValue: &fileLength forKey: NSURLFileSizeKey error: nil ];
95
96
96
97
NSNumber *responseSize = fileLength;
98
+ NSUInteger responseSent = 0 ;
99
+
100
+ NSMutableDictionary *headers = [NSMutableDictionary dictionaryWithCapacity: 5 ];
101
+ headers[@" Content-Type" ] = mimeType;
102
+ headers[@" Cache-Control" ] = @" no-cache" ;
103
+ headers[@" Content-Length" ] = [responseSize stringValue ];
104
+
105
+ // Check for Range header
106
+ NSString *rangeHeader = [urlSchemeTask.request valueForHTTPHeaderField: @" Range" ];
107
+ if (rangeHeader) {
108
+ NSRange range = NSMakeRange (NSNotFound , 0 );
109
+
110
+ if ([rangeHeader hasPrefix: @" bytes=" ]) {
111
+ NSString *byteRange = [rangeHeader substringFromIndex: 6 ];
112
+ NSArray <NSString *> *rangeParts = [byteRange componentsSeparatedByString: @" -" ];
113
+ NSUInteger start = (NSUInteger )[rangeParts[0 ] integerValue ];
114
+ NSUInteger end = rangeParts.count > 1 && ![rangeParts[1 ] isEqualToString: @" " ] ? (NSUInteger )[rangeParts[1 ] integerValue ] : [fileLength unsignedIntegerValue ] - 1 ;
115
+ range = NSMakeRange (start, end - start + 1 );
116
+ }
117
+
118
+ if (range.location != NSNotFound ) {
119
+ // Ensure range is valid
120
+ if (range.location >= [fileLength unsignedIntegerValue ] && [self taskActive: urlSchemeTask]) {
121
+ headers[@" Content-Range" ] = [NSString stringWithFormat: @" bytes */%@ " , fileLength];
122
+ NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc ] initWithURL: req.URL statusCode: 416 HTTPVersion: @" HTTP/1.1" headerFields: headers];
123
+ [urlSchemeTask didReceiveResponse: response];
124
+ [urlSchemeTask didFinish ];
125
+
126
+ @synchronized (self.handlerMap ) {
127
+ [self .handlerMap removeObjectForKey: urlSchemeTask];
128
+ }
129
+ return ;
130
+ }
97
131
98
- NSDictionary *headers = @{
99
- @" Content-Length" : [responseSize stringValue ],
100
- @" Content-Type" : mimeType,
101
- @" Cache-Control" : @" no-cache"
102
- };
132
+ [fileHandle seekToFileOffset: range.location];
133
+ responseSize = [NSNumber numberWithUnsignedInteger: range.length];
134
+ statusCode = 206 ; // Partial Content
135
+ headers[@" Content-Range" ] = [NSString stringWithFormat: @" bytes %lu -%lu /%@ " , (unsigned long )range.location, (unsigned long )(range.location + range.length - 1 ), fileLength];
136
+ headers[@" Content-Length" ] = [NSString stringWithFormat: @" %lu " , (unsigned long )range.length];
137
+ }
138
+ }
103
139
104
- NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc ] initWithURL: req.URL statusCode: 200 HTTPVersion: @" HTTP/1.1" headerFields: headers];
140
+ NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc ] initWithURL: req.URL statusCode: statusCode HTTPVersion: @" HTTP/1.1" headerFields: headers];
105
141
if ([self taskActive: urlSchemeTask]) {
106
142
[urlSchemeTask didReceiveResponse: response];
107
143
}
108
144
109
- NSUInteger responseSent = 0 ;
110
145
while ([self taskActive: urlSchemeTask] && responseSent < [responseSize unsignedIntegerValue ]) {
111
146
@autoreleasepool {
112
147
NSData *data = [self readFromFileHandle: fileHandle upTo: FILE_BUFFER_SIZE error: &error];
0 commit comments