arduino-libraries / ArduinoHttpClient

Arduino HTTP Client library
288 stars 172 forks source link

How to POST a request to a https #101

Closed CHM1968 closed 3 years ago

CHM1968 commented 3 years ago

Hi, I'm pretty new on Arduino. I'm using ArduinoHttpClient and need to POST a request in secure way (https://). I'm not able to define the https:// on the serverName passed to HttpClient(ethernetClient, serverName, webServerPort). When I use serverName = url (ssl9083.websiteseguro.com or 179.188.19.74) with port 443 the board hangs and after sometime returns -3 on httpClient.responseStatusCode().

I'm using Arduino Uno R3 with Ethernet Shield W5100.

I'd appreciate any help. Below the code.

Thank you in advance.

#include <Ethernet.h>
#include <EthernetUdp.h>
#include <ArduinoHttpClient.h>

//UDP Variables
#define UDP_PACKET_SIZE 80 //UDP size
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress localIp(192, 168, 1, 9);
unsigned int localPort = 8888;      // local port to listen on
char packetBuffer[UDP_PACKET_SIZE];  // buffer to hold incoming packet,
EthernetUDP Udp; // An EthernetUDP instance to let us send and receive packets over UDP

//Http Variables
// Environment = P, H, D
char ENV[1] = {'H'};
const char* devServerName = "192.168.1.105";
const char* homServerName = "179.188.19.74";
//const char* homServerName = "https://ssl9083.websiteseguro.com/cfbinformatica"; Port 80 - NOK Frooze
//const char* homServerName = "https://ssl9083.websiteseguro.com"; Port 80 - NOK Frooze
//const char* homServerName = "ssl9083.websiteseguro.com/cfbinformatica"; Port 80 - NOK Frooze
//const char* homServerName = "ssl9083.websiteseguro.com"; Port 80 - OK conectou e retornou 404
//const char* homServerName = "179.188.19.74"; Port 80 OK conectou e retornou 404 - Port 443 retornou -3
const char* prdServerName = "ssl9083.websiteseguro.com/cfbinformatica";
String measurementServiceInsertMeasurement = "/MeasurementService.svc/InsertMeasurement";
String postInsertMeasurement = "/MeasurementService.svc/InsertMeasurement";
String serverName;
int webServerPort;
EthernetClient ethernetClient;
String authUserUid;
String userValidationUidCredentials;

void setup() {
  setupSerial();
  setupEthernetUDP();
  setupHttp();
}

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

void setupEthernetUDP() {
  // start the Ethernet
  Ethernet.begin(mac, localIp);
  Serial.print("IP: ");
  Serial.println(Ethernet.localIP());

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Etn shield notFnd");
    while (1);
  }

  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Cable notConn");
    while (1);
  }

  // start UDP
  Udp.begin(localPort);
  Serial.println("UDP init OK");
  delay(5000);
}

void setupHttp() {
  // Your Domain name with URL path or IP address with path

    switch(ENV[0]) {
    case 'P' :
      serverName = prdServerName;
      webServerPort = 443;
      postInsertMeasurement = "/housemeterprd" + measurementServiceInsertMeasurement;
      break;
    case 'H' :
      serverName = homServerName;
      webServerPort = 443;
      postInsertMeasurement = "/cfbinformatica/housemeterhom" + measurementServiceInsertMeasurement;
      break;
    default :
      serverName = devServerName;
      webServerPort = 80;
      postInsertMeasurement = "/housemeterdev" + measurementServiceInsertMeasurement;
  }
  authUserUid = "Mg==";
  userValidationUidCredentials = "PlUfGKwdXKmcF7HEoEPFu5QqGA3w52ukaUsIp5gOOlOXX928fermbxvGNsfbVr4Q";
  Serial.println("HTTP init OK");
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i=0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    readPackage();
    processPackage();
  }
  delay(10);
}

void readPackage() {
  // read the packet into packetBufffer
  Udp.read(packetBuffer, UDP_PACKET_SIZE);
  Serial.println("Contents:");
  Serial.println(packetBuffer);
}

void processPackage() {
  switch(packetBuffer[0]) {
    case 'A' :
      handleAckMsg();
      break;
    case 'E' :
      handleErrorMsg();
      break;
    default :
      handleDataMsg();
  }
}

void handleAckMsg() {

}

void handleErrorMsg() {

}

void handleDataMsg() {
  String meterMAC;
  meterMAC = convertToString(packetBuffer+35, 12);
  String measurementValue;
  measurementValue = convertToString(packetBuffer+20, 15);
  String postData = "{\"meterMAC\":\"" + meterMAC + "\",\"measurementValue\":" + measurementValue +"}";
  sendHttpPostDataMsg(&postData);
  replyBack();
}

void sendHttpPostDataMsg(String *postData) {
  Serial.print(serverName); 
  Serial.println(" Server ");
  Serial.print(webServerPort); 
  Serial.println(" port ");
  Serial.print(postInsertMeasurement); 
  Serial.println(" Url");
  String data = *postData;
  Serial.print(data); 
  Serial.println(" data ");
  Serial.print(data.length()); 
  Serial.println(" data length ");

  HttpClient httpClient = HttpClient(ethernetClient, serverName, webServerPort);

  httpClient.beginRequest();
  httpClient.post(postInsertMeasurement);

  httpClient.sendHeader("Content-Type", "application/json;charset=utf-8");
  httpClient.sendHeader("Content-Length", data.length()); 
  httpClient.sendHeader("Accept", "application/json");
  httpClient.sendHeader("AuthUserUid", authUserUid);
  httpClient.sendHeader("AuthUserValidationUid", userValidationUidCredentials);
  httpClient.sendHeader("DeviceLanguage", "English");
  httpClient.sendHeader("AuthUserProfile", "user");

  httpClient.beginBody();
  httpClient.print(data);

  httpClient.endRequest();
  int statusCode = httpClient.responseStatusCode();
  String response = httpClient.responseBody();

  httpClient.flush();
  httpClient.stop();

  Serial.print(statusCode); 
  Serial.println(" Http ret code");
  Serial.print("Response: ");
  Serial.println(response);      
}

void replyBack() {
  // send a reply to the IP address and port that sent us the packet we received
  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.write(packetBuffer);
  Udp.endPacket();
}

String convertToString(char* arr, int size)
{
    int i;
    String s = "";
    for (i = 0; i < size; i++) {
        s = s + arr[i];
    }
    return s;
}

here the results of the http call: 21:30:49.179 -> IP: 192.168.1.9 21:30:49.179 -> UDP init OK 21:30:54.226 -> HTTP init OK 21:31:05.891 -> Received packet of size 47 21:31:05.891 -> From 192.168.1.32, port 58412 21:31:05.937 -> Contents: 21:31:05.937 -> 000000000000000010330000000017.9090DEADBEEFFEED 21:31:05.985 -> 179.188.19.74 Server 21:31:06.031 -> 443 port 21:31:06.031 -> /cfbinformatica/housemeterhom/MeasurementService.svc/InsertMeasurement Url 21:31:06.125 -> {"meterMAC":"DEADBEEFFEED","measurementValue":0000000017.9090} data 21:31:06.172 -> 62 data length 21:32:07.214 -> -3 Http ret code 21:32:07.214 -> Response:

per1234 commented 3 years ago

Hi @CHM1968. Thanks for your interest in the ArduinoHttpClient library.

I see we already have a prior issue report about this at https://github.com/arduino-libraries/ArduinoHttpClient/issues/87.

It's best to have only a single issue per subject so we can consolidate all relevant discussion to one place, so I'll go ahead and close this in favor of the other.

If you end up with additional information to share, feel free to comment in the other thread.