[Solved] GPRS - DDNS Web Redirection Issue

I’m having an issue trying to send a GET request over to my server running at my house on my Raspberry Pi.

Here’s my setup:
Arduino MKR GSM 1400 → no-ip.com DDNS (port forwarding) → Home router w/ port forwarding → raspberry pi

What I done so far:
I created an SQL DB on my pi with two php files to store all requests into the DB and to read all values from the DB.
Coded up the MKR GSM 1400 to send GET requests to my server.

I verified a few things:

  1. Local machine - I can sent a GET request (Chrome) on my local machine, capture it on my SQL DB and read it back
  2. VPN - Routed my local machine through a VPN and can send a GET request (Chrome), capture and read it back using the DDNS
  3. Postman - Verified I can send and read back data from my GET command local and through VPN using the DDNS (https://www.getpostman.com/)

This is telling my that everything on my server and DDNS should be setup OK and is working.
When I am trying to send a GET request with the MKR GSM 1400, I get a response back from my DDNS that matches exactly the same as my response back using Postman, However, the only difference is data does not get populated in my DB.
Here’s the part that is throwing me for a loop, if I replace the DDNS host name in my GET request with the IP of my home router, it works.

I don’t understand why I can’t use the hostname, but the IP address works just fine. I don’t understand if this is a noip.com web redirection issue or something how http requests are handled on the GSM module. It just doesn’t make sense to me how it works on chrome and postman, but not on the MKR GSM 1400. I tried doing a POST request and sending the data over in JASON format, with no luck either.

I’m trying to avoid having to ping the DDNS to get the IP and then use that IP for the requests. The application is for a remote weather station, where power and data matter, so I would like to reduce the number of operations I have to do.

The code I am using is basically one of the examples

// libraries
#include <MKRGSM.h>

#include "arduino_secrets.h" 
// Please enter your sensitive data in the Secret tab or arduino_secrets.h
// PIN Number
const char PINNUMBER[]     = SECRET_PINNUMBER;
// APN data
const char GPRS_APN[]      = SECRET_GPRS_APN;
const char GPRS_LOGIN[]    = SECRET_GPRS_LOGIN;
const char GPRS_PASSWORD[] = SECRET_GPRS_PASSWORD;

// initialize the library instance
GSMClient client;
GPRS gprs;
GSM gsmAccess;

// URL, path and port (for example: example.org)
char server[] = "XXXXX.ddns.net";
//char server[] = "XX.XX.XX.XX";  // Works when IP Address is used
char path[] = "/ardu2SQL.php?data=imhere";
int port = 80; // port 80 is the default for HTTP

void setup() {
  // initialize serial communications and wait for port to open:
  Serial1.begin(9600);
  while (!Serial1) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial1.println("Starting Arduino web client.");
  // connection state
  bool connected = false;

  // After starting the modem with GSM.begin()
  // attach the shield to the GPRS network with the APN, login and password
  while (!connected) {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
      connected = true;
    } else {
      Serial1.println("Not connected");
      delay(1000);
    }
  }

  Serial1.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, port)) {
    Serial1.println("connected");

    // Make a HTTP request:
    client.print("GET ");
    client.print(path);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
  } else {
    // if you didn't get a connection to the server:
    Serial1.println("connection failed");
  }
}

void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial1.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.available() && !client.connected()) {
    Serial1.println();
    Serial1.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    for (;;)
      ;
  }
}

Here’s the HTML response from the DDNS

HTTP/1.1 200 Found
Date: Wed, 20 Feb 2019 06:47:47 GMT
Server: Apache
Vary: Accept-Encoding
Content-Length: 965
Connection: close
Content-Type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<!-- WEB REDIRECTION PROVIDED BY NOIP.COM  http://www.noip.com/ -->
<head>
<TITLE></TITLE>
<meta name="keywords" content="">
<meta name="description" content="">
<link rel="icon" href="http://IPADDRESS:5211/favicon.ico" type="image/ico">
<link rel="shortcut icon" href="http://IPADDRESS:5211/favicon.ico">
</head>
<!--
<script language="JavaScript">
if(window != top) {
        top.location.href = location.href;
}
</script>
-->
<frameset  rows="*,29" >
	<frame src="http://IPADDRESS:5211/ardu2SQL.php" name="redir_frame" frameborder=0>
	
	<frame src="http://XXXX.ddns.net/KHgKKjl_popupgoogle.html" noresize="noresize" scrolling="no" name="ad_frame" 
frameborder="0">
	<noframes>
	Sorry, your browser does not support frames.  Click <a href="http://IPADDRESS:5211/ardu2SQL.php" TARGET=_top>here</A>
	</noframes>
</frameset>

</html>

EDIT: I think I just realized what is going on after I posted this. no-ip.com is responding back with the request I want to send in a frame. So if the browser doesn’t support a frame, the request doesn’t go through. Is there an easy way to ping the DDNS so I can get the forwarding IP from the host name?

I verified a few things:

  1. Local machine - I can sent a GET request (Chrome) on my local machine, capture it on my SQL DB and read it back
  2. VPN - Routed my local machine through a VPN and can send a GET request (Chrome), capture and read it back using the DDNS
  3. Postman - Verified I can send and read back data from my GET command local and through VPN using the DDNS (https://www.getpostman.com/)

Irrelevant. Go to a friend and try to access your server from there. Does that work? And don’t test it with a browser but on the command line.

The web-forwarding of no-ip.com does not work if you don’t have a browser with Javascript enabled. The Arduino is not able to run a browser (it never will).

Thanks for the help. I ended up getting it by fixing the post request I was sending and also using the IP directly. I didn't realize no-ip.com wouldn't work without JavaScript