Привет! Всю голову сломал, нужна помощь.
с клиента приходит такой POST-запрос:
POST /save HTTP/1.1
Host: 192.168.0.17
Connection: keep-alive
Content-Length: 47
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://192.168.0.17
Referer: http://192.168.0.17/secure.htm
Accept-Encoding: gzip, deflate
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
field1=TTK-191&field2=ghbdtnbr&newField=newValue
имеется библиотека:
#pragma once
#include <Arduino.h>
#include <Ethernet.h>
#include <SD.h>
#define MAX_REQUEST_HANDLERS 10
class ArdClient {
private:
EthernetServer server;
EthernetClient client;
byte _MACAddress[6];
byte _IPAddress[4];
int _port;
typedef void (*RequestHandler)(EthernetClient client);
struct RequestHandlerEntry {
const char* path;
RequestHandler handler;
};
typedef void (*PostHandler)(EthernetClient client, String body);
struct PostHandlerEntry {
const char* path;
PostHandler handler;
};
RequestHandlerEntry requestHandlers[MAX_REQUEST_HANDLERS];
PostHandlerEntry postHandlers[MAX_REQUEST_HANDLERS];
int numRequestHandlers = 0;
int numPostHandlers = 0;
public:
ArdClient(int port = 80);
void begin(byte MACAddress[], byte IPAddress[], byte subnetMask[]) {
Ethernet.begin(MACAddress, IPAddress, subnetMask);
memcpy(_MACAddress, MACAddress, 6);
memcpy(_IPAddress, IPAddress, 4);
}
void begin(byte MACAddress[], byte IPAddress[]) {
Ethernet.begin(MACAddress, IPAddress);
memcpy(_MACAddress, MACAddress, 6);
memcpy(_IPAddress, IPAddress, 4);
}
void sendHeader(EthernetClient client) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
}
void onRequest(const char* path, RequestHandler handler) {
if (numRequestHandlers < MAX_REQUEST_HANDLERS) {
requestHandlers[numRequestHandlers].path = path;
requestHandlers[numRequestHandlers].handler = handler;
numRequestHandlers++;
}
}
void onPost(const char* path, PostHandler handler) {
if (numPostHandlers < MAX_REQUEST_HANDLERS) {
postHandlers[numPostHandlers].path = path;
postHandlers[numPostHandlers].handler = handler;
numPostHandlers++;
}
}
void tick() {
EthernetClient incomingClient = server.available();
if (incomingClient) {
String request = "";
while (incomingClient.connected()) {
if (incomingClient.available()) {
char c = incomingClient.read();
Serial.print(c); // выводим полный GET/POST запрос в Serial
request += c;
if (c == '\n') {
break;
}
}
}
String path = request.substring(request.indexOf(' ') + 1, request.lastIndexOf(' '));
if (request.startsWith("POST")) {
// If it's a POST request, extract body from the request
String body = request.substring(request.lastIndexOf("\r\n\r\n") + 4);
handlePost(incomingClient, path.c_str(), body);
} else if (request.startsWith("GET")) {
handleGet(incomingClient, path.c_str());
}
incomingClient.stop();
}
}
void handleGet(EthernetClient client, const char* path) {
if (path[0] != '/') { // проверяем наличие символа "/" в начале строки path
client.println("HTTP/1.1 404 Not Found");
client.println("Content-Type: text/html");
client.println();
client.println("<h1>404 Not Found</h1>");
return;
}
for (int i = 0; i < numRequestHandlers; i++) {
Serial.print("requestHandlers[i].path = "); Serial.println(requestHandlers[i].path);
Serial.print("path = "); Serial.println(path);
if (strstr(path, requestHandlers[i].path) != NULL
&& strstr(path, requestHandlers[i].path) == path
&& strlen(path) == strlen(requestHandlers[i].path)) {
Serial.println("OK");
requestHandlers[i].handler(client);
return;
}
}
if (numRequestHandlers >= MAX_REQUEST_HANDLERS) {
client.println("HTTP/1.1 500 Internal Server Error");
client.println("Content-Type: text/html");
client.println();
client.println("<h1>500 Internal Server Error</h1>");
return;
}
client.println("HTTP/1.1 404 Not Found");
client.println("Content-Type: text/html");
client.println();
client.println("<h1>404 Not Found</h1>");
}
void handlePost(EthernetClient client, const char* path, String body) {
for (int i = 0; i < numPostHandlers; i++) {
Serial.print("postHandlers[i].path = "); Serial.println(postHandlers[i].path);
Serial.print("path = "); Serial.println(path);
if (strstr(path, postHandlers[i].path) != NULL
&& strstr(path, postHandlers[i].path) == path
&& strlen(path) == strlen(postHandlers[i].path)) {
Serial.println("OK");
postHandlers[i].handler(client, body);
return;
}
}
if (numPostHandlers >= MAX_REQUEST_HANDLERS) {
client.println("HTTP/1.1 500 Internal Server Error");
client.println("Content-Type: text/html");
client.println();
client.println("<h1>500 Internal Server Error</h1>");
return;
}
client.println("HTTP/1.1 404 Not Found");
client.println("Content-Type: text/html");
client.println();
client.println("<h1>404 Not Found</h1>");
}
};
ArdClient::ArdClient(int port) : _port(port), server(port) {}
и основной код программы:
#include "ArdClient.h"
byte mac[] = {0x4C, 0xD3, 0xAF, 0x1B, 0xF8, 0x99};
byte ip[] = {192, 168, 0, 17};
byte subnet[] = {255, 255, 255, 0};
ArdClient server(80);
bool SD_OK;
void setup() {
Serial.begin(9600);
server.begin(mac, ip, subnet);
if (!SD.begin(4)) return;
Serial.println("SD OK");
SD_OK = true;
// добавление обработчиков GET запросов
server.onRequest("/", handleIndex);
server.onRequest("/index.htm", handleIndex);
server.onRequest("/secure.htm", handleSecure);
server.onPost("/save", handleSave);
}
void loop() {
if (!SD_OK) return;
server.tick();
}
void handleIndex(EthernetClient client) {
File webFile = SD.open("htm/index.htm");
if (webFile) {
server.sendHeader(client);
while (webFile.available()) {
client.write(webFile.read());
}
webFile.close();
} else {
server.sendHeader(client);
client.println("<h1>File not found</h1>");
}
}
void handleSecure(EthernetClient client) {
File webFile = SD.open("htm/secure.htm");
if (webFile) {
server.sendHeader(client);
while (webFile.available()) {
client.write(webFile.read());
}
webFile.close();
} else {
server.sendHeader(client);
client.println("<h1>File not found</h1>");
}
}
void handleSave(EthernetClient client, String body) {
Serial.print("POST /save ");
Serial.print("body = ");Serial.println(body);
// здесь можно произвести сохранение полученных данных
server.sendHeader(client);
client.print("<html><body><h1>POST request saved</h1></body></html>");
}
проблема в том, что в ф-ции handleSave(EthernetClient client, String body);
body возвращает “T /save HTTP/1.1”, а мне нужно чтобы body = “field1=TTK-19&field2=ghbdtnbr&newField=newValue”. Не пойму где ошибка в библиотеке.
Люди добрые, помогите, всю голову сломал. Спасибо!