Skip to content

Commit

Permalink
Fix range detection, backport to old core
Browse files Browse the repository at this point in the history
  • Loading branch information
whscullin committed Jan 20, 2025
1 parent 5aaac71 commit a7ce79e
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 88 deletions.
24 changes: 9 additions & 15 deletions js/components/util/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export const loadHttpBlockFile = async (
header.headers.get('content-length') || '0',
10
);
const hasByteRange = header.headers.get('accept-ranges') === 'byte';
const hasByteRange = header.headers.get('accept-ranges') === 'bytes';
if (hasByteRange) {
await smartPort.setBlockDisk(
driveNo,
Expand Down Expand Up @@ -255,10 +255,7 @@ export const loadHttpUnknownFile = async (
signal?: AbortSignal,
onProgress?: ProgressCallback
) => {
// const data = await loadHttpFile(url, signal, onProgress);
// const { name, ext } = getNameAndExtension(url);
await smartStorageBroker.setUrl(driveNo, url, signal, onProgress);
// await smartStorageBroker.setBinary(driveNo, name, ext, data);
};

export class SmartStorageBroker implements MassStorage<unknown> {
Expand All @@ -274,21 +271,18 @@ export class SmartStorageBroker implements MassStorage<unknown> {
onProgress?: ProgressCallback
) {
const { name, ext } = getNameAndExtension(url);
if (includes(DISK_FORMATS, ext)) {
const head = await fetch(url, { method: 'HEAD' });
if (includes(BLOCK_FORMATS, ext)) {
const head = await fetch(url, { method: 'HEAD', mode: 'cors' });
const contentLength = parseInt(
head.headers.get('content-length') || '0',
10
);
if (contentLength >= 800 * 1024) {
if (includes(BLOCK_FORMATS, ext)) {
await this.smartPort.setBlockDisk(
driveNo,
new HttpBlockDisk(name, contentLength, url)
);
} else {
throw new Error(`Unable to load "${name}"`);
}
const hasByteRange = head.headers.get('accept-ranges') === 'bytes';
if (contentLength >= 800 * 1024 && hasByteRange) {
await this.smartPort.setBlockDisk(
driveNo,
new HttpBlockDisk(name, contentLength, url)
);
initGamepad();
return;
}
Expand Down
200 changes: 127 additions & 73 deletions js/ui/apple2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
JSONDisk,
BlockFormat,
FLOPPY_FORMATS,
isBlockStorage,
} from '../formats/types';
import { initGamepad } from './gamepad';
import KeyBoard from './keyboard';
Expand All @@ -37,6 +38,7 @@ import { Screen, SCREEN_FULL_PAGE } from './screen';
import { JoyStick } from './joystick';
import { System } from './system';
import { Options } from '../options';
import { HttpBlockDisk } from 'js/components/util/http_block_disk';

let paused = false;

Expand Down Expand Up @@ -447,85 +449,137 @@ export function doLoadHTTP(driveNo: DriveNumber, url?: string) {
const input = document.querySelector<HTMLInputElement>('#http_url')!;
url = url || input.value;
if (url) {
fetch(url)
.then(function (response) {
if (response.ok) {
const reader = response.body!.getReader();
let received = 0;
const chunks: Uint8Array[] = [];
const contentLength = parseInt(
response.headers.get('content-length')!,
10
);

return reader
.read()
.then(
function readChunk(
result
): Promise<ArrayBufferLike> {
if (result.done) {
const data = new Uint8Array(received);
let offset = 0;
for (
let idx = 0;
idx < chunks.length;
idx++
) {
data.set(chunks[idx], offset);
offset += chunks[idx].length;
const urlParts = url.split('/');
const file = urlParts.pop()!;
const fileParts = file.split('.');
const ext = fileParts.pop()!.toLowerCase();
const name = decodeURIComponent(fileParts.join('.'));
fetch(url, { method: 'HEAD' })
.then((head) => {
const contentLength = parseInt(
head.headers.get('content-length') || '0',
10
);
const hasByteRange =
head.headers.get('accept-ranges') === 'bytes';
if (
hasByteRange &&
includes(BLOCK_FORMATS, ext) &&
contentLength >= 800 * 1024 &&
isBlockStorage(_massStorage)
) {
_massStorage
.setBlockDisk(
driveNo,
new HttpBlockDisk(name, contentLength, url)
)
.catch((error: Error) => {
openAlert(error.message);
console.error(error);
});
loadingStop();
} else {
fetch(url)
.then(function (response) {
if (response.ok) {
const reader = response.body!.getReader();
let received = 0;
const chunks: Uint8Array[] = [];
const contentLength = parseInt(
response.headers.get('content-length')!,
10
);

return reader
.read()
.then(
function readChunk(
result
): Promise<ArrayBufferLike> {
if (result.done) {
const data = new Uint8Array(
received
);
let offset = 0;
for (
let idx = 0;
idx < chunks.length;
idx++
) {
data.set(
chunks[idx],
offset
);
offset +=
chunks[idx].length;
}
return Promise.resolve(
data.buffer
);
}

received += result.value.length;
if (contentLength) {
loadingProgress(
received,
contentLength
);
}
chunks.push(result.value);

return reader
.read()
.then(readChunk);
}
);
} else {
throw new Error(
'Error loading: ' + response.statusText
);
}
})
.then(function (data) {
if (includes(DISK_FORMATS, ext)) {
if (data.byteLength >= 800 * 1024) {
if (includes(BLOCK_FORMATS, ext)) {
_massStorage
.setBinary(driveNo, name, ext, data)
.then(() => initGamepad())
.catch((error) => {
console.error(error);
openAlert(
`Unable to load ${name}`
);
});
}
} else {
if (includes(FLOPPY_FORMATS, ext)) {
_disk2
.setBinary(driveNo, name, ext, data)
.then(() => initGamepad())
.catch((error) => {
console.error(error);
openAlert(
`Unable to load ${name}`
);
});
}
return Promise.resolve(data.buffer);
}

received += result.value.length;
if (contentLength) {
loadingProgress(received, contentLength);
}
chunks.push(result.value);

return reader.read().then(readChunk);
} else {
throw new Error(
`Extension ${ext} not recognized.`
);
}
);
} else {
throw new Error('Error loading: ' + response.statusText);
}
})
.then(function (data) {
const urlParts = url.split('/');
const file = urlParts.pop()!;
const fileParts = file.split('.');
const ext = fileParts.pop()!.toLowerCase();
const name = decodeURIComponent(fileParts.join('.'));
if (includes(DISK_FORMATS, ext)) {
if (data.byteLength >= 800 * 1024) {
if (includes(BLOCK_FORMATS, ext)) {
_massStorage
.setBinary(driveNo, name, ext, data)
.then(() => initGamepad())
.catch((error) => {
console.error(error);
openAlert(`Unable to load ${name}`);
});
}
} else {
if (includes(FLOPPY_FORMATS, ext)) {
_disk2
.setBinary(driveNo, name, ext, data)
.then(() => initGamepad())
.catch((error) => {
console.error(error);
openAlert(`Unable to load ${name}`);
});
}
}
} else {
throw new Error(`Extension ${ext} not recognized.`);
loadingStop();
})
.catch((error: Error) => {
loadingStop();
openAlert(error.message);
console.error(error);
});
}
loadingStop();
})
.catch((error: Error) => {
loadingStop();
openAlert(error.message);
console.error(error);
});
Expand Down

0 comments on commit a7ce79e

Please sign in to comment.