Отправить запрос на публикацию файла из ESP32
Невозможно ли отправить запрос на публикацию файла с ESP32, используя файловую систему SPIFFS? ESP32 зависает при отправке.
Пример кода:
File file = SPIFFS.open("/Images/test.bmp", FILE_READ);
String start_request = ""; String end_request = "";
start_request = start_request +
"\n--AaB03x\n" +
"Content-Disposition: form-data; name=\"userfile\"; filename=\"CAM.bmp\"\n" +
"Content-Transfer-Encoding: binary\n\n";
end_request = end_request + "\n--AaB03x--\n";
uint16_t full_length;
full_length = start_request.length() + file.size() + end_request.length();
WiFiClient client;
if (!client.connect("server_name", 80)) {
Serial.println("Connected FILED!");
return;
}
Serial.println("Connected ok!");
client.println("POST /Home/Index HTTP/1.1");
client.println("Host: example.com");
client.println("User-Agent: ESP32");
client.println("Content-Type: multipart/form-data; boundary=AaB03x");
client.print("Content-Length: "); client.println(full_length);
client.print(start_request);
while (file.available()){
client.write(file.read());
}
Serial.println(">>><<<");
client.println(end_request);
@, 👍0
Обсуждение1 ответ
▲ -1
Можно отправить запрос POST с полями данных, дополненными двоичными данными, как показано в приведенном ниже коде. Представленный код был создан для выполнения POST-запроса к репозиторию Dataverse, однако его можно легко адаптировать к любому другому POST-запросу. Наконец, приведенный ниже код оптимизирован для микропроцессоров Tensilica Xtensa LX6/7 по сравнению с ESP32.
Полный код можно найти здесь:
https ://github.com/aeonSolutions/openScienceResearch-Smart-DAQ-Device-able-to-Upload-Live-Experimental-Sensor-Data-to-a-Data-Repo
// ************************************************* ***************
// Загрузить набор данных в Dataverse Гарварда
// ******************************************************* **********
void UploadToDataverse() {
//Проверяем статус соединения WiFi
if(WiFi.status() != WL_CONNECTED){
mserial.printStrln("WiFi Disconnected");
if (connect2WIFInetowrk()){
UploadToDataverse();
}
}
// Начать отправку файла набора данных
File datasetFile = FFat.open("/"+EXPERIMENTAL_DATA_FILENAME, FILE_READ);
if (!datasetFile){
mserial.printStrln("Dataset file not found");
return;
}
String boundary = "7MA4YWxkTrZu0gW";
String contentType = "text/csv";
// DATASET_REPOSITORY_URL = "/api/files/:persistentId/replace?persistentId=" +PERSISTENT_ID;
DATASET_REPOSITORY_URL = "/api/datasets/:persistentId/add?persistentId="+PERSISTENT_ID;
String datasetFileName = datasetFile.name();
String datasetFileSize = String(datasetFile.size());
mserial.printStrln("Dataset File Details:");
mserial.printStrln("Filename:" + datasetFileName);
mserial.printStrln("size (bytes): "+ datasetFileSize);
mserial.printStrln("");
WiFiClientSecure client;
int str_len = SERVER_URL.length() + 1; // Длина (с одним дополнительным символом нулевого терминатора)
char SERVER_URL_char [str_len]; // Подготавливаем массив символов (буфер)
SERVER_URL.toCharArray(SERVER_URL_char, str_len); // Копируем его
client.stop();
client.setCACert(HARVARD_ROOT_CA_RSA_SHA1);
if (!client.connect(SERVER_URL_char, SERVER_PORT)) {
mserial.printStrln("Cloud server URL connection FAILED!");
mserial.printStrln(SERVER_URL_char);
int server_status = client.connected();
mserial.printStrln("Server status code: " + String(server_status));
return;
}
mserial.printStrln("Connected to the dataverse of Harvard University");
mserial.printStrln("");
// Теперь мы создаем URI для запроса
mserial.printStr("Requesting URL: ");
mserial.printStrln(DATASET_REPOSITORY_URL);
// Делаем HTTP-запрос и добавляем HTTP-заголовки
// заголовок сообщения
String postHeader = "POST " + DATASET_REPOSITORY_URL + " HTTP/1.1\r\n";
postHeader += "Host: " + SERVER_URL + ":" + String(SERVER_PORT) + "\r\n";
postHeader += "X-Dataverse-key: " + API_TOKEN + "\r\n";
postHeader += "Content-Type: multipart/form-data; boundary=" + boundary + "\r\n";
postHeader += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
postHeader += "Accept-Encoding: gzip,deflate\r\n";
postHeader += "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
postHeader += "User-Agent: AeonLabs LDAD Smart DAQ device\r\n";
postHeader += "Keep-Alive: 300\r\n";
postHeader += "Connection: keep-alive\r\n";
postHeader += "Accept-Language: en-us\r\n";
// заголовок jsonData
String jsonData = "{\"description\":\"LIVE Experimental data upload from LDAD Smart 12bit DAQ \",\"categories\":[\"Data\"], \"restrict\":\"false\", \"tabIngest\":\"false\"}";
String jsonDataHeader = "--" + boundary + "\r\n";
jsonDataHeader += "Content-Disposition: form-data; name=\"jsonData\"\r\n\r\n";
jsonDataHeader += jsonData+"\r\n";
// заголовок набора данных
String datasetHead = "--" + boundary + "\r\n";
datasetHead += "Content-Disposition: form-data; name=\"file\"; filename=\"" + datasetFileName + "\"\r\n";
datasetHead += "Content-Type: " + contentType + "\r\n\r\n";
// хвост запроса
String tail = "\r\n--" + boundary + "--\r\n\r\n";
// длина содержимого
int contentLength = jsonDataHeader.length() + datasetHead.length() + datasetFile.size() + tail.length();
postHeader += "Content-Length: " + String(contentLength, DEC) + "\n\n";
// отправляем заголовок поста
int postHeader_len=postHeader.length() + 1;
char charBuf0[postHeader_len];
postHeader.toCharArray(charBuf0, postHeader_len);
client.print(charBuf0);
mserial.printStr(charBuf0);
// отправляем заголовок ключа
char charBufKey[jsonDataHeader.length() + 1];
jsonDataHeader.toCharArray(charBufKey, jsonDataHeader.length() + 1);
client.print(charBufKey);
mserial.printStr(charBufKey);
// отправка буфера запросов
char charBuf1[datasetHead.length() + 1];
datasetHead.toCharArray(charBuf1, datasetHead.length() + 1);
client.print(charBuf1);
mserial.printStr(charBuf1);
// создаем буфер
const int bufSize = 2048;
byte clientBuf[bufSize];
int clientCount = 0;
while (datasetFile.available()) {
clientBuf[clientCount] = datasetFile.read();
clientCount++;
if (clientCount > (bufSize - 1)) {
client.write((const uint8_t *)clientBuf, bufSize);
clientCount = 0;
}
}
datasetFile.close();
if (clientCount > 0) {
client.write((const uint8_t *)clientBuf, clientCount);
mserial.printStrln("[binary data]");
}
// отправить хвост
char charBuf3[tail.length() + 1];
tail.toCharArray(charBuf3, tail.length() + 1);
client.print(charBuf3);
mserial.printStr(charBuf3);
// Читаем все строки ответа с сервера и печатаем их в mserial
mserial.printStrln("");
mserial.printStrln("Response Headers:");
String responseHeaders = "";
while (client.connected()) {
// mserial.printStrln("при подключении клиента");
responseHeaders = client.readStringUntil('\n');
mserial.printStrln(responseHeaders);
if (responseHeaders == "\r") {
mserial.printStrln("====== end of headers ======");
break;
}
}
String responseContent = client.readStringUntil('\n');
mserial.printStrln("Harvard University's Dataverse reply was:");
mserial.printStrln("==========");
mserial.printStrln(responseContent);
mserial.printStrln("==========");
mserial.printStrln("closing connection");
client.stop();
}
,
@Miguel Silva
Смотрите также:
- esp32, platformio A fatal error occurred: Packet content transfer stopped (received 8 bytes) *** [upload] Error 2
- Как выбрать альтернативные контакты I2C на ESP32?
- Драйверы для чипа последовательного порта CH9102X
- Как преобразовать форматированный оператор print в строковую переменную?
- ESP32 - "Детектор Браунаута был активирован" при запуске Wi-Fi
- Питание esp32cam от аккумулятора
- Контакты RX и TX на esp32
- ESP32: отключить детектор отключения питания
HTTP требует пустой строки после заголовков. добавьте пустую строку с
client.println()
передclient.print(start_request);
, @Juraj