esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
15.98k stars 13.34k forks source link

could not read complete response in WiFiClientSecure #5041

Closed ali-zohrevand closed 6 years ago

ali-zohrevand commented 6 years ago

Basic Infos

hi. i used WiFiClientSecure example but in response client read string until new line i want complete response

Platform

Settings in IDE

Problem Description

i used WiFiClientSecure example but in response client read string until new line

String line = client.readStringUntil('\n');

is there any function read complete client response?

my response is corrupted :
WiFi connected
IP address: 
192.168.137.66
connecting to httpbin.org
certificate matches
requesting URL: /get
request sent
headers received
reply was:
==========
{
==========
closing connection

Sketch

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char* ssid = "...";
const char* password = ".....";

ESP8266WebServer server(80);

const int led = 4;

void handleRoot() {
  digitalWrite(led, 1);
  server.send(200, "text/plain", "Hello from esp8266!");
  digitalWrite(led, 0);
}

void handleNotFound(){
  digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  digitalWrite(led, 0);
}

void setup(void){
  pinMode(led, OUTPUT);
  digitalWrite(led, 0);
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }

  server.on("/", handleRoot);

  server.on("/inline", [](){
    server.send(200, "text/plain", "this works as well");
  });

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop(void){
  server.handleClient();
}
devyte commented 6 years ago

The sketch uses the basic webserver, but your problem talks about WiFiClientSecure. That makes no sense. Also, I suspect you didn't fill out the core version, among other things, because the string there are the defaults. Please edit your post and fill in the required info carefully, or this will be closed.

ali-zohrevand commented 6 years ago

thanks for answering. i know sketch is for basic web server, i just looking for function could return complete response not readStringUntil some byte. is there any function in WiFiClientSecure that could do it, i searched in source file but unfortunately i could not find proper function

Pablo2048 commented 6 years ago

Simple int read(uint8_t *buf, size_t size) override; does not work?

kherNI commented 6 years ago

@c0otlass I'm not sure this is the best way, but it has worked for me:


  String chunk = "";
  int limit = 1;

  do {
    if (tlsClient.connected()) {
      yield();
      tlsClient.setTimeout(2000);
      chunk = tlsClient.readStringUntil('\n');
      response += chunk;
      Serial.println(chunk);
    }
  } while (chunk.length() > 0 && ++limit < 100);
Serial.println(response);```
ali-zohrevand commented 6 years ago

@KaloNK thanks

it worked

/*
 *  HTTP over TLS (HTTPS) example sketch
 *
 *  This example demonstrates how to use
 *  WiFiClientSecure class to access HTTPS API.
 *  We fetch and display the status of
 *  esp8266/Arduino project continuous integration
 *  build.
 *
 *  Created by Ivan Grokhotkov, 2015.
 *  This example is in public domain.
 */

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>

const char* ssid = "ali";
const char* password = "123456789";

const char* host = "httpbin.org";
const int httpsPort = 443;

// Use web browser to view and copy
// SHA1 fingerprint of the certificate
const char* fingerprint = "EF C5 CA CC 17 68 74 DC A6 4B 15 6F 52 1B 47 53 1C FB 79 58";
//EF:C5:CA:CC:17:68:74:DC:A6:4B:15:6F:52:1B:47:53:1C:FB:79:58

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.print("connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Use WiFiClientSecure class to create TLS connection
  WiFiClientSecure client;
  Serial.print("connecting to ");
  Serial.println(host);
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    return;
  }

  if (client.verify(fingerprint, host)) {
    Serial.println("certificate matches");
  } else {
    Serial.println("certificate doesn't match");
  }

  String url = "/get";
  Serial.print("requesting URL: ");
  Serial.println(url);

  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "User-Agent: ESP8266\r\n" +
               "Connection: close\r\n\r\n");

  Serial.println("request sent");
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
  }

  String chunk = "";
  int limit = 1;
  String response="";

Serial.println(response);
 // String line = client.readStringUntil('z');
    do {
    if (client.connected()) {
      client.setTimeout(2000);
      chunk = client.readStringUntil('\n');
      response += chunk;
      Serial.println(chunk);
    }
  } while (chunk.length() > 0 && ++limit < 100);
  Serial.println("reply was:");
  Serial.println("==========");
 // Serial.println(line);
  Serial.println("==========");
}

void loop() {
}
JasonMeredith1 commented 5 years ago

What if we wanted to send the response to ArduinoJson to deserialize ? I can get my response to print to serial, but I need to grab a 2 specific parts of the json response... ideas?

JasonMeredith1 commented 5 years ago

`#include

include

ifndef STASSID

define STASSID "###ssid####"

define STAPSK "####pass####"

endif

const char ssid = STASSID; const char password = STAPSK;

const char* host = "maps.googleapis.com"; const int httpsPort = 443; // Current fingerprint for maps.googleapis.com

const char* fingerprint = "C6 3E 93 AB 25 2B 06 11 2F F9 D3 61 FB 2E 89 28 91 2C 27 46";

void setup() { Serial.begin(115200); Serial.println(); Serial.print("connecting to "); Serial.println(ssid); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP());

// Use WiFiClientSecure class to create TLS connection WiFiClientSecure client; Serial.print("connecting to "); Serial.println(host);

Serial.printf("Using fingerprint '%s'\n", fingerprint); client.setFingerprint(fingerprint);

if (!client.connect(host, httpsPort)) { Serial.println("connection failed"); return; }

String url = "/maps/api/directions/json?origin=14108+Vistawood%2C78249&destination=120+Playmoor%2C78210&departure_time=now&traffic_model=best_guess&key=####MYAPIKEY####";
Serial.print("requesting URL: ");
Serial.println(url);
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
           "Host: " + host + "\r\n" +
           "User-Agent: ESP8266\r\n" +
           "Connection: close\r\n\r\n");

Serial.println("request sent"); while (client.connected()) { String line = client.readStringUntil('\n'); if (line == "\r") { Serial.println("headers received"); break; } }

String chunk = ""; int limit = 1; String response="";

Serial.println(response); do { if (client.connected()) { client.setTimeout(4000); chunk = client.readStringUntil('\n'); response += chunk; Serial.println(chunk); } } while (chunk.length() > 0 && ++limit < 1000); } // I want to deserialize the JSON response and pull out // ["routes"]["legs"][0]["duration_in_traffic"]["text"] void loop(){ } `