Skip to content

Commit 5c42a1f

Browse files
fix(DownloadData): add custom redirect handler
WEBSAVE struggles with the chain 301 -> 308 -> 302 required for some OSF paths.
1 parent fac2ebf commit 5c42a1f

File tree

1 file changed

+71
-8
lines changed

1 file changed

+71
-8
lines changed

src/Common/downloadData.m

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
function dataPath = downloadData(Model,path)
2+
% Downlaod example data for a given qMRLab model
3+
24
if ~exist('path','var') || isempty(path)
35
h = msgbox('Please select a destination to create example folder.','qMRLab');
46
waitfor(h);
@@ -81,19 +83,28 @@
8183
download_success = true;
8284
disp('Data has been downloaded ...');
8385
catch
84-
% websave failed, try final method
86+
% websave failed, try next method
8587
end
8688
end
8789

88-
% Method 4: Try urlwrite (older but sometimes works better)
90+
% Method 4: Try custom redirect handler
8991
if ~download_success
9092
try
91-
urlwrite(url, filename); %#ok<URLWR>
93+
downloadWithRedirects(url, filename);
9294
download_success = true;
95+
catch
96+
% custom redirect handler failed, try final method
97+
end
98+
end
99+
100+
% Method 5: Try urlwrite (older but sometimes works better)
101+
if ~download_success
102+
try
103+
urlwrite(url, filename); %#ok<URLWR>
93104
disp('Data has been downloaded ...');
94105
catch ME_final
95106
% All methods failed
96-
error('AllMethodsFailed', ['Could not download using any method: ' ME_final.message]);
107+
error(['Could not download using any method: ' ME_final.message]);
97108
end
98109
end
99110
end
@@ -118,9 +129,6 @@
118129
end
119130
end
120131

121-
122-
123-
124132
oldname = [path filesep filename(1:end-4)];
125133
if (exist(oldname,'dir')~=0)
126134
newname = [path filesep filename(1:end-4) '_data'];
@@ -140,4 +148,59 @@
140148
end
141149
end
142150

143-
end
151+
end
152+
153+
function downloadWithRedirects(url, outputFile, maxRedirects)
154+
% Download a file following HTTP redirects manually
155+
% WEBSAVE struggles with the chain 301 -> 308 -> 302 required
156+
% for some OSF paths.
157+
158+
if nargin < 3
159+
maxRedirects = 10;
160+
end
161+
162+
currentUrl = url;
163+
redirectCount = 0;
164+
165+
while redirectCount < maxRedirects
166+
request = matlab.net.http.RequestMessage('GET');
167+
uri = matlab.net.URI(currentUrl);
168+
options = matlab.net.http.HTTPOptions('ConnectTimeout', 60);
169+
170+
try
171+
response = send(request, uri, options);
172+
catch ME
173+
error('Failed to connect to %s: %s', currentUrl, ME.message);
174+
end
175+
176+
statusCode = response.StatusCode;
177+
178+
if statusCode == 200
179+
% Success! Write the file
180+
181+
fid = fopen(outputFile, 'wb');
182+
fwrite(fid, response.Body.Data, 'uint8');
183+
fclose(fid);
184+
185+
finfo = dir(outputFile);
186+
fprintf('Download successful: %d bytes\n', finfo.bytes);
187+
return;
188+
189+
elseif statusCode == 301 || statusCode == 302 || statusCode == 307 || statusCode == 308
190+
% Follow redirect
191+
192+
locationHeader = response.Header([response.Header.Name] == "Location");
193+
if isempty(locationHeader)
194+
error('Redirect response without Location header');
195+
end
196+
197+
currentUrl = string(locationHeader.Value);
198+
redirectCount = redirectCount + 1;
199+
fprintf('Redirect: %s -> %s\n', url, currentUrl);
200+
201+
else
202+
error('Unexpected status code: %d', statusCode);
203+
end
204+
end
205+
error('Too many redirects (max %d)', maxRedirects);
206+
end

0 commit comments

Comments
 (0)