最近在測試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 ""; } |
留言列表