curl error 6: could not resolve host - This is working for editor but not when building to Quest 2

I am trying to make a http post request using UnityWebRequest the script works fine in the Unity editor I give the server parameters and it displays on my data table. Then when I go to build it and run it on the quest 2 I don’t get anything. I used the debug console while running the game on the Quest and when I go to make the request all I get through debug logs is - curl error 6: could not resolve destination host

This project is for a Sr.Design project at LSU I would really appreciate any guidance or solutions.

Please let me know if any additional information is needed to answer this frustrating problem.

Thanks.

http or https?

unsecure http may get blocked, don‘t use that

check if the quest can generally connect to the internet, and reach the destination server (look for solutions on stackoverflow)

could not resolve generally refers to DNS resolution, eg turning a domain name into an ip address
since the quest is on wifi whereas your pc is more likely on LAN, the router may apply different rules and filters, so be sure to check router settings, specifically don‘t use the guest wifi since that is typically very restricted

It is https.
The Quest 2 can connect to WiFi and go on the internet. We even tried it on my team members Quest he built it and we are getting the same error. But it works fine in the Unity editor.

I am also on my homes WiFi my pc is LAN and when I am using the Quest it is WiFi. So I will look into the DNS resolution.

This is the code for connecting and sending the request along with the error at the bottom. Keep in mind that this works in Unity Editor just not on the Quest 2 stand alone build.

using UnityEngine;
using UnityEngine.Networking;
using System.Text;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using System.Data;

public class PredictionRequest : MonoBehaviour
{
    public GlobalValveVariable_UI gvv_UI;
    public GlobalValveVariable_Button gvv_button;
    string sv_config_str_button;
  
    public List<GameObject> dataRows = new List<GameObject>(); // Change to List
    public List<PredictionResponse> predictionResponses = new List<PredictionResponse>(); // List to store prediction responses
    public GameObject dataRowPrefab; // Prefab for data row
    public Transform dataRowsParent; // Parent transform for data rows

    public PredictionResponse globalResponse;

    [Serializable]
    public class PredictionData
    {
        public string sv_config_str;
        public int flow_sp;
    }
    [Serializable]
    public class PredictionResponse
    {
        public string loop;
        public float c_valve_percent_open;
        public float dpt_01;
        public float dpt_02;
        public float dpt_03;
        public float dpt_04;
        public float dpt_05;
        public float dpt_06;
        public float dpt_07;
        public float dpt_08;
        public float dpt_09;
        public float dpt_10;
        public float dpt_11;
        public float flow_rate;
        public float gpt_01;
        public float gpt_02;
        public float gpt_03;
        public float mean_error;
    }

    public void UiRequest(){
        string result = new string(gvv_UI.flow_sp_UI.Where(char.IsDigit).ToArray());
        int flowSpIntUI = int.Parse(result);
        string svConfigStringUI = gvv_UI.sv_config_str_UI;
        Debug.Log("SV Config string from PythonAnywhere script UI " + gvv_UI.sv_config_str_UI);
        Debug.Log("Flow Rate string from PythonAnywhere script UI " + flowSpIntUI);
        OnRequest(svConfigStringUI, flowSpIntUI);
    }

    public void ButtonRequest(){
        Debug.Log("Prediction request for buttonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn");
        int flowSpIntbutton = int.Parse(gvv_button.valveVariables_Buttons["Flow Set Point:"]);
        Debug.Log("Concatenated flow_sp_button " + flowSpIntbutton);
        foreach (var pair in gvv_button.valveVariables_Buttons)
        {          
            if (pair.Key != "Flow Set Point:"){
            sv_config_str_button += pair.Value;
            }
        }
        Debug.Log("SV Config string from PythonAnywhere script button " + sv_config_str_button);
        OnRequest(sv_config_str_button, flowSpIntbutton);
        sv_config_str_button = "";
    }
    public void OnRequest(string svConfigString, int flowSp)
    {
        StartCoroutine(SendPredictionRequest(svConfigString, flowSp));
    }
    IEnumerator SendPredictionRequest(string svConfigStr, int flowSp)
    {
        string url = "https://duyvylatoi.pythonanywhere.com/predict";
        PredictionData data = new PredictionData
        {
            sv_config_str = svConfigStr,
            flow_sp = flowSp
        };
        string json = JsonUtility.ToJson(data);
        byte[] jsonToSend = new UTF8Encoding().GetBytes(json);
        UnityWebRequest request = UnityWebRequest.PostWwwForm(url, "POST");
        request.uploadHandler = (UploadHandler)new UploadHandlerRaw(jsonToSend);
        request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");
        yield return request.SendWebRequest();
        if (request.result == UnityWebRequest.Result.Success)
        {
            // Successfully received a response
            string jsonResponse = request.downloadHandler.text;

            // Deserialize JSON response
            PredictionResponse response = JsonUtility.FromJson<PredictionResponse>(jsonResponse);
            globalResponse = response;
            predictionResponses.Add(response); // Add response to list

            UpdateTextMeshPro(response);

     
       }
        else
        {
            Debug.LogError("Error occurred during prediction: " + request.error);
        }

    }


    public void UpdateTextMeshPro(PredictionResponse response)
    {
        Debug.Log("predict response count "+dataRows.Count);
        // Check if the number of responses exceeds maxRowCount
        if (dataRows.Count > 6)
        {
                Debug.Log("Entered IF response");
                // Get the first row in the list and remove it from the list
                GameObject rowToDelete = dataRows[0];
                dataRows.RemoveAt(0);
              
                // Destroy the row GameObject
                Destroy(rowToDelete);
          
          
            // Reset the position of the remaining rows
            for (int i = 0; i < dataRows.Count; i++)
            {
                // Calculate the position offset based on the index of the row
                float yyOffset = 40f;
              
                // Apply the position offset to the current row
                dataRows[i].transform.localPosition += new Vector3(0f, yyOffset, 0f);
            }
        }

      
                // Instantiate a new row GameObject
                GameObject newRow = Instantiate(dataRowPrefab, dataRowsParent);
                      
                // Add the new row to the list
                dataRows.Add(newRow);
                Debug.Log(newRow+ "Added new row to list");
                      
                // Calculate the position offset based on the index of the row
                float yOffset = -40f * (dataRows.Count-1);
                      
                // Apply the position offset to the new row
                newRow.transform.localPosition += new Vector3(0f, yOffset, 0f);
                      
                // Update the TextMeshPro components of the row with response data
                UpdateTextMeshProForRow(newRow, response);
      
    }



    private void UpdateTextMeshProForRow(GameObject row, PredictionResponse response)
        {
        // Access TextMeshPro components of the row
        TextMeshProUGUI[] textMeshes = row.GetComponentsInChildren<TextMeshProUGUI>();
      
            foreach (TextMeshProUGUI textMesh in textMeshes)
            {

                // Update each TextMeshPro component based on its name or other identifier
                switch (textMesh.gameObject.name)
                {
                    case "Loop":
                        textMesh.text = response.loop;
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "Valve Percent Open":
                        textMesh.text = response.c_valve_percent_open.ToString("0.00") + "%";
                        Debug.Log("Here is "+textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "DPT_01":
                        textMesh.text = response.dpt_01.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "DPT_02":
                        textMesh.text = response.dpt_02.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "DPT_03":
                        textMesh.text = response.dpt_03.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "DPT_04":
                        textMesh.text = response.dpt_04.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "DPT_05":
                        textMesh.text = response.dpt_05.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "DPT_06":
                        textMesh.text = response.dpt_06.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "DPT_07":
                        textMesh.text = response.dpt_07.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "DPT_08":
                        textMesh.text = response.dpt_08.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "DPT_09":
                        textMesh.text = response.dpt_09.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "DPT_10":
                        textMesh.text = response.dpt_10.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "DPT_11":
                        textMesh.text = response.dpt_11.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "Flow Rate":
                        textMesh.text = response.flow_rate.ToString("0.00") + "gpm";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "GPT_01":
                        textMesh.text = response.gpt_01.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "GPT_02":
                        textMesh.text = response.gpt_02.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "GPT_03":
                        textMesh.text = response.gpt_03.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;
                    case "Mean Error":
                        textMesh.text = response.mean_error.ToString("0.00") + " PSI";
                        Debug.Log("Here is "+ textMesh.gameObject.name +" "+textMesh.text);
                        break;

 
                }
            }
        } 
}

I am getting this error when running the game on unity but not while running in unity editor
AndroidPlayer “Oculus_Quest 2” Error occurred during prediction: Cannot resolve destination host
d__13:MoveNext()
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

AndroidPlayer “Oculus_Quest 2” Curl error 6: Could not resolve host: vy.pythonanywhere.com

You did notice that the URL is truncated?

I wonder if this has to do with the domain containing or the first part ending in “atoi” which is a C++ method to convert “ascii string to integer”. Perhaps there’s a cleaning process that prevents some sort of code injection. You may want to try accessing another subdomain like “abcd.python…” for testing, or generally any other public webrequest API that receives and returns json (plenty of them around, freely accessible).

That is just something I wonder about. May be nothing after all since there are other parts of the subdomain missing too.

This was the full error

You
AndroidPlayer “Oculus_Quest 2” Curl error 6: Could not resolve host: duyvylatoi.pythonanywhere.com
but we will try to change the url as well.