I set up a minimal Unity project with only one empty GameObject and the following script attached:
using System.Net;
using UnityEngine;
using UnityEngine.Networking;
public class WebRequest : MonoBehaviour
{
// Start is called before the first frame update
public string serverUrl; // some.local.network.ip:port
void Start()
{
Debug.Log("Sending request to" + serverUrl);
UnityWebRequest getRequest = new UnityWebRequest(serverUrl, UnityWebRequest.kHttpVerbGET);
getRequest.chunkedTransfer = false;
getRequest.SendWebRequest();
}
}
I tested the code above with a local NodeJS server and successfully received requests when running a) the code in the (local) Editor and b) a built exported to an Android device and c) a build app in the HoloLens (1) emulator and d) running the app locally (APPX export as well as directly from Visual Studio). When exporting the same code to a UWP application (with Windows Mixed Reality enabled for HoloLens), the request is not received a) on a HoloLens device as well as b) a remote PC using an APPX export. On both systems – HoloLens and remote PC – Firefox and/or Edge were able to reach the server. I enabled EnterpriseAuthentication, InternetClient, InternetClientServer, PrivateNetworkClientServer (and WebCam, Microphone and SpatialPerception for HoloLens). I however receive some proxy errors:
Curl error 7: Failed to connect to proxy.<url>.net port 1080: Connection refused```
I assume that the institute network is some influential factor here. However, the Android request worked anyway and also replacing the `UnityWebRequest` with:
```csharp
System.Net.WebRequest request = System.Net.WebRequest.Create(serverUrl);
request.Credentials = CredentialCache.DefaultCredentials;
WebResponse response = request.GetResponse();
allows the UWP application to reach the remote NodeJS server. I found related issues here and here but unfortunately neither updating Unity nor using trailing backslashes or chunkedTransfer solved it for me.
I could however work around the issue by disabling “Automatically detect settings” in the Proxy section of Windows’ Settings.
Tested Unity Version: 2019.2.11f1 and 2019.2.10f1
HoloLens Version: 17763.806.x86fre.rs5_release_svc_prod1.191005-1655
Windows Version: Windows 10 1909
Any suggestion about how to get UnityWebRequest working for UWP applications in a network with an HTTP proxy without the need of tinkering with the OS would be much appreciated.
On UWP under the hood UnityWebRequest uses this class to get proxy configuration:
On Android it works, because proxies are not supported there, hence direct connection.
It might be a bug that we don’t check whether we can connect directly (ProxyConfiguration has such property).
This documentation has more details about proxies and might explain why .NET APIs work:
Also worth to check proxy settings on device itself.
Ultimately the problem is with UWP itself and the limitations imposed on the APIs.
The NetworkInformation.GetPRoxyConfigurationAsync() API doesn’t return all of the Proxy configuration data, compared to the Win32 API WinHttpGetIEProxyConfigForCurrentUser(). Instead, the WinRT APIs will automatically “plumb the connection” for you via StreamSocket, or in your case .NET WebRequest.
Unity uses libCurl internally for HTTP instead of native APIs for better cross-platform support, but this requires us to collect proxy information from Windows and manually configure libCurl accordingly. Since Windows proxy configuration is complex, this is difficult to do even on WindowsStandalone, but it’s impossible to properly support on UWP because of the restrictions imposed on the platform.
So, unfortunately to use UnityWebRequest you’ll have to manually configure HoloLens proxy settings so it’ll work, or replace it with System.Net.WebRequest.
This is not a very satisfying response, I have to say. Is there a way I can do it from the code? Or do I have to instruct my users on how to configure proxy settings? I’m also somewhat unfamiliar on this topic, how exactly do you configure such settings?
Should we even use UnityWebRequests these days? It feels like System.Net.WebRequest is the way to go now. What’s the point of an http API in Unity if it doesn’t work everywhere. It’s really frustrating.
I can’t get it working. How do you configure proxy settings manually from code? It’s really driving me crazy. It works when I run it from visual studio, both in master and debug mode, but it doesn’t when I download it from the Microsoft Store. It’s nonsense and impossible to debug, and each iteration takes hours.
Hey, we’re looking at this. It seems specifically this breaks if you configure a proxy that has a “bypass” list. This bypass list is usually configured if your proxy doesn’t support making web requests to particular web address. Most often this happens when trying to make web requests to your local area network IP address. This has generally been a rare case, so this wasn’t the highest priority thing to address. Web requests that go through the proxy work just fine.
Can you explain what you’re trying to do and what exactly doesn’t work?
Assuming it is something close to what you’re saying, shouldn’t it be a network error? I’m working with a log in form at the beginning of my app. Not only in the editor, but also when I hit play on visual studio (both in Debug or Master mode), if I disconnect the Wi-Fi, my app will show a dialog box that says “Cannot resolve destination host. ConnectionError,” because I set a callback to do so after a network error happens. This is my code:
private IEnumerator POST_Login(POST_LoginReqBody body, Action<UnityWebRequest, DownloadHandler> res, Action<string, UnityWebRequest> err)
{
using (var request = new UnityWebRequest(API_ACCOUNT_LOGIN, "POST"))
{
// Prepare body of the request
string bodyJSON = JsonUtility.ToJson(body);
byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(bodyJSON);
// Attach body and define request handler
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
// Set request header
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("Authorization", "<JSONWebToken_goes_here... not on this one in particular, maybe. But here...>");
// Send request
yield return request.SendWebRequest();
// Handle basic errors...
if (request.isNetworkError)
{
Debug.LogError("Network error. (POST_Login)");
Debug.LogError(request.error);
err(request.error, request);
yield break;
}
if (request.isHttpError)
{
Debug.LogError("Http Error. (POST_Login)");
Debug.LogError(request.error);
err(request.error, request);
yield break;
}
// Handle a successful request
Debug.Log("Requset Success");
res(request, request.downloadHandler);
}
}
Therefore, it seems that the UnityWebRequest API is not working at all. The request, I presume, never happens. That’s why I don’t get a request error.
If what you tell me is true, shouldn’t the app also not work when I hit play on Visual Studio in Debug/Master mode? It works just fine when I do it from there. In some way, I wish it didn’t, because then I would be able to debug it closely. As I said, it’s only when I download it from the Microsoft Store that I get something that doesn’t work, which is very frustrating because every iteration takes several hours, if not a day or so.
… the callback does not seem to be called at all. (Because I can’t see the dialog box that I talked you about.) This is very strange behavior. In the editor, if I disconnect the WiFi, I will see such dialog box (called in the callback) saying there was a connection error, as intended. But the same doesn’t happen in the UWP build (not even after I disconnect the WiFi). I am wondering there could be an issue with Coroutines in UWP that affects UnityWebRequest too, or similar.
But if it is indeed a network error, well, I opened this thread of its own here https://discussions.unity.com/t/803005 . Perhaps we should keep the conversation going in that thread.
It sounds you’re running into a totally different issue from what is being discussed in this thread. To be absolutely clear, the issue here reproduces ONLY if you change windows internet settings to go through a proxy, and add a specific URL or IP address into the bypass list.