301 Redirect Error sending data to Server using Esp32

Hello Everyone,

I have a premium database set up and have the script and everything ready to go. I tested sending data through my browser and the database accepted the request and echoed new request successful and the data was entered into the database. Now, when I send with my esp32, I am getting the following error:

14:24:35.152 -> +CIPRXGET: 2,0,1023,9
14:24:35.152 -> HTTP/1.1 301 Moved Permanently
14:24:35.152 -> Connection: close
14:24:35.152 -> content-type: text/html
14:24:35.152 -> content-length: 707
14:24:35.152 -> date: Thu, 15 Jun 2023 18:24:34 GMT
14:24:35.152 -> server: LiteSpeed
14:24:35.152 -> location: https://bridgesense.net/update4.php?data=1&X=-0.1373&Y=0.0065&Z=9.7151&T=14:50:32:252
14:24:35.152 -> platform: hostinger
14:24:35.152 -> content-security-policy: upgrade-insecure-requests
14:24:35.190 -> 
14:24:35.190 -> <!DOCTYPE html>
14:24:35.190 -> <html style="height:100%">
14:24:35.190 -> <head>
14:24:35.190 -> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
14:24:35.190 -> <title> 301 Moved Permanently
14:24:35.190 -> </title></head>
14:24:35.190 -> <body style="color: #444; margin:0;font: normal 14px/20px Arial, Helvetica, sans-serif; height:100%; background-color: #fff;">
14:24:35.190 -> <div style="height:auto; min-height:100%; ">     <div style="text-align: center; width:800px; margin-left: -400px; position:absolute; top: 30%; left:50%;">
14:24:35.247 ->         <h1 style="margin:0; font-size:150px; line-height:150px; font-weight:bold;">301</h1>
14:24:35.247 -> <h2 style="margin-top:20px;font-size: 30px;">Moved Permanently
14:24:35.247 -> </h2>
14:24:35.247 -> <p>The document has been permanently moved.</p>
14:24:35.247 -> </div></div></body
14:24:35.247 -> OK
14:24:35.270 -> AT+CIPRXGET=2,0,9
14:24:35.270 -> 
14:24:35.270 -> +CIPRXGET: 2,0,9,0
14:24:35.270 -> ></html>
14:24:35.270 -> 
14:24:35.270 -> OK
AT+CIPRXGET=4,0

+CIPRXGET: 4,0,0

OK
AT+CIPSTATUS=0

+CIPSTATUS: 0,0,"TCP","154.49.142.244","80","REMOTE CLOSING"

OK
AT+CIPRXGET=4,0

+CIPRXGET: 4,0,0

OK
AT+CIPSTATUS=0

+CIPSTATUS: 0,0,"TCP","154.49.142.244","80","REMOTE CLOSING"

OK

My receiver code is below:

#include <esp_now.h>
#include <WiFi.h>

#define TINY_GSM_MODEM_SIM7000
#define SerialMon Serial
#define SerialAT Serial1
#define TINY_GSM_RX_BUFFER 1024
#define DUMP_AT_COMMANDS
#define TINY_GSM_DEBUG SerialMon
#define GSM_AUTOBAUD_MIN 9600
#define GSM_AUTOBAUD_MAX 115200
#define TINY_GSM_USE_GPRS true
#define TINY_GSM_USE_WIFI false
#define GSM_PIN ""

const char apn[]      = "213x.m2m.com.attz";
const char gprsUser[] = "";
const char gprsPass[] = "";

const char server[]   = "bridgesense.net";
const int  port       = 80;


#include <TinyGsmClient.h>
#include <ArduinoHttpClient.h>

#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm        modem(debugger);
#else
TinyGsm        modem(SerialAT);
#endif

#define UART_BAUD   115200
#define PIN_DTR     25
#define PIN_TX      27
#define PIN_RX      26
#define PWR_PIN     4

TinyGsmClient client(modem);
HttpClient    http(client, server, port);
int counter, lastIndex, numberOfPieces = 24;
String pieces[24], input;
float value_data[8] = {0.0};
int count = 0;
int url_Check = 0;

//Function Declaration
void updateData();
void initGSM();
void connectAPN();

//String data1 , data2 , data3 , data4, data5, data6, data7;
String data_Post = "";
char resource[16384];
typedef struct struct_message {

  float depth1;
  float depth2;
  float depth3;
  float depth4;
  float accel_x;
  float accel_y;
  float accel_z;
  char TTime[15];
  float Temp;


} struct_message;


struct_message myData;
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&myData, incomingData, sizeof(myData));
  /*
    Serial.print("\n Bytes received: ");
    Serial.println(len);
    Serial.print("\n Depth_1: ");
    Serial.println(myData.depth1);
    Serial.print("\n Depth_2: ");
    Serial.println(myData.depth2);
    Serial.print("\n Depth_3: ");
    Serial.println(myData.depth3);
    Serial.print("\n Depth_4: ");
    Serial.println(myData.depth4);
    Serial.print("\n X-Accel: ");
    Serial.println(myData.accel_x);
    Serial.print("\n Y-Accel: ");
    Serial.println(myData.accel_y);
    Serial.print("\n Z-Accel: ");
    Serial.println(myData.accel_z);

  */
  //convert to Float
  //  value_data[0] = String(myData.depth1).toFloat();
  //  value_data[1] = String(myData.depth2).toFloat();
  //  value_data[2] = String(myData.depth3).toFloat();
  //  value_data[3] = String(myData.depth4).toFloat();
  //  value_data[4] = String(myData.accel_x).toFloat();
  //  value_data[5] = String(myData.accel_y).toFloat();
  //  value_data[6] = String(myData.accel_z).toFloat();
  //  value_data[7] = String(myData.Temp).toFloat();


  /*
    &D1= depth1 sensor
    &D2= depthe2 sensor
    &D3= deppth3 sensor
    &D4= depthe4 sensor
    &X= X-acceleration
    &Y= Y-acceleration
    &Z= Z-acceleration
    &Te= Temperature
    &T= Time
  */
  if (myData.depth1 == 0 && myData.depth2 == 0 && myData.depth3 == 0 && myData.depth4 == 0 &&  myData.Temp == 0) // If depth1,2,3,4 & Temp is equal to zero. It means we are only sending Acceleration & time
  {
    if (url_Check == 0)
    {
      data_Post += "/update4.php?data=1";

    }

    data_Post += "&X=" + String(myData.accel_x, 4 ) + "&Y=" + String(myData.accel_y, 4) + "&Z=" + String(myData.accel_z, 4) + "&T=" + String(myData.TTime);
                 count++;
                 url_Check = 1;
                 if (count == 1) //change the packet size
  {
    Serial.println(data_Post);
      updateData();
      delay(11115000);
      count = 0;
      data_Post = "";
      url_Check = 0;

    }

  }
  else  // send complete packet
  {
    data_Post += "/update4.php?data=2";
    data_Post += "&D1=" + String(myData.depth1, 2 ) + "&D2=" + String(myData.depth2, 2) + "&D3=" + String(myData.depth3, 2) + "&D4=" + String(myData.depth4, 2);
    data_Post += "&X=" + String(myData.accel_x, 4 ) + "&Y=" + String(myData.accel_y, 4) + "&Z=" + String(myData.accel_z, 4) + "&Te=" + String(myData.Temp, 2);
    data_Post += "&T=" + String(myData.TTime);
    Serial.println(data_Post);
    updateData();
    data_Post = "";

  }


}


//This Setup code is executed once then moves to void loop

void setup() {
  SerialMon.begin(115200);
  delay(10);
  initGSM();
  delay(2000);
  connectAPN();
  delay(2000);
  WiFi.mode(WIFI_STA);
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  else {
    Serial.println("ESP-NOW initialized Sucessfully");
  }
  esp_now_register_recv_cb(OnDataRecv);
}

void loop() {

}


//Intilization and Setup is everything above this comment Line


//The board is only intended to perform specific tasks once during the setup phase and
//then wait for external events or interrupts to trigger new actions or behaviors. In this case,
//the loop() function may be left blank because the board does not need to do anything continuously.
//You have to have a loop() function, but it doesn't have to have anything in it.
//So put everything in setup(), and have an empty loop().


void updateData() {

  if (modem.isGprsConnected()) {
    char resource[4096];


    // SerialMon.print(F("Performing HTTP GET request... "));



    data_Post.toCharArray(resource , data_Post.length() + 1);
    Serial.println(resource);
    Serial.println("---------------END PACKET------");
    Serial.println("-----Sending Data starts----");
    int err = http.get(resource);
    if (err != 0) {
      SerialMon.println(F("failed to connect"));
      delay(10000);
      return;
    }
    Serial.println("----sending data ends----");
    //  int status_code = http.responseStatusCode();
    //      SerialMon.print(F("Response status code: "));
    //      SerialMon.println(status_code);
    //      if (!status_code) {
    //        //delay(10000);
    //       // return;
    //      }
    //      SerialMon.println(F("Response Headers:"));
    //      while (http.headerAvailable()) {
    //        String headerName  = http.readHeaderName();
    //        String headerValue = http.readHeaderValue();
    //        SerialMon.println("    " + headerName + " : " + headerValue);
    //      }
    //      int length = http.contentLength();
    //      if (length >= 0) {
    //        SerialMon.print(F("Content length is: "));
    //        SerialMon.println(length);
    //      }
    //      if (http.isResponseChunked()) {
    //        SerialMon.println(F("The response is chunked"));
    //    }
    String body = http.responseBody();
    //  SerialMon.println(F("Response:"));
    //   SerialMon.println(body);
    // http.stop();
    //  http.connectionKeepAlive();
    //      SerialMon.println(F("Server disconnected"));


  }
  else {

    if (!modem.gprsConnect(apn, gprsUser, gprsPass))
    {
      Serial.println("---GPRS not connected!----");
      Serial.println("---Re-initit GSM/GPRS---");
      initGSM();
      connectAPN();

    }
    else
    {
      Serial.println("---GPRS is connected!---");
    }

  }


}



void initGSM() {

  Serial.println("-------InitGSM starts-----");

  pinMode(PWR_PIN, OUTPUT);
  digitalWrite(PWR_PIN, HIGH);
  delay(300);
  digitalWrite(PWR_PIN, LOW);

  SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);
  Serial.println("Initializing modem...");
  //  if (!modem.restart()) {
  //    Serial.println("Failed (modem.restart()) to restart modem, attempting to continue without restarting");
  //  }
  Serial.println("Initializing modem...");
  if (!modem.init()) {
    Serial.println("Failed  (modem.init()) to restart modem, attempting to continue without restarting");
  }

  String name = modem.getModemName();
  //delay(500);
  Serial.println("Modem Name: " + name);

  String modemInfo = modem.getModemInfo();
  //delay(500);
  Serial.println("Modem Info: " + modemInfo);
  if ( GSM_PIN && modem.getSimStatus() != 3 ) {
    modem.simUnlock(GSM_PIN);
  }
  modem.sendAT("+CFUN=0 ");
  if (modem.waitResponse(10000L) != 1) {
    DBG(" +CFUN=0  false ");
  }
  //delay(200);
  String res;
  res = modem.setNetworkMode(2);
  if (res != "1") {
    DBG("setNetworkMode  false ");
    return ;
  }
  //delay(200);
  res = modem.setPreferredMode(1);
  if (res != "1") {
    DBG("setPreferredMode  false ");
    return ;
  }
  //delay(400);
  modem.sendAT("+CFUN=1 ");
  if (modem.waitResponse(10000L) != 1) {
    DBG(" +CFUN=1  false ");
  }
  //delay(200);

  SerialAT.println("AT+CGDCONT?");
  delay(50);
  if (SerialAT.available()) {
    input = SerialAT.readString();
    for (int i = 0; i < input.length(); i++) {
      if (input.substring(i, i + 1) == "\n") {
        pieces[counter] = input.substring(lastIndex, i);
        lastIndex = i + 1;
        counter++;
      }
      if (i == input.length() - 1) {
        pieces[counter] = input.substring(lastIndex, i);
      }
    }
    input = "";
    counter = 0;
    lastIndex = 0;

    for ( int y = 0; y < numberOfPieces; y++) {
      for ( int x = 0; x < pieces[y].length(); x++) {
        char c = pieces[y][x];  //gets one byte from buffer
        if (c == ',') {
          if (input.indexOf(": ") >= 0) {
            String data = input.substring((input.indexOf(": ") + 1));
            if ( data.toInt() > 0 && data.toInt() < 25) {
              modem.sendAT("+CGDCONT=" + String(data.toInt()) + ",\"IP\",\"" + String(apn) + "\",\"0.0.0.0\",0,0,0,0");
            }
            input = "";
            break;
          }
          // Reset for reuse
          input = "";
        } else {
          input += c;
        }
      }
    }
  } else {
    Serial.println("Failed to get PDP!");
  }

  Serial.println("\n\n\nWaiting for network...");
  if (!modem.waitForNetwork()) {
    //delay(10000);
    return;
  }

  if (modem.isNetworkConnected()) {
    Serial.println("Network connected");
  }

  Serial.println("\n---Starting GPRS TEST---\n");
  Serial.println("Connecting to: " + String(apn));
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    //delay(10000);
    return;
  }

  Serial.print("GPRS status: ");
  if (modem.isGprsConnected()) {
    Serial.println("connected");
  } else {
    Serial.println("not connected");
  }

  Serial.println("--------Init GSM ends-------");
}


void connectAPN() {
  Serial.print("Connecting to APN: ");
  Serial.print(apn);
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    Serial.println(" fail");
  }
  else {
    Serial.println(" OK");
  }
}

It looks like your server wants to upgrade your http request to an https request. Your browser probably just does it in the background.

The ESP32 does not. You will have to follow the link provided by your server and go to

https://bridgesense.net/update4.php?data=1&X=-0.1373&Y=0.0065&Z=9.7151&T=14:50:32:252

Which will lead you into the land of HTTPS, Certificates, etc..

I tried that and got the following error now: 400 Bad Request

HTTPS is required

This is an SSL protected page, please use the HTTPS scheme instead of the plain HTTP scheme to access this URL.

Hint: The URL should starts with https://


Powered By LiteSpeed Web Server
http://www.litespeedtech.com

You cannot simply change http to https and expect it to work. You will need all the other bits that come with https. Did you read the tutorial?

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