Problems writing to Client using EthernetWebServer_SSL_STM32 and SdFat libraries
Posted: Tue May 25, 2021 5:00 pm
This seems to be a problem similar to the one posted by ahorow, "Write to Ethernet truncated using EthernetWebServer_SSL_STM32 library".
I am attempting to write a file found on an SD card to a connected Ethernet client. The file opens fine, and I have no problems writing to the client. For testing purposes I also write the lines read from the file to the serial port at the same time as being written to the client. What is happening though, is that a larger portion of file contents are displayed in the serial monitor, but the browser only receives about 2900 characters. The actual file, not including the header, sent separately, is about 260000 bytes long. I ran a test sending the file's content via 8000 "client.print(...)" statements and this worked fine.
I have attached code. Anything not necessary to the basic function of the code has been stripped out to give us the minimum required to debug plus additional code for debug purposes. I am using the libraries EthernetWebServer_SSL_STM32 & SdFat. My code is derived from the WebServer example. No errors are registered during operation.
Links to the libraries are: https://github.com/greiman/SdFat & https://github.com/khoih-prog/EthernetW ... _SSL_STM32
Serial printout at startup:
Abbreviated contents of the file test.htm
Abbreviated output to the Serial monitor:
Writes to the serial monitor stop here.
Abbreviated output to the web client:
Writes to the client stop here.
These are things that I have tried:
I haven't programmed for a number of years, so I am a bit rusty and probably overlooking something obvious.
I am attempting to write a file found on an SD card to a connected Ethernet client. The file opens fine, and I have no problems writing to the client. For testing purposes I also write the lines read from the file to the serial port at the same time as being written to the client. What is happening though, is that a larger portion of file contents are displayed in the serial monitor, but the browser only receives about 2900 characters. The actual file, not including the header, sent separately, is about 260000 bytes long. I ran a test sending the file's content via 8000 "client.print(...)" statements and this worked fine.
I have attached code. Anything not necessary to the basic function of the code has been stripped out to give us the minimum required to debug plus additional code for debug purposes. I am using the libraries EthernetWebServer_SSL_STM32 & SdFat. My code is derived from the WebServer example. No errors are registered during operation.
Links to the libraries are: https://github.com/greiman/SdFat & https://github.com/khoih-prog/EthernetW ... _SSL_STM32
Serial printout at startup:
Code: Select all
Start WebServer on NUCLEO_F767ZI, using LAN8742A Ethernet & STM32Ethernet Library
EthernetWebServer_SSL_STM32 v1.3.0
You're connected to the network, IP = 192.168.2.164
Code: Select all
#include "defines.h"
#include "SdFat.h"
/****************************************************************************************************************************
WebServer.ino - Simple Arduino web server sample for ESP8266 AT-command shield
For STM32F/L/H/G/WB/MP1 with built-in Ethernet LAN8742A (Nucleo-144, DISCOVERY, etc) or W5x00/ENC28J60 shield/module
EthernetWebServer_SSL_STM32 is a library for STM32 using the Ethernet shields to run WebServer and Client with/without SSL
Use SSLClient Library code from https://github.com/OPEnSLab-OSU/SSLClient
Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer_SSL_STM32
Licensed under MIT license
*****************************************************************************************************************************/
#define REPLY_HEADER "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n"
void Process_Client_Request()
{
FsFile file;
char line[500];
char Received_Character = '\0';
uint32_t Character_Index = 0;
uint32_t n;
uint32_t File_Length_Bytes;
uint32_t File_Length_Lines;
// listen for incoming clients
EthernetClient client = server.available();
static ArduinoOutStream cout(Serial);
if (client)
{
// an http request ends with a blank line
bool currentLineIsBlank = true;
while (client.connected())
{
if (client.available())
{
char c = client.read();
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank)
{
Serial.println(F("Sending response:\n"));
// send a standard http response header
// use \r\n instead of many println statements to speedup data send
client.print(REPLY_HEADER);
Serial.println(F(REPLY_HEADER));
// Open the SD card
if (!sd.begin(SD_CONFIG))
{
sd.initErrorHalt(&Serial);
}
// Specify the file to read
char fileName[] = "test.htm";
// Open the file to READ from the SD card
if (!file.open(fileName, O_READ))
{
sd.errorHalt(&Serial, F("open failed"));
}
File_Length_Bytes = file.fileSize();
File_Length_Lines = 0;
Serial.print(__DATE__); Serial.print(", "); Serial.println(__TIME__);
while ((n = file.fgets(line, sizeof(line))) > 0)
{
// Write the line to the client
client.print(line);
// Print the line
Serial.print(line);
File_Length_Lines++;
}
file.close();
break;
}
if (c == '\n')
{
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r')
{
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(10);
// close the connection:
client.stop();
Serial.println(F("\n\nClient disconnected"));
Serial.println("\n");
Serial.print("Total bytes read: "); Serial.println(File_Length_Bytes);
Serial.print("Total lines read: "); Serial.println(File_Length_Lines);
Serial.println("");
}
}
Code: Select all
<html><body>
This is line number: 1<br>
This is line number: 2<br>
This is line number: 3<br>
This is line number: 4<br>
This is line number: 5<br>
...
This is line number: 7997<br>
This is line number: 7998<br>
This is line number: 7999<br>
This is line number: 8000<br>
</html></body>
Code: Select all
<html><body>
This is line number: 1<br>
This is line number: 2<br>
This is line number: 3<br>
This is line number: 4<br>
This is line number: 5<br>
...
This is line number: 198<br>
This is line number: 199<br>
This is line number: 200<br>
This is line number: 201<br>
This is line number: 202<br>
Abbreviated output to the web client:
Code: Select all
<html><body>
This is line number: 1<br>
This is line number: 2<br>
This is line number: 3<br>
This is line number: 4<br>
This is line number: 5<br>
...
This is line number: 99<br>
This is line number: 100<br>
This is line number: 101<br>
This is line number: 102<br>
This is line number: 103<br>
This i
These are things that I have tried:
- Different makes & sizes of SD cards using different formats - no change
- Modified to file.fgets(line, sizeof(line), "\n")) & client.write(line, countOfBytesReadWithfget); - no change
- I looked into https://github.com/OPEnSLab-OSU/SSLClie ... on-gotchas. They mention changes to allow for larger output buffer sizes to the Ethernet.h file. I have determined that the code is using the ethernet.h file found here: Arduino/libraries/STM32duino_LwIP/src/netif/ethernet.h. This file does not have the options to increase the buffer size. Tried going through the various header files referenced but have not been able to find a setting for send buffering.
- To illiminate possible timing issues I have added a delay of varying lengths to the inner while() loop. These had an adverse effect and were again removed.
- I have tried client.write(line, n);, client.print(line); and cout << line; methods - identical results using all three.
- I tried to use the standard Arduino SD library instead of the SdFat library. I also did a client.write(myFile.read()); instead of reading to the 'line' string variable, otherwise code unchanged. Same results - output to the client stops after about 104 of the 8000 line transferred.
I haven't programmed for a number of years, so I am a bit rusty and probably overlooking something obvious.