HTTP Server running with Ethernet library =]

Hi all !

I'm actually doing some work on a new HTTP server.
I actually working on a new HTTP server for Arduino ETHERNET library.

I will include these features :

  • Parsing variables inside the URL
  • Defining client request type (GET, POST, ...)
  • Serving pages requested
  • Eventually images (shared somewhere on the net // directly included into the FLASH/EEPROM/SD
  • Reading request parameters (User-Agent ; Accept ; Accept-Language ; Accept-Encoding ; Accept-Charset ; Connection ; Cache-Control ; Authorization ; etc ...)
  • Authentication : BASIC /OR/ FORM (i'm not yet decided ... i prefer the FORM one ... but it could be good to have both)

I'm actually facing a problem on the AUTHENTICATION feature where i'm willing to read the REMOTE IP of the CLIENT CONNECTING to the HTTP SERVER.
It seems that the Arduino ETHERNET library doesn't include such code.

Does somebody knows how is it possible to do it ?

I searched a little and found some informations, but it doesn't seems to be well going.
Does the ETHERNET library had been updated since Arduino IDE 0022 ?

Thanks !

There have been lots of changes to the Ethernet library since 0022 - DHCP and DNS have been added, and some of the classes renamed so that it's easier to switch between Ethernet and WiFi shields.

But there still isn't a way to find the remote IP address. I don't think it would be really hard to add - just no-one has needed it yet. If you want to try adding it, use the latest release candidate of Arduino 1.0 - which you can get from Google Code Archive - Long-term storage for Google Code Project Hosting.

I'd suggest adding a remoteIP method to the EthernetClient class (and as a pure virtual in Client too, ideally):

virtual IPAddress remoteIP();

That would make the most sense, as it would match the one already in EthernetUDP.h. You'll have to look at the w5100 datasheet, or poke through the existing code to work out how you'd actually read the remote IP though.

Then submit a patch/pull request and we can add it to a future release of the Ethernet library :slight_smile:

Or, if none of that makes sense, submit a feature request to Google Code Archive - Long-term storage for Google Code Project Hosting. but it might be a while before I'll have enough free time to implement it :-/

Cheers,

Adrian.

If you are up to modifying the ethernet library, this is the code I use.

Add this to client.cpp. I added it just under the Client::available() function.

uint8_t Client::remoteIP(uint8_t *buf) {
  if (_sock != MAX_SOCK_NUM)
    return W5100.readSnDIPR(_sock,buf);
  return 0;
}

Add this to client.h. Again, I added it under the available() declaration.

  virtual uint8_t remoteIP(uint8_t *buf);

Then I use it like this:

byte ipBuf[4];
char outBuf[18];

client.remoteIP(ipBuf);
sprintf(outBuf,"%u.%u.%u.%u",ipBuf[0],ipBuf[1],ipBuf[2],ipBuf[3]);

I didn't know about this 1.0 version ...
It seems that the Ethernet library is improved ... but not enough for me :grin:

I hope there will be the RemoteIP included natively on the next RC (or perhaps the FINAL release) :slight_smile:

See you, thanks for the bit of code you provided SurferTim.
Finally, i think i will be using the HTTP BASIC AUTHENTICATION for my web server.
I will see the FORM AUTH later ...

By the way : Thanks for the informations !

Ok fine guys,

So i managed to build the HTTP server finely.
Actually it consumes approx. 2kB of RAM (the whole program consumes 2kB).
It can read anything coming inside a request from a client.

By the way, it actually supports these features :

  • GET / POST (i will create both way to parse the variables coming from a FORM validation)
    It will probably only support FORMs based on this ENCTYPE : "application/x-www-form-urlencoded".
    The other ENCTYPE ("multipart/form-data") is hard to include (perhaps later ...)
  • Supports AUTHENTICATION with BASIC mode and BASE64 hash (of username and password // for example : "dXNlcjpwYXNz" is for "user:pass")
  • 404 Error page (with HTTP ERROR CODE included)
  • 301 Redirection (if user only enters http:///, the HTTP server will announce to the client a 301 HTTP STATUS CODE and tell it to follow the link "http:///index.html)
  • Serving many pages from FLASH (actually working on serving the pages directly from a SD card)
  • Ability to show pages and include some variables from the Arduino memories (RAM / FLASH / other ...) on a per demand basis (for showing memoryFree(), for example, you have to include in the HTML file, on a blank line, the code -memoryFree()- which it will recognises and interprets fine then show the free RAM wherever you want on your page :slight_smile:

... more to come :wink:

Amazing... another thread with the same question.

I have replied to RogerLu a reply with a solution for what you want. There is also a thread asking for that not long ago in the forum, most likely started by RogerLu. Try giving him a shout.

It's not hard at all, the registers are there, you only need to add the right method.

Here's the thread:

http://arduino.cc/forum/index.php/topic,78209.0.html

Again, I have already looked it up for RogerLu, so it may be a nice idea to get that from him.

In fact, for now, i'm using the BASIC AUTH method for authentication.
It doesn't require the use of REMOTE IP ADDRESS and therefore, i was totally n00b when i asked the question about gathering the remote IP of the client connecting for authenticating him.

It was clearly non-sense at all !
The BASIC AUTH is actually perfect because it works perfectly and is really easy to implement.
On the other side, BASIC AUTH on a NON-SSL connection is some kind of problematic because it is possible to do "man in the middle" attacks for capturing the BASE64 hash on the packets that flows from each HTTP request of an authenticated client to the server.
When the HASH is captured, it is very easy to decode and authenticate as the originating client.

But, hey ! We can't do SSL on the arduino because it lacks CPU power (and probably RAM).
So BASIC AUTH is pretty cool for now.

I will work also on FORMs AUTH as it is pretty cool too.
But for now, i'm trying to optimize my code, and try to choose a very good way for parsing values on POST/GET requests to update the ones running in Arduino's RAM.
I saw the Webduino project at start of my coding and this project use JSON/RESTful interface which seems to be XML compatible.

See you :wink:

Ok guys, i'm back with my project ...

I let time pass since i hadn't put my hands on the arduino IDE (last time was when the 1.0 was still in beta/RC) !

I adapted my code to run on the new IDE (new libraries like Ethernet, SD and SPI), by the way, it wasn't so hard to do.
I'm actually commenting the code to (eventually) release it here for everybody to improve it :slight_smile:

Let me some days and i hope i will be able to post it !

Bye !

There was discussion below on a method to get the remote IP.

zoomkat:
There was discussion below on a method to get the remote IP.

How to obtain the remote client IP address when using the Ethernet Shield - Networking, Protocols, and Devices - Arduino Forum

Sorry i did not edit the topic subject ...

-> By the way, did you read the last message of this post ? :grin:

I did not even notice the age of my post ...

Here are the news :

  • Serves "files" directly from SD card
  • Indicates ENCTYPE, MIME TYPE, FILESIZE, etc ... before sending files to client
  • Parse any line coming from a client (and can do actions based on the values)
  • Can parse GET and POST values being sent by the client
  • Support BASIC authentication
  • Support HTTP status codes (not all, but at least, the useful ones)
  • Support "Default document" to open first (if client types http:// of HTTP SERVER)
  • Can plug/unplug/replug SD card at any time (without having to reset to whole system for the SD card to be accessible again)
  • Bandwidth on file upload is approx. 5kB/s
  • ... more to come ]:smiley:

TO DO :

  • Finalize doing actions when client validates a FORM
  • Stabilize the whole system
  • Stores website(s) configuration files directly on SD card (... not using FLASH as it gives me strange behavior sometimes)
  • Stores some configuration data inside the configuration files that could define if the website(s) needs AUTH or anything else ...
  • Enhance iPhone compatibility (perhaps Android, others mobiles platforms too)
  • AFTER ALL : create a library of this HTTP SERVER ... would be cool not to have the whole sketch full of code :slight_smile:
  • Yours suggestions ?

See you

ajax support would be nice. useful for updating the value for a few fields without refreshing the entire page.
can you elaborate on iphone compatibility? is it for things like supporting the apple-touch-icon used by safari browser client? jquery?

I imagine this would barely fit on an UNO and a mega would be required right?

Hi,

In fact, actually, the code eats 2400 bytes of RAM.
I'm clearly not a "PRO" developer for simplifying code and optimizing it.
I think it is possible to lower the RAM use with reusing some variables i'm using as buffers to temporarily cache the client request data lines and parse them.

I don't actually have time to comment the code, but soon, i will continue it and post it.

See you !