I have a project working using the basic method in this code without the authentication part. It loads index.htm, css, js, jpg files succesfully. When I added the authentication parts, the HTTP_req is empty at line 89. Therefore, the StrContains line does not find "GET /index.htm".
This code appears all over the forum in differing variations. The version which works for me as an example does not use the "if (StrContains(HTTP_req, "GET /index.htm") method.
My project depends on the HTTP_req for finding AJAX statements. Is my response to the header off somehow?
The authentication works and the code gets to line 89...... then the browser does not load the index.htm.
It seems so close --- I really believe I have experimented diligently and read all the forum threads on this subject. Please help....
// Web Server Login form using SD card and the HTTP_req string method
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ 80
// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 113, 27, 159); // 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
void setup() {
// disable Ethernet chip
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
Serial.begin(115200); // for debugging
// initialize SD card
Serial.println(F("Initializing SD card..."));
if (!SD.begin(4)) {
Serial.println(F("ERROR - SD card initialization 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
}
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)
HTTP_req[req_index] = c;
if (req_index < (REQ_BUF_SZ - 1)) {
// HTTP_req[req_index] = c; // save HTTP request character
req_index++;
}
// Serial.write(c);
// 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) {
// Serial.println("Line 82......");
// send a standard http response header
// remainder of header follows below, depending on if
// web page or XML page is requested
// Ajax request - send XML file
client.println("HTTP/1.1 200 OK");
Serial.println("Line 89......");
if (StrContains(HTTP_req, "GET /index.htm")) {
client.println("Content-Type: text/html");
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 {
Serial.println("Line 110.........");
SendAuthentificationpage(client);
}
break;
}
// every line of text received from the client ends with \r\n
if (c == '\n') {
currentLineIsBlank = true;
// last character on line of received text
// starting new line with next character read
// admin:admin YWRtaW46YWRtaW4=
// ZWNlOm5vdGljZQ==
if (strstr(HTTP_req, "Authorization: Basic") > 0 && strstr(HTTP_req, "YWRtaW46YWRtaW4=") > 0)
authentificated = true;
// Serial.write(HTTP_req);
memset(HTTP_req, 0, sizeof(HTTP_req));
req_index = 0;
} 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)
} // rest of the code is same as without authentication
//============================================
// 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;
}