Webduino authentication website from SD card

Hello Guys!

Authentication code: (http://ten-fingers-and-a-brain.com/tag/arduino/)

/* Web_Authentication.ino - Webduino Authentication example */

/* This example assumes that you're familiar with the basics
 * of the Ethernet library (particularly with setting MAC and
 * IP addresses) and with the basics of Webduino. If you
 * haven't had a look at the HelloWorld example you should
 * probably check it out first */

/* you can change the authentication realm by defining
 * WEBDUINO_AUTH_REALM before including WebServer.h */
#define WEBDUINO_AUTH_REALM "Weduino Authentication Example"

#include "SPI.h"
#include "Ethernet.h"
#include "WebServer.h"

/* CHANGE THIS TO YOUR OWN UNIQUE VALUE.  The MAC number should be
 * different from any other devices on your network or you'll have
 * problems receiving packets. */
static uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

/* CHANGE THIS TO MATCH YOUR HOST NETWORK.  Most home networks are in
 * the 192.168.0.XXX or 192.168.1.XXX subrange.  Pick an address
 * that's not in use and isn't going to be automatically allocated by
 * DHCP from your router. */
static uint8_t ip[] = { 192, 168, 1, 210 };

/* This creates an instance of the webserver.  By specifying a prefix
 * of "", all pages will be at the root of the server. */
#define PREFIX ""
WebServer webserver(PREFIX, 80);

void defaultCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
{
  server.httpSuccess();
  if (type != WebServer::HEAD)
  {
    P(helloMsg) = "<h1>Hello, World!</h1><a href=\"private.html\">Private page</a>";
    server.printP(helloMsg);
  }
}

void privateCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
{
  /* if the user has requested this page using the following credentials
   * username = user
   * password = user
   * display a page saying "Hello User"
   *
   * the credentials have to be concatenated with a colon like
   * username:password
   * and encoded using Base64 - this should be done outside of your Arduino
   * to be easy on your resources
   *
   * in other words: "dXNlcjp1c2Vy" is the Base64 representation of "user:user"
   *
   * if you need to change the username/password dynamically please search
   * the web for a Base64 library */
  if (server.checkCredentials("dXNlcjp1c2Vy"))
  {
    server.httpSuccess();
    if (type != WebServer::HEAD)
    {
      P(helloMsg) = "<h1>Hello User</h1>";
      server.printP(helloMsg);
    }
  }
  /* if the user has requested this page using the following credentials
   * username = admin
   * password = admin
   * display a page saying "Hello Admin"
   *
   * in other words: "YWRtaW46YWRtaW4=" is the Base64 representation of "admin:admin" */
  else if (server.checkCredentials("YWRtaW46YWRtaW4="))
  {
    server.httpSuccess();
    if (type != WebServer::HEAD)
    {
      P(helloMsg) = "<h1>Hello Admin</h1>";
      server.printP(helloMsg);
    }
  }
  else
  {
    /* send a 401 error back causing the web browser to prompt the user for credentials */
    server.httpUnauthorized();
  }
}

void setup()
{
  Ethernet.begin(mac, ip);
  webserver.setDefaultCommand(&defaultCmd);
  webserver.addCommand("index.html", &defaultCmd);
  webserver.addCommand("private.html", &privateCmd);
  webserver.begin();
}

void loop()
{
  char buff[64];
  int len = 64;

  /* process incoming connections one at a time forever */
  webserver.processConnection(buff, &len);
}

I have a index.htm and pic.jpg on the SD card.
index.htm:

<!DOCTYPE html>

<html>
    
<head>

<link rel="shortcut icon" href="/favicon.ico">    
</head>
    
<body>
<BODY background="pic.jpg" style="background-position:top center; background-repeat:no-repeat; background-attachment:fixed">
</body>

</html>

How can I display a background image? How can I read the index.htm file on the SD card?
Somebody help me! smiley-cry Please smiley-sad

How can I display a background image?

Looks like you are trying to.

I have a index.htm and pic.jpg on the SD card.

So, why do you have a command defined for other files:

  webserver.addCommand("index.html", &defaultCmd);
  webserver.addCommand("private.html", &privateCmd);

How can I read the index.htm file on the SD card?

One character at a time. What have you tried? There are examples in the SD library.

I’m sorry if I write something wrong.
I want to display the image on the SD card after authentication.
I tried. (192.168.1.177/private2.html). The screen is blank. Just so know.

/* Web_Authentication.ino - Webduino Authentication example */

/* This example assumes that you're familiar with the basics
 * of the Ethernet library (particularly with setting MAC and
 * IP addresses) and with the basics of Webduino. If you
 * haven't had a look at the HelloWorld example you should
 * probably check it out first */

/* you can change the authentication realm by defining
 * WEBDUINO_AUTH_REALM before including WebServer.h */
#define WEBDUINO_AUTH_REALM "Weduino Authentication Example"

#include "SPI.h"
#include "Ethernet.h"
#include "WebServer.h"
#include "SD.h"
/* CHANGE THIS TO YOUR OWN UNIQUE VALUE.  The MAC number should be
 * different from any other devices on your network or you'll have
 * problems receiving packets. */
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,177);

/* This creates an instance of the webserver.  By specifying a prefix
 * of "", all pages will be at the root of the server. */
#define PREFIX ""
WebServer webserver(PREFIX, 80);

void defaultCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
{
  server.httpSuccess();
  if (type != WebServer::HEAD)
  {
    P(helloMsg) = "<h1>Hello, World!</h1><a href=\"private.html\">Private page</a>";
    server.printP(helloMsg);
  }
}

void privateCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
{
  /* if the user has requested this page using the following credentials
   * username = user
   * password = user
   * display a page saying "Hello User"
   *
   * the credentials have to be concatenated with a colon like
   * username:password
   * and encoded using Base64 - this should be done outside of your Arduino
   * to be easy on your resources
   *
   * in other words: "dXNlcjp1c2Vy" is the Base64 representation of "user:user"
   *
   * if you need to change the username/password dynamically please search
   * the web for a Base64 library */
  if (server.checkCredentials("dXNlcjp1c2Vy"))
  {
    server.httpSuccess();
    if (type != WebServer::HEAD)
    {
      P(helloMsg) = "<h1>Hello User</h1>";
      server.printP(helloMsg);
    }
  }
  /* if the user has requested this page using the following credentials
   * username = admin
   * password = admin
   * display a page saying "Hello Admin"
   *
   * in other words: "YWRtaW46YWRtaW4=" is the Base64 representation of "admin:admin" */
  else if (server.checkCredentials("YWRtaW46YWRtaW4="))
  {
    server.httpSuccess();
    if (type != WebServer::HEAD)
    {
      P(helloMsg) = "<h1>Hello Admin</h1>";
      server.printP(helloMsg);

    }
  }
  else
  {
    /* send a 401 error back causing the web browser to prompt the user for credentials */
    server.httpUnauthorized();
  }
}
void sdHTML(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  server.httpSuccess();
  
  File datei;
  
  datei = SD.open("index.htm", FILE_READ);
  if(datei)
  {
    int16_t c;
    while((c = datei.read()) >= 0) {
      server.print((char)c);
    }
    datei.close();
  }
  else
  {
    Serial.println("Datei wurde nicht gefunden");
  }
}
void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  webserver.setDefaultCommand(&defaultCmd);
  webserver.addCommand("private.html", &privateCmd);
  webserver.addCommand("private2.html", &sdHTML);
  webserver.begin();
}

void loop()
{
  char buff[64];
  int len = 64;

  /* process incoming connections one at a time forever */
  webserver.processConnection(buff, &len);
}

Another trial:

#include <SPI.h>
#include <Ethernet.h>
#include <WebServer.h>
#include <SdFat.h>
#include <SdFatUtil.h>

#define REQ_BUF_SZ   20
#define BUFSIZ 100
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,177);
char rootFileName[] = "index.htm"; 
EthernetServer server(80);
byte USER_AUTHENDICATED=0;
/************ SDCARD STUFF ************/
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
int t=15;
// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))

void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}
/////////////////////////////////////////////////////////////////////////////////////
#define PREFIX ""
WebServer webserver(PREFIX, 80);
/////////////////////////////////////////////////////////////////////////////////////
void privateCmd(WebServer &serverA, WebServer::ConnectionType type, char *, bool)
{
  if  (serverA.checkCredentials("YWRtaW46YWRtaW4="))
  {
    serverA.httpSuccess();
    USER_AUTHENDICATED=1;
    delay(20);
    P(helloMsg) = "<html><head><meta http-equiv='refresh' content=3;></head><body bgcolor='#000000' style='font-family:Verdana;color:#ffffff;font-size:12px;'><form>Login Succesfull!</form></body></html>";
    serverA.printP(helloMsg);
    delay(20);
    STARTWEB();
  }
  else
  {serverA.httpUnauthorized(); 
   USER_AUTHENDICATED=0;

  }
}


void loop() {
    char buff[64];
  int len = 64;
  // listen for incoming clients0
  webserver.processConnection(buff, &len);
 
 if (USER_AUTHENDICATED==1)
    {
      
      STARTWEB();
    }
  
}

void defaultCmd(WebServer &serverA, WebServer::ConnectionType type, char *, bool)
{
  if  (serverA.checkCredentials("YWRtaW46YWRtaW4="))
  {
    serverA.httpSuccess();
    USER_AUTHENDICATED=1;
    delay(20);
    P(helloMsg) = "<html><head><meta http-equiv='refresh' content=4;></head><body bgcolor='#000000' style='font-family:Verdana;color:#ffffff;font-size:12px;'><form>Login Succesfull!</form></body></html>";
    serverA.printP(helloMsg);
    delay(20);
    STARTWEB();
  }
  else
  {serverA.httpUnauthorized(); 
   USER_AUTHENDICATED=0;
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(115200);
PgmPrint("Free RAM: ");
  Serial.println(FreeRam());  
  
  // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  // breadboards.  use SPI_FULL_SPEED for better performance.
  pinMode(10, OUTPUT);                       // set the SS pin as an output (necessary!)
  digitalWrite(10, HIGH);                    // but turn off the W5100 chip!

  if (!card.init(SPI_HALF_SPEED, 4)) error("card.init failed!");
  
  // initialize a FAT volume
  if (!volume.init(&card)) error("vol.init failed!");

  PgmPrint("Volume is FAT");
  Serial.println(volume.fatType(),DEC);
  Serial.println();
  
  if (!root.openRoot(&volume)) error("openRoot failed");

  // list file in root with date and size
  PgmPrintln("Files found in root:");
  root.ls(LS_DATE | LS_SIZE);
  Serial.println();
    
  // Recursive list of all directories
  PgmPrintln("Files found in all dirs:");
  root.ls(LS_R);
  
  Serial.println();
  PgmPrintln("Done");
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  
    
  /////////////////////////////////////////////////////////////////////////////
    webserver.setDefaultCommand(&privateCmd);
   // webserver.addCommand("private.html", &defaultCmd);

  webserver.begin();
  /////////////////////////////////////////////////////////////////////////////
}


void STARTWEB()
{
  char clientline[BUFSIZ];
  char *filename;
  int index = 0;
  int image = 0;
  //Start Webserver with classic arduino way.......
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    index = 0;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          // are we too big for the buffer? start tossing out data
          if (index >= BUFSIZ) 
            index = BUFSIZ -1;
            
          // continue to read more data!
          continue;
        }
                clientline[index] = 0;
        filename = 0;
        
        // Print it out for debugging
        Serial.print("ELSO ELLENORZO PONT:");
        Serial.println(clientline);
        delay(100);
        if (strstr(clientline, "GET / ") != 0) {
          filename = rootFileName;
          Serial.print("MASODIK ELLENORZO PONT:");
          Serial.println(filename);
        }
        
        if (strstr(clientline, "GET /") != 0) {
        if (!filename) filename = clientline + 5; // look after the "GET /" (5 chars)
          // a little trick, look for the " HTTP/1.1" string and 
          // turn the first character of the substring into a 0 to clear it out.
          (strstr(clientline, " HTTP"))[0] = 0;
        Serial.print("HARMADIK ELLENORZO PONT:");
        Serial.println(filename);
////////////////////////////////////////////////////////////////////////
        
        if (file.open(&root, filename, O_READ)) {Serial.println("NEGYEDIK ELLENORZO PONT"); }
        
        client.println("HTTP/1.1 200 OK");
          if (strstr(filename, ".htm") != 0)
             client.println("Content-Type: text/html");
         else 
             client.println("Content-Type: text");

                  int16_t c;
          while ((c = file.read()) >= 0) {
              // uncomment the serial to debug (slow!)
              //Serial.print((char)c);
              client.print((char)c);
              Serial.println("OTODIK ELLENORZO PONT");
          }
        file.close();
 
}
    else {
          // everything else is a 404
          client.println("HTTP/1.1 404 Not Found");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<h2>File Not Found!</h2>");
         Serial.println("Nincs meg a fájl");  
         }
            break;
      }
}
    // give the web browser time to receive the data
    delay(1);
    client.stop();
  }

}

Displays the contents of the index.html file. The image is not displayed. :frowning:

        Serial.print("HARMADIK ELLENORZO PONT:");
        Serial.println(filename);

What does this cause to be displayed in the Serial Monitor?

          // a little trick, look for the " HTTP/1.1" string and 
          // turn the first character of the substring into a 0 to clear it out.
          (strstr(clientline, " HTTP"))[0] = 0;

Only when it works. If the GET request doesn't contain HTTP, then you just fucked up.

          if (strstr(filename, ".htm") != 0)
             client.println("Content-Type: text/html");
         else 
             client.println("Content-Type: text");

Really? If the client requests a .jpg file, you are going to send it back as text?

              client.print((char)c);

I've never understood why someone would cast a char as a char. Please enlighten me.

If it's a text file, this statement is fine. If it's not, then it is wrong.

Binary files are read, and sent to the client differently.

What does this cause to be displayed in the Serial Monitor?

Serialmonitor:
ELSO ELLENORZO PONT:GET / HTTP/1.1
MASODIK ELLENORZO PONT:index.htm
HARMADIK ELLENORZO PONT:index.htm
It's just control.

Really? If the client requests a .jpg file, you are going to send it back as text?

What do you need to be rewritten? Please help me.

I've never understood why someone would cast a char as a char. Please enlighten me.

If it's a text file, this statement is fine. If it's not, then it is wrong.

Binary files are read, and sent to the client differently.

Unfortunately, I can not fully understand the code. I just want to display an image in the background after authentication. :frowning:
The image size is about 20kb. That is why the sd card. Please help me :frowning: