ARDUINO网络服务器身份验证

时间:2016-03-05 09:59:50

标签: html c++ c arduino webserver

我有一个" index.htm"文件加载到以太网屏蔽的SD卡上。它用于将文本从网页发送到Arduino以便在LCD上显示。它工作正常,直到这里。当我尝试向Arduino Web服务器添加基本HTTP身份验证时出现问题。网站加载但我输入的文字没有显示在液晶显示屏上。我检查了LCD连接,没有问题。我认为我在Arduino上的代码存在问题。这是没有HTTP身份验证的Arduino代码:

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#include <LiquidCrystal.h>
// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ   40
// size of buffer that stores a line of text for the LCD + null terminator
#define LCD_BUF_SZ   17

// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,6);   // IP address, may need to change depending on network
EthernetServer server(80);       // create a server at port 80
File webFile;                    // the web page file on the SD card
char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
char req_index = 0;              // index into HTTP_req buffer
char lcd_buf_1[LCD_BUF_SZ] = {0};// buffer to save LCD line 1 text to
char lcd_buf_2[LCD_BUF_SZ] = {0};// buffer to save LCD line 2 text to
LiquidCrystal lcd(10,9,8,7,6,5);

void setup()
{
// disable Ethernet chip
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);

Serial.begin(115200);       // for debugging

lcd.begin(16, 2);
// Message on LCD
lcd.print(F("Initializing"));

// initialize SD card
Serial.println("Initializing SD card...");
if (!SD.begin(4)) {
    Serial.println("ERROR - SD card initialization failed!");
    lcd.print(F("SD init failed"));
    return;    // init failed
}
Serial.println("SUCCESS - SD card initialized.");
// check for index.htm file
if (!SD.exists("index.htm")) {
    Serial.println("ERROR - Can't find index.htm file!");
    return;  // can't find index file
}
Serial.println("SUCCESS - Found index.htm file.");

Ethernet.begin(mac, ip);  // initialize Ethernet device
server.begin();           // start to listen for clients

// End of initialization message on LCD + print IP address
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Done."));
lcd.setCursor(0, 1);
lcd.print(ip);
}

void loop()
{
EthernetClient client = server.available();  // try to get client

if (client) {  // got client?
    boolean currentLineIsBlank = true;
    while (client.connected()) {
        if (client.available()) {   // client data available to read
            char c = client.read(); // read 1 byte (character) from client
            // limit the size of the stored received HTTP request
            // buffer first part of HTTP request in HTTP_req array (string)
            // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
            if (req_index < (REQ_BUF_SZ - 1)) {
                HTTP_req[req_index] = c;          // save HTTP request character
                req_index++;
            }
            // last line of client request is blank and ends with \n
            // respond to client only after last line received
            if (c == '\n' && currentLineIsBlank) {
                // send a standard http response header
                client.println("HTTP/1.1 200 OK");
                // remainder of header follows below, depending on if
                // web page or XML page is requested
                // Ajax request - send XML file
                if (StrContains(HTTP_req, "ajax_inputs")) {
                    // send rest of HTTP header
                    client.println("Content-Type: text/xml");
                    client.println("Connection: keep-alive");
                    client.println();

                    // print the received text to the LCD if found
                    if (GetLcdText(lcd_buf_1, lcd_buf_2, LCD_BUF_SZ)) {
                      // lcd_buf_1 and lcd_buf_2 now contain the text from
                      // the web page
                      // write the received text to the LCD
                      lcd.clear();
                      lcd.setCursor(0, 0);
                      lcd.print(lcd_buf_1);
                      lcd.setCursor(0, 1);
                      lcd.print(lcd_buf_2);
                    }
                }
                else {  // web page request
                    // send rest of HTTP header
                    client.println("Content-Type: text/html");
                    client.println("Connection: keep-alive");
                    client.println();
                    // send web page
                    webFile = SD.open("index.htm");        // open web page file
                    if (webFile) {
                        Serial.println("Successfully opened webfile");

                        while(webFile.available()) {
                            client.write(webFile.read()); // send web page to client
                        }
                        webFile.close();
                    }
                }
                // reset buffer index and all buffer elements to 0
                req_index = 0;
                StrClear(HTTP_req, REQ_BUF_SZ);
                break;
            }
            // every line of text received from the client ends with \r\n
            if (c == '\n') {
                // last character on line of received text
                // starting new line with next character read
                currentLineIsBlank = true;
            } 
            else if (c != '\r') {
                // a text character was received from client
                currentLineIsBlank = false;
            }
        } // end if (client.available())
    } // end while (client.connected())
    delay(1);      // give the web browser time to receive the data
    client.stop(); // close the connection
} // end if (client)
}

// get the two strings for the LCD from the incoming HTTP GET request
boolean GetLcdText(char *line1, char *line2, int len)
{
 boolean got_text = false;    // text received flag
 char *str_begin;             // pointer to start of text
 char *str_end;               // pointer to end of text
 int str_len = 0;
 int txt_index = 0;
 char *current_line;

 current_line = line1;

 // get pointer to the beginning of the text
 str_begin = strstr(HTTP_req, "&L1=");

 for (int j = 0; j < 2; j++) { // do for 2 lines of text
  if (str_begin != NULL) {
  str_begin = strstr(str_begin, "=");  // skip to the =
  str_begin += 1;                      // skip over the =
  str_end = strstr(str_begin, "&");

  if (str_end != NULL) {
    str_end[0] = 0;  // terminate the string
    str_len = strlen(str_begin);

    // copy the string to the buffer and replace %20 with space ' '
    for (int i = 0; i < str_len; i++) {
      if (str_begin[i] != '%') {
        if (str_begin[i] == 0) {
          // end of string
          break;
        }
        else {
          current_line[txt_index++] = str_begin[i];
          if (txt_index >= (len - 1)) {
            // keep the output string within bounds
            break;
          }
        }
      }
      else {
        // replace %20 with a space
        if ((str_begin[i + 1] == '2') && (str_begin[i + 2] == '0')) {
          current_line[txt_index++] = ' ';
          i += 2;
          if (txt_index >= (len - 1)) {
            // keep the output string within bounds
            break;
          }
        }
      }
    } // end for i loop
    // terminate the string
    current_line[txt_index] = 0;
    if (j == 0) {
      // got first line of text, now get second line
      str_begin = strstr(&str_end[1], "L2=");
      current_line = line2;
      txt_index = 0;
    }
    got_text = true;
  }
 }
 } // end for j loop

 return got_text; 

}

// sets every element of str to 0 (clears array)
void StrClear(char *str, char length)
{
for (int i = 0; i < length; i++) {
    str[i] = 0;
}
}

 // searches for the string sfind in the string str
 // returns 1 if string found
 // returns 0 if string not found
char StrContains(char *str, char *sfind)
{
char found = 0;
char index = 0;
char len;

len = strlen(str);

if (strlen(sfind) > len) {
    return 0;
}
while (index < len) {
    if (str[index] == sfind[found]) {
        found++;
        if (strlen(sfind) == found) {
            return 1;
        }
    }
    else {
        found = 0;
    }
    index++;
}

return 0;
}

并且,以下是带有身份验证的代码:

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#include <LiquidCrystal.h>
// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ   40
// size of buffer that stores a line of text for the LCD + null terminator
#define LCD_BUF_SZ   17

// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,12);   // IP address, may need to change depending on network
EthernetServer server(80);       // create a server at port 80
File webFile;                    // the web page file on the SD card
char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
char req_index = 0;              // index into HTTP_req buffer
char lcd_buf_1[LCD_BUF_SZ] = {0};// buffer to save LCD line 1 text to
char lcd_buf_2[LCD_BUF_SZ] = {0};// buffer to save LCD line 2 text to
LiquidCrystal lcd(10,9,8,7,6,5);

void setup()
{
// disable Ethernet chip
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);

Serial.begin(115200);       // for debugging

lcd.begin(16, 2);
// Message on LCD
lcd.print(F("Initializing"));

// initialize SD card
Serial.println(F("Initializing SD card..."));
if (!SD.begin(4)) {
    Serial.println(F("ERROR - SD card initialization failed!"));
    lcd.print(F("SD init failed"));
    return;    // init failed
}
Serial.println(F("SUCCESS - SD card initialized."));
// check for index.htm file
if (!SD.exists("index.htm")) {
    Serial.println(F("ERROR - Can't find index.htm file!"));
    return;  // can't find index file
}
Serial.println(F("SUCCESS - Found index.htm file."));

Ethernet.begin(mac, ip);  // initialize Ethernet device
server.begin();           // start to listen for clients

// End of initialization message on LCD + print IP address
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Done."));
lcd.setCursor(0, 1);
lcd.print(ip);
}



void SendAuthentificationpage(EthernetClient &client)
{
      client.println("HTTP/1.1 401 Authorization Required");
      client.println("WWW-Authenticate: Basic realm=\"Secure Area\"");
      client.println("Content-Type: text/html");
      client.println("Connnection: close");
      client.println();
      client.println("<!DOCTYPE HTML>");
      client.println("<HTML>  <HEAD>   <TITLE>Error</TITLE>");
      client.println(" </HEAD> <BODY><H1>401 Unauthorized.</H1></BODY> </HTML>");
}

boolean authentificated=false;
void loop()
{
EthernetClient client = server.available();  // try to get client

if (client) {  // got client?
    memset(HTTP_req,0,sizeof(HTTP_req));

    authentificated=false;
    boolean currentLineIsBlank = true;
    while (client.connected()) {
        if (client.available()) {   // client data available to read
            char c = client.read(); // read 1 byte (character) from client
            // limit the size of the stored received HTTP request
            // buffer first part of HTTP request in HTTP_req array (string)
            // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)


            if (req_index < (REQ_BUF_SZ - 1)) {
                HTTP_req[req_index] = c;          // save HTTP request character
                req_index++;
            }
            Serial.println(HTTP_req);
            // last line of client request is blank and ends with \n
            // respond to client only after last line received
            if (c == '\n' && currentLineIsBlank) {
              if(authentificated){
                // send a standard http response header
                client.println("HTTP/1.1 200 OK");
                // remainder of header follows below, depending on if
                // web page or XML page is requested
                // Ajax request - send XML file
                if (StrContains(HTTP_req, "ajax_inputs")) {
                    // send rest of HTTP header
                    Serial.println(F("Receiving text"));
                    client.println("Content-Type: text/xml");
                    client.println("Connection: keep-alive");
                    client.println();

                    // print the received text to the LCD if found
                    if (GetLcdText(lcd_buf_1, lcd_buf_2, LCD_BUF_SZ)) {
                      // lcd_buf_1 and lcd_buf_2 now contain the text from
                      // the web page
                      // write the received text to the LCD
                      lcd.clear();
                      lcd.setCursor(0, 0);
                      lcd.print(lcd_buf_1);
                      //lcd.setCursor(0, 1);
                      //lcd.print(lcd_buf_2);
                    }
                }
                else {  // web page request
                    // send rest of HTTP header
                    client.println("Content-Type: text/html");
                    client.println("Connection: keep-alive");
                    client.println();
                    // send web page
                    webFile = SD.open("index.htm");        // open web page file
                    if (webFile) {
                        Serial.println(F("Successfully opened webfile"));

                        while(webFile.available()) {
                            client.write(webFile.read()); // send web page to client
                        }
                        webFile.close();
                    }
                }
                // reset buffer index and all buffer elements to 0
                req_index = 0;
                StrClear(HTTP_req, REQ_BUF_SZ);
                break;
            }
            else {
                       SendAuthentificationpage(client);                
            }
            break;
          }
            // every line of text received from the client ends with \r\n
            if (c == '\n') {
                // last character on line of received text
                // starting new line with next character read
               if (strstr(HTTP_req,"Authorization: Basic")>0 && strstr(HTTP_req,"ZWNlOm5vdGljZQ==")>0)
                authentificated=true;
                 memset(HTTP_req,0,sizeof(HTTP_req));
                 req_index=0;
                currentLineIsBlank = true;
            } 
            else if (c != '\r') {
                // a text character was received from client
                currentLineIsBlank = false;
            }

        } // end if (client.available())
    } // end while (client.connected())
    delay(1);      // give the web browser time to receive the data
    client.stop(); // close the connection
} // end if (client)
}

// get the two strings for the LCD from the incoming HTTP GET request
boolean GetLcdText(char *line1, char *line2, int len)
{

//Serial.println(")
 boolean got_text = false;    // text received flag
 char *str_begin;             // pointer to start of text
 char *str_end;               // pointer to end of text
 int str_len = 0;
 int txt_index = 0;
 char *current_line;

 current_line = line1;

 // get pointer to the beginning of the text
 str_begin = strstr(HTTP_req, "&L1=");

for (int j = 0; j < 2; j++) { // do for 2 lines of text
if (str_begin != NULL) {
  str_begin = strstr(str_begin, "=");  // skip to the =
  str_begin += 1;                      // skip over the =
  str_end = strstr(str_begin, "&");

  if (str_end != NULL) {
    str_end[0] = 0;  // terminate the string
    str_len = strlen(str_begin);

    // copy the string to the buffer and replace %20 with space ' '
    for (int i = 0; i < str_len; i++) {
      if (str_begin[i] != '%') {
        if (str_begin[i] == 0) {
          // end of string
          break;
        }
        else {
          current_line[txt_index++] = str_begin[i];
          if (txt_index >= (len - 1)) {
            // keep the output string within bounds
            break;
          }
        }
      }
      else {
        // replace %20 with a space
        if ((str_begin[i + 1] == '2') && (str_begin[i + 2] == '0')) {
          current_line[txt_index++] = ' ';
          i += 2;
          if (txt_index >= (len - 1)) {
            // keep the output string within bounds
            break;
          }
        }
      }
    } // end for i loop
    // terminate the string
    current_line[txt_index] = 0;
    if (j == 0) {
      // got first line of text, now get second line
      str_begin = strstr(&str_end[1], "L2=");
      current_line = line2;
      txt_index = 0;
    }
    got_text = true;
  }
}
} // end for j loop

return got_text;
}

// sets every element of str to 0 (clears array)
void StrClear(char *str, char length)
{
for (int i = 0; i < length; i++) {
    str[i] = 0;
}
}

// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char *str, char *sfind)
{
char found = 0;
char index = 0;
char len;

len = strlen(str);

if (strlen(sfind) > len) {
    return 0;
}
while (index < len) {
    if (str[index] == sfind[found]) {
        found++;
        if (strlen(sfind) == found) {
            return 1;
        }
    }
    else {
        found = 0;
    }
    index++;
}

return 0;
}

网站正确加载。在代码中,如果GET请求包含字符串&#34; ajax_input&#34;,则必须在LCD上显示我在网站中输入的文本。但是,这种情况并没有发生。我来到这里。请帮助!

PS:这是串口显示器的屏幕截图。可以看出,&#34; ajax_inputs&#34;明确存在于GET请求中。此外,我在网页中键入的内容显示在串行监视器中(堆栈溢出)。 serial monitor 如果您需要,我会参考这些教程:https://startingelectronics.org/tutorials/arduino/ethernet-shield-web-server-tutorial/SD-card-web-server/

0 个答案:

没有答案
相关问题