最近在測試ESP32,他的SimepleWiFiServer範例直接使用WiFiServer類別建立server,ESP8266則直接提供WebServer類別,server.on()函數可以根據url後面的字串自動呼叫處理函數,這功能在ESP32目前尚無法使用,因此撰寫了 HttpRequestString
類別,用來支援參數分析,只要將GET後面的字串帶入,就可得到 Uri與參數的Name-Value。該類別使用了 String 類別,WString.h是ESP32提供的,如果用於其他Core須自行修改,例如 #include <String.h>。
以下getClientRequest(),是參考ESP32的DNS_Web_Server的範例,當 client連線時,取的GET後面的request字串:
String getClientRequest(WiFiClient
client)
{
// Wait for data from client to become available
while(client.connected() && !client.available()){
delay(1);
}
// Read the first line of HTTP request
String request = client.readStringUntil('\r');
// First line of HTTP request looks like "GET /path
HTTP/1.1"
// Retrieve the "/path" part by finding the spaces
int addr_start = request.indexOf(' ');
int addr_end = request.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
Serial.print("Invalid request: ");
Serial.println(request);
return "";
}
request = request.substring(addr_start + 1, addr_end);
Serial.print("Request: ");
Serial.println(request);
client.flush();
return request;
}
|
將上面取得的request字串傳入responseClientRequest(),建立params物件後,即可取得request的uri與參數的值,接著可用於response判斷。
void responseClientRequest(WiFiClient
client, String request)
{
HttpRequestParams params(request);
if (params.Uri == "/")
{
sendHeader(client);
//if (params.get("Level").length()>0)
{
client.print("Level is
'");
client.print(params.get("Level"));
client.print("'<br>");
}
sendBody(client);
sendTail(client);
}
// Check to see if the client request was "GET /H" or
"GET /L":
else if (params.Uri=="/H") {
LedStatus = HIGH;
digitalWrite(pinLED, LedStatus); // GET /H turns the LED on
Serial.println("LED ON");
sendPage(client);
}
else if (params.Uri=="/L") {
LedStatus = LOW;
digitalWrite(pinLED, LedStatus); // GET /L turns the LED off
Serial.println("LED OFF");
sendPage(client);
}
else {
sendHeader(client);
client.print("HTTP/1.1 404 Not Found\r\n\r\n");
sendTail(client);
}
// close the connection:
client.stop();
Serial.println("client disonnected");
}
|
以下是類別HttpRequestString.h:
// HttpRequestString.h
#ifndef HttpRequestString_h
#define HttpRequestString_h
#include <WString.h>
#define MaxParamaterCount 10
typedef struct {
String Name;
String Value;
} HttpRequestParam;
class HttpRequestParams {
public:
String Uri;
HttpRequestParam param[MaxParamaterCount];
int paramCount;
HttpRequestParams(String request);
String get(String Name);
};
#endif //HttpRequestString_h
//
|
以下是實做檔HttpRequestString.cpp:
// HttpRequestString.cpp
#include <Arduino.h>
#include "HttpRequestParams.h"
#define DEBUG_LEVEL 0
HttpRequestParams::HttpRequestParams(String
request)
{
paramCount = 0;
int param_start = request.indexOf('?');
#if (DEBUG_LEVEL>0)
Serial.print("param_start=");
Serial.println(param_start);
#endif
if (param_start<0) {
Uri = request;
return; //no parameters
} else {
Uri = request.substring(0, param_start-1);
}
#if (DEBUG_LEVEL>0)
Serial.print("Uri=");
Serial.println(Uri);
#endif
int param_separator = request.indexOf('=', param_start + 1);
#if (DEBUG_LEVEL>0)
Serial.print("param_separator=");
Serial.println(param_separator);
#endif
while (param_separator > 0) { //found a parameter
param[paramCount].Name = request.substring(param_start + 1,
param_separator);
int param_end = request.indexOf('&', param_start + 1);
if (param_end<0) param_end = request.length(); //last parameter
param[paramCount].Value = request.substring(param_separator + 1,
param_end);
#if (DEBUG_LEVEL>0)
Serial.print("Param(");
Serial.print(paramCount);
Serial.print("): ");
Serial.print(param[paramCount].Name);
Serial.print("=");
Serial.println(param[paramCount].Value);
#endif
paramCount++;
param_start = param_end;
param_separator = request.indexOf('=', param_start + 1);
}
}
String HttpRequestParams::get(String
Name)
{
#if (DEBUG_LEVEL>1)
Serial.print("Search ");
Serial.print(Name);
#endif
for (int i=0; i<paramCount; i++) {
#if (DEBUG_LEVEL>1)
Serial.print(" ");
Serial.print(i);
#endif
if (param[i].Name.equals(Name)) {
#if (DEBUG_LEVEL>1)
Serial.print(" Found
");
Serial.println(param[i].Value);
#endif
return param[i].Value;
}
}
#if (DEBUG_LEVEL>1)
Serial.println();
#endif
return "";
}
|
沒有留言:
張貼留言