mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2025-07-22 20:26:41 +00:00
Merge branch 'master' of github.com:limelight-stream/limelight-ios
# By Cameron Gutman # Via Cameron Gutman * 'master' of github.com:limelight-stream/limelight-ios: Add timeouts to HTTP requests Change StreamView's background to black Display a failure dialog when we fail to launch an app
This commit is contained in:
commit
f0b6602b99
@ -102,63 +102,75 @@ static const NSString* PORT = @"47984";
|
|||||||
[NSURLConnection connectionWithRequest:request delegate:self];
|
[NSURLConnection connectionWithRequest:request delegate:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) createRequestFromString:(NSString*) urlString {
|
- (NSURLRequest*) createRequestFromString:(NSString*) urlString enableTimeout:(BOOL)normalTimeout {
|
||||||
NSString* escapedUrl = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
NSString* escapedUrl = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||||
NSURL* url = [[NSURL alloc] initWithString:escapedUrl];
|
NSURL* url = [[NSURL alloc] initWithString:escapedUrl];
|
||||||
return [NSURLRequest requestWithURL:url];
|
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
|
||||||
|
if (normalTimeout) {
|
||||||
|
// Timeout the request after 5 seconds
|
||||||
|
[request setTimeoutInterval:5];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Timeout the request after 60 seconds
|
||||||
|
[request setTimeoutInterval:60];
|
||||||
|
}
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) newPairRequest:(NSData*)salt {
|
- (NSURLRequest*) newPairRequest:(NSData*)salt {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=getservercert&salt=%@&clientcert=%@",
|
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=getservercert&salt=%@&clientcert=%@",
|
||||||
_baseURL, _uniqueId, _deviceName, [self bytesToHex:salt], [self bytesToHex:_cert]];
|
_baseURL, _uniqueId, _deviceName, [self bytesToHex:salt], [self bytesToHex:_cert]];
|
||||||
return [self createRequestFromString:urlString];
|
// This call blocks while waiting for the user to input the PIN on the PC
|
||||||
|
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) newUnpairRequest {
|
- (NSURLRequest*) newUnpairRequest {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/unpair?uniqueid=%@", _baseURL, _uniqueId];
|
NSString* urlString = [NSString stringWithFormat:@"%@/unpair?uniqueid=%@", _baseURL, _uniqueId];
|
||||||
return [self createRequestFromString:urlString];
|
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) newChallengeRequest:(NSData*)challenge {
|
- (NSURLRequest*) newChallengeRequest:(NSData*)challenge {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientchallenge=%@",
|
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientchallenge=%@",
|
||||||
_baseURL, _uniqueId, _deviceName, [self bytesToHex:challenge]];
|
_baseURL, _uniqueId, _deviceName, [self bytesToHex:challenge]];
|
||||||
return [self createRequestFromString:urlString];
|
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) newChallengeRespRequest:(NSData*)challengeResp {
|
- (NSURLRequest*) newChallengeRespRequest:(NSData*)challengeResp {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&serverchallengeresp=%@",
|
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&serverchallengeresp=%@",
|
||||||
_baseURL, _uniqueId, _deviceName, [self bytesToHex:challengeResp]];
|
_baseURL, _uniqueId, _deviceName, [self bytesToHex:challengeResp]];
|
||||||
return [self createRequestFromString:urlString];
|
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) newClientSecretRespRequest:(NSString*)clientPairSecret {
|
- (NSURLRequest*) newClientSecretRespRequest:(NSString*)clientPairSecret {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientpairingsecret=%@", _baseURL, _uniqueId, _deviceName, clientPairSecret];
|
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientpairingsecret=%@", _baseURL, _uniqueId, _deviceName, clientPairSecret];
|
||||||
return [self createRequestFromString:urlString];
|
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) newPairChallenge {
|
- (NSURLRequest*) newPairChallenge {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=pairchallenge", _baseURL, _uniqueId, _deviceName];
|
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=pairchallenge", _baseURL, _uniqueId, _deviceName];
|
||||||
return [self createRequestFromString:urlString];
|
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest *)newAppListRequest {
|
- (NSURLRequest *)newAppListRequest {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/applist?uniqueid=%@", _baseURL, _uniqueId];
|
NSString* urlString = [NSString stringWithFormat:@"%@/applist?uniqueid=%@", _baseURL, _uniqueId];
|
||||||
return [self createRequestFromString:urlString];
|
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest *)newServerInfoRequest {
|
- (NSURLRequest *)newServerInfoRequest {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/serverinfo?uniqueid=%@", _baseURL, _uniqueId];
|
NSString* urlString = [NSString stringWithFormat:@"%@/serverinfo?uniqueid=%@", _baseURL, _uniqueId];
|
||||||
return [self createRequestFromString:urlString];
|
return [self createRequestFromString:urlString enableTimeout:TRUE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) newLaunchRequest:(NSString*)appId width:(int)width height:(int)height refreshRate:(int)refreshRate rikey:(NSString*)rikey rikeyid:(int)rikeyid {
|
- (NSURLRequest*) newLaunchRequest:(NSString*)appId width:(int)width height:(int)height refreshRate:(int)refreshRate rikey:(NSString*)rikey rikeyid:(int)rikeyid {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/launch?uniqueid=%@&appid=%@&mode=%dx%dx%d&additionalStates=1&sops=1&rikey=%@&rikeyid=%d", _baseURL, _uniqueId, appId, width, height, refreshRate, rikey, rikeyid];
|
NSString* urlString = [NSString stringWithFormat:@"%@/launch?uniqueid=%@&appid=%@&mode=%dx%dx%d&additionalStates=1&sops=1&rikey=%@&rikeyid=%d", _baseURL, _uniqueId, appId, width, height, refreshRate, rikey, rikeyid];
|
||||||
return [self createRequestFromString:urlString];
|
// This blocks while the app is launching
|
||||||
|
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) newResumeRequestWithRiKey:(NSString*)riKey riKeyId:(int)riKeyId {
|
- (NSURLRequest*) newResumeRequestWithRiKey:(NSString*)riKey riKeyId:(int)riKeyId {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/resume?uniqueid=%@&rikey=%@&rikeyid=%d", _baseURL, _uniqueId, riKey, riKeyId];
|
NSString* urlString = [NSString stringWithFormat:@"%@/resume?uniqueid=%@&rikey=%@&rikeyid=%d", _baseURL, _uniqueId, riKey, riKeyId];
|
||||||
return [self createRequestFromString:urlString];
|
// This blocks while the app is resuming
|
||||||
|
return [self createRequestFromString:urlString enableTimeout:FALSE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*) bytesToHex:(NSData*)data {
|
- (NSString*) bytesToHex:(NSData*)data {
|
||||||
|
@ -43,7 +43,9 @@
|
|||||||
[_callback showPIN:PIN];
|
[_callback showPIN:PIN];
|
||||||
|
|
||||||
NSData* pairResp = [_httpManager executeRequestSynchronously:[_httpManager newPairRequest:salt]];
|
NSData* pairResp = [_httpManager executeRequestSynchronously:[_httpManager newPairRequest:salt]];
|
||||||
if ([[HttpManager getStringFromXML:pairResp tag:@"paired"] intValue] != 1) {
|
NSString* pairedString;
|
||||||
|
pairedString = [HttpManager getStringFromXML:pairResp tag:@"paired"];
|
||||||
|
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
//TODO: better message
|
||||||
[_callback pairFailed:@"pairResp failed"];
|
[_callback pairFailed:@"pairResp failed"];
|
||||||
@ -59,7 +61,8 @@
|
|||||||
NSData* encryptedChallenge = [cryptoMan aesEncrypt:randomChallenge withKey:aesKey];
|
NSData* encryptedChallenge = [cryptoMan aesEncrypt:randomChallenge withKey:aesKey];
|
||||||
|
|
||||||
NSData* challengeResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRequest:encryptedChallenge]];
|
NSData* challengeResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRequest:encryptedChallenge]];
|
||||||
if ([[HttpManager getStringFromXML:challengeResp tag:@"paired"] intValue] != 1) {
|
pairedString = [HttpManager getStringFromXML:challengeResp tag:@"paired"];
|
||||||
|
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
//TODO: better message
|
||||||
[_callback pairFailed:@"challengeResp failed"];
|
[_callback pairFailed:@"challengeResp failed"];
|
||||||
@ -77,7 +80,8 @@
|
|||||||
NSData* challengeRespEncrypted = [cryptoMan aesEncrypt:challengeRespHash withKey:aesKey];
|
NSData* challengeRespEncrypted = [cryptoMan aesEncrypt:challengeRespHash withKey:aesKey];
|
||||||
|
|
||||||
NSData* secretResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRespRequest:challengeRespEncrypted]];
|
NSData* secretResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRespRequest:challengeRespEncrypted]];
|
||||||
if ([[HttpManager getStringFromXML:secretResp tag:@"paired"] intValue] != 1) {
|
pairedString = [HttpManager getStringFromXML:secretResp tag:@"paired"];
|
||||||
|
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
//TODO: better message
|
||||||
[_callback pairFailed:@"secretResp failed"];
|
[_callback pairFailed:@"secretResp failed"];
|
||||||
@ -105,7 +109,8 @@
|
|||||||
|
|
||||||
NSData* clientPairingSecret = [self concatData:clientSecret with:[cryptoMan signData:clientSecret withKey:[CryptoManager readKeyFromFile]]];
|
NSData* clientPairingSecret = [self concatData:clientSecret with:[cryptoMan signData:clientSecret withKey:[CryptoManager readKeyFromFile]]];
|
||||||
NSData* clientSecretResp = [_httpManager executeRequestSynchronously:[_httpManager newClientSecretRespRequest:[Utils bytesToHex:clientPairingSecret]]];
|
NSData* clientSecretResp = [_httpManager executeRequestSynchronously:[_httpManager newClientSecretRespRequest:[Utils bytesToHex:clientPairingSecret]]];
|
||||||
if (![[HttpManager getStringFromXML:clientSecretResp tag:@"paired"] isEqual:@"1"]) {
|
pairedString = [HttpManager getStringFromXML:clientSecretResp tag:@"paired"];
|
||||||
|
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
//TODO: better message
|
||||||
[_callback pairFailed:@"clientSecretResp failed"];
|
[_callback pairFailed:@"clientSecretResp failed"];
|
||||||
@ -113,7 +118,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
NSData* clientPairChallenge = [_httpManager executeRequestSynchronously:[_httpManager newPairChallenge]];
|
NSData* clientPairChallenge = [_httpManager executeRequestSynchronously:[_httpManager newPairChallenge]];
|
||||||
if (![[HttpManager getStringFromXML:clientPairChallenge tag:@"paired"] isEqual:@"1"]) {
|
pairedString = [HttpManager getStringFromXML:clientPairChallenge tag:@"paired"];
|
||||||
|
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
|
||||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||||
//TODO: better message
|
//TODO: better message
|
||||||
[_callback pairFailed:@"clientPairChallenge failed"];
|
[_callback pairFailed:@"clientPairChallenge failed"];
|
||||||
|
@ -41,12 +41,23 @@
|
|||||||
cert:cert];
|
cert:cert];
|
||||||
|
|
||||||
NSData* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
NSData* serverInfoResp = [hMan executeRequestSynchronously:[hMan newServerInfoRequest]];
|
||||||
if (![[HttpManager getStringFromXML:serverInfoResp tag:@"currentgame"] isEqualToString:@"0"]) {
|
NSString* currentGame = [HttpManager getStringFromXML:serverInfoResp tag:@"currentgame"];
|
||||||
|
if (currentGame == NULL) {
|
||||||
|
[_callbacks launchFailed];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if ([currentGame isEqualToString:@"0"]) {
|
||||||
// App already running, resume it
|
// App already running, resume it
|
||||||
[self resumeApp:hMan];
|
if (![self resumeApp:hMan]) {
|
||||||
|
[_callbacks launchFailed];
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Start app
|
// Start app
|
||||||
[self launchApp:hMan];
|
if (![self launchApp:hMan]) {
|
||||||
|
[_callbacks launchFailed];
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoDecoderRenderer* renderer = [[VideoDecoderRenderer alloc]initWithView:_renderView];
|
VideoDecoderRenderer* renderer = [[VideoDecoderRenderer alloc]initWithView:_renderView];
|
||||||
|
@ -81,7 +81,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void) launchFailed {
|
- (void) launchFailed {
|
||||||
|
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Connection Failed"
|
||||||
|
message:@"Failed to start app"
|
||||||
|
preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action){
|
||||||
|
[self performSegueWithIdentifier:@"returnToMainFrame" sender:self];
|
||||||
|
}]];
|
||||||
|
[self presentViewController:alert animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) displayMessage:(char*)message {
|
- (void) displayMessage:(char*)message {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" initialViewController="wb7-af-jn8">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" initialViewController="wb7-af-jn8">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@ -109,7 +109,7 @@
|
|||||||
<view key="view" contentMode="scaleToFill" id="VPm-Ae-rc4" userLabel="RenderView" customClass="StreamView">
|
<view key="view" contentMode="scaleToFill" id="VPm-Ae-rc4" userLabel="RenderView" customClass="StreamView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
</view>
|
</view>
|
||||||
<nil key="simulatedStatusBarMetrics"/>
|
<nil key="simulatedStatusBarMetrics"/>
|
||||||
<nil key="simulatedTopBarMetrics"/>
|
<nil key="simulatedTopBarMetrics"/>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A388a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="dgh-JZ-Q7z">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="dgh-JZ-Q7z">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6244"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@ -103,7 +103,7 @@
|
|||||||
<view key="view" contentMode="scaleToFill" id="eir-e9-IPE" customClass="StreamView">
|
<view key="view" contentMode="scaleToFill" id="eir-e9-IPE" customClass="StreamView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
</view>
|
</view>
|
||||||
<nil key="simulatedStatusBarMetrics"/>
|
<nil key="simulatedStatusBarMetrics"/>
|
||||||
<nil key="simulatedTopBarMetrics"/>
|
<nil key="simulatedTopBarMetrics"/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user