forked from Ninjalama/streamyfin_mirror
fix: improved server check
Included timeout, check url even if http is included, doc strings
This commit is contained in:
117
app/login.tsx
117
app/login.tsx
@@ -80,40 +80,92 @@ const Login: React.FC = () => {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
async function checkUrl(url: string) {
|
||||
// remove trailing / so we don't double add double / in my checker
|
||||
if (url.endsWith("/")) {
|
||||
url = url.slice(0, -1);
|
||||
}
|
||||
|
||||
if( await fetch("https://" + url + "/System/Info/Public", {mode: 'cors'}).then((response) => {
|
||||
return response.status;
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
}) === 200) {
|
||||
return "https://"+url
|
||||
} else if (await fetch("http://" + url + "/System/Info/Public", {mode: 'cors'}).then((response) => {
|
||||
return response.status;
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
}) === 200) {
|
||||
return "http://"+url
|
||||
const [loadingServerCheck, setLoadingServerCheck] = useState<boolean>(false);
|
||||
|
||||
/**
|
||||
* Checks the availability and validity of a Jellyfin server URL.
|
||||
*
|
||||
* This function attempts to connect to a Jellyfin server using the provided URL.
|
||||
* It tries both HTTPS and HTTP protocols, with a timeout to handle long 404 responses.
|
||||
*
|
||||
* @param {string} url - The base URL of the Jellyfin server to check.
|
||||
* @returns {Promise<string | undefined>} A Promise that resolves to:
|
||||
* - The full URL (including protocol) if a valid Jellyfin server is found.
|
||||
* - undefined if no valid server is found at the given URL.
|
||||
*
|
||||
* Side effects:
|
||||
* - Sets loadingServerCheck state to true at the beginning and false at the end.
|
||||
* - Logs errors and timeout information to the console.
|
||||
*/
|
||||
async function checkUrl(url: string) {
|
||||
url = url.endsWith("/") ? url.slice(0, -1) : url;
|
||||
setLoadingServerCheck(true);
|
||||
|
||||
const protocols = ["https://", "http://"];
|
||||
const timeout = 2000; // 2 seconds timeout for long 404 responses
|
||||
|
||||
try {
|
||||
for (const protocol of protocols) {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
||||
|
||||
try {
|
||||
const response = await fetch(`${protocol}${url}/System/Info/Public`, {
|
||||
mode: "cors",
|
||||
signal: controller.signal,
|
||||
});
|
||||
clearTimeout(timeoutId);
|
||||
if (response.ok) {
|
||||
return `${protocol}${url}`;
|
||||
}
|
||||
} catch (e) {
|
||||
const error = e as Error;
|
||||
if (error.name === "AbortError") {
|
||||
console.log(`Request to ${protocol}${url} timed out`);
|
||||
} else {
|
||||
console.error(`Error checking ${protocol}${url}:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
} finally {
|
||||
setLoadingServerCheck(false);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the connection attempt to a Jellyfin server.
|
||||
*
|
||||
* This function trims the input URL, checks its validity using the `checkUrl` function,
|
||||
* and sets the server address if a valid connection is established.
|
||||
*
|
||||
* @param {string} url - The URL of the Jellyfin server to connect to.
|
||||
*
|
||||
* @returns {Promise<void>}
|
||||
*
|
||||
* Side effects:
|
||||
* - Calls `checkUrl` to validate the server URL.
|
||||
* - Shows an alert if the connection fails.
|
||||
* - Sets the server address using `setServer` if the connection is successful.
|
||||
*
|
||||
*/
|
||||
const handleConnect = async (url: string) => {
|
||||
url = url.trim();
|
||||
if (!url.startsWith("http")) {
|
||||
const result = await checkUrl(url);
|
||||
if (result === undefined){
|
||||
Alert.alert("Invalid URL", "Please enter a valid URL");
|
||||
return;
|
||||
}
|
||||
url = result;
|
||||
|
||||
const result = await checkUrl(
|
||||
url.startsWith("http") ? new URL(url).host : url
|
||||
);
|
||||
|
||||
if (result === undefined) {
|
||||
Alert.alert(
|
||||
"Connection failed",
|
||||
"Could not connect to the server. Please check the URL and your network connection."
|
||||
);
|
||||
return;
|
||||
}
|
||||
console.log(url);
|
||||
setServer({ address: url });
|
||||
|
||||
setServer({ address: result });
|
||||
};
|
||||
|
||||
const handleQuickConnect = async () => {
|
||||
@@ -150,7 +202,6 @@ const Login: React.FC = () => {
|
||||
color="black"
|
||||
onPress={() => {
|
||||
removeServer();
|
||||
setServerURL("");
|
||||
}}
|
||||
justify="between"
|
||||
iconLeft={
|
||||
@@ -248,7 +299,12 @@ const Login: React.FC = () => {
|
||||
maxLength={500}
|
||||
/>
|
||||
</View>
|
||||
<Button onPress={ async () => await handleConnect(serverURL)} className="mb-2">
|
||||
<Button
|
||||
loading={loadingServerCheck}
|
||||
disabled={loadingServerCheck}
|
||||
onPress={async () => await handleConnect(serverURL)}
|
||||
className="mb-2"
|
||||
>
|
||||
Connect
|
||||
</Button>
|
||||
</View>
|
||||
@@ -258,4 +314,3 @@ const Login: React.FC = () => {
|
||||
};
|
||||
|
||||
export default Login;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user