@@ -89,24 +89,59 @@ - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)ur
8989 return ;
9090 }
9191
92+ NSInteger statusCode = 200 ; // Default to 200 OK status
9293 NSString *mimeType = [self getMimeType: fileURL] ?: @" application/octet-stream" ;
9394 NSNumber *fileLength;
9495 [fileURL getResourceValue: &fileLength forKey: NSURLFileSizeKey error: nil ];
9596
9697 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+ }
97131
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+ }
103139
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];
105141 if ([self taskActive: urlSchemeTask]) {
106142 [urlSchemeTask didReceiveResponse: response];
107143 }
108144
109- NSUInteger responseSent = 0 ;
110145 while ([self taskActive: urlSchemeTask] && responseSent < [responseSize unsignedIntegerValue ]) {
111146 @autoreleasepool {
112147 NSData *data = [self readFromFileHandle: fileHandle upTo: FILE_BUFFER_SIZE error: &error];
0 commit comments