Redirection with Arduino Wifi Rev 2

Hello

I am trying to control my arduino with a google spreadsheet. The sheet is as well used to log data.
Data logging works fine via a "doGet" script.
By data gathering i got:

Status code: 302
Response: <HTML>
<HEAD>
<TITLE>Moved Temporarily</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Moved Temporarily</H1>
The document has moved <A HREF="https://script.googleusercontent.com/macros/echo?user_content_key=sfl6s47tbDyzqTmZlivpG2PJADDmLTBQYKAqbXw_FyRiYupVBQCy2dDmDlWGfpGdFvl7wklzor7id5GbVlDVoCi61bQMiqKpOJmA1Yb3SEsKFZqtv3DaNYcMrmhZHmUMWojr9NvTBuBLhyHCd5hHa3RPuJqkvUROZaCe_pjVma7SmiJ9YXP6Gag2W0Sc4isrApF96gzrQTR0yx7NkUd_K5QZr9Setq5kZHMIxZvIaHLGQSpqBWNL-KDHPIhCQ5drda71HFMvP7Th5qV-y_4qEA&amp;lib=Moa8oYzMClGGgF5550jyaC6-vHCGOnLBX">here</A>.
</BODY>
</HTML>

Code Snippet for the get call:

Serial.println("making GET/ request");
String urlFinal1 = "/macros/s/" + GOOGLE_SCRIPT_ID + "/exec?read=A33";
client.get(urlFinal1);

//  statusCode = client.responseStatusCode();
//  response = client.responseBody();

Is there a way to "allow" this redirection?
atm following libraries are used:

#include <ArduinoHttpClient.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"

Might this library could help, but i can't find any examples or how to enable redirection
#include <HTTPed.h>

Thanks in advance for any support

Most Arduino HTTP client libraries don't offer support to automatically handle redirections. You have to implement that yourself. But that's quite easy, if the response code is 302 (or 303) just make another get using the URL you got in the "Location" header.

Although this library implements the redirection case I wouldn't recommend it as it uses the String class and this should be avoided on AVR (and megaAVR) platforms.
It's also rather uncommon for a library to print debug information to the serial interface without setting a corresponding flag or the like.

Thanks for your response:
I am more the hardware guy and not that good in programming.
Any examples /tipps how to "grab" this Location header?

Greetings

By looping through the headers after reading the response code and checking that it was 302 or 303.
Post your code because you might have to change part of it to do this.

I tried something here but getting the 404 error.
By copying the new link in the browser it works...so the parsing should be OK.
Anyway thanks already for the support

#include <ArduinoHttpClient.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"

char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;

char serverAddress[] = "script.google.com";  // server address
char serverAddress2[] = "script.googleusercontent.com";  // server address after redirect
int port = 443; // SSL Port
String GOOGLE_SCRIPT_ID = "AKfycbw7-xwd6z3u3TRix5n0ojuTvBjxQkec0hgNQhlo8Eh7HAnXIg__JDIndpSPgm1QhSix";    // ID von Params

WiFiSSLClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);
int status = WL_IDLE_STATUS;

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

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network.
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("Connected to WiFi");
  printWifiStatus();
}

void loop() {
  if (status == WL_CONNECTED) {
    client = HttpClient(wifi, serverAddress, port);
    Serial.println("making GET request");
    String urlFinal = "/macros/s/" + GOOGLE_SCRIPT_ID + "/exec?read=B2&p1=1&p2=2";
    client.get(urlFinal);

    // read the status code and body of the response
    int statusCode = client.responseStatusCode();
    String response = client.responseBody();
    Serial.print("Status code: ");
    Serial.println(statusCode);
    Serial.print("Response: ");
    Serial.println(response);

    // now parse the response
    int labelStart = response.indexOf("key");
    // find the first = after key
    int contentStart = response.indexOf("=", labelStart);
    // find the following } and get what's between the braces:
    int contentEnd = response.indexOf("\"", labelStart);
    String red_ID = response.substring(contentStart + 1, contentEnd);
    Serial.println("Parsed KEy");
    Serial.println(red_ID);
    Serial.println();


    //Request after redirect
    Serial.println("equest after redirect");
    client = HttpClient(wifi, serverAddress2, port);
    String urlFinal1 = "/macros/echo?user_content_key=" + red_ID;
    client.get(urlFinal1);

    // read the status code and body of the response
    statusCode = client.responseStatusCode();
    response = client.responseBody();
    Serial.print("Status code: ");
    Serial.println(statusCode);
    Serial.print("Response: ");
    Serial.println(response);
    delay(30000);
  }
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

Sorry, parsing html output if you could get a defined header isn't very clever. That output can change without notice because the content isn't fixed by any standard. But at least you posted your code, so we can help.

In front of the first line:

String response = client.responseBody();

insert:

if (statusCode == 302 || statusCode == 303) {
  String location;
  while (client.headerAvailable()) {
    if (client.readHeaderName() == "Location")
      location = client.readHeaderValue();
      break;
    }
  }
  if (location.length()) {
    // assume always https
    uint16_t path_begin = location.substring(8).indexOf('/');
    String server = location.substring(8, path_begin);
    String path = location.substring(path_begin);
    client. = HttpClient(wifi, server, port);
    client.get(path);
    statusCode = client.responseStatusCode();
  }
}

That might be because the browser does a lot more things than just sending requests and showing the result. One example is the Cookie system. Your URL on Google returns 3 cookies (sorry, I just tried your URL to get that information) which the server expects to be included as headers in the next request sent, even if that is a redirection.

Thanks a alot for your reply. I see your code is way more elegant than my newbie stuff.
I see i have a lot to learn parse/html handling.
Does your already solve this 3 cookies (header) thing?
(I can test earliest in the evening

No problem in using my url, its for testing obly atm.
:slight_smile:

Hello
I tested out. I had to do some small modifications, but now i am getting the correct response :slight_smile:

Thank you very much

Here what i modified. (one missing bracket and the plus 8 in building the server and path

    
    if (statusCode == 302 || statusCode == 303) {
      String location;
      Serial.print(" Redirection");
      while (client.headerAvailable()) {
        if (client.readHeaderName() == "Location") {
          location = client.readHeaderValue();
          break;
        }
      }
      if (location.length()) {
        uint16_t path_begin = location.substring(8).indexOf('/');
        String server = location.substring(8, path_begin + 8);
        String path = location.substring(path_begin + 8);
        client = HttpClient(wifi, server, port);
        client.get(path);
        statusCode = client.responseStatusCode();
        Serial.print("Status code: after Redirect is: ");
        Serial.println(statusCode);
      }
    }

Just for my understanding is it now working because in your code you are "updating" the client, while i created a new one, or why do i get now a 200 instead of a 404?

I'm not parsing the HTML returned but the header as the standard suggests. And your code relies on the Google server returning the parameters always in the same order and redirecting to the same URL except those parameters. That are probably too much assumptions.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.