Sorry, what I am about to say may sound picky and I don't want to be disparaging, but your code has issues.
First of all. When I look at what your shield is doing in Wireshark, most of the packets are ~50 to 60 bytes. Your shield is framing data, 1 character per TCP packet, most of the time. I got a couple 118 byte packets, so it is possible for the shield to be more efficient.
Second. You are playing fast and loose with the HTTP protocol. Most modern browsers are very tolerant but some user-agents are not.
GET /index.htm HTTP/1.1
HTTP/1.1 200 OK
Issue 1. You declared a HTTP/1.1 response but this is not a HTTP/1.1 response. If it were, you would have to include
Because the user agent sent you
If you include those headers, you should not immediately close the session but rather, provide the client some time to close the connection gracefully. If the client does not close the session gracefully, you may then presume it is dead and forcibly close the session.
The behaviour of your server, closing the session immediately after servicing the request, is much closer to HTTP/1.0 So why don't you declare that ?
Issue 2. You should not be putting line breaks in your headers. Headers are name:value pairs with the syntax
There is an interesting point about protocol interpretation to be made here. From what I recall, the RFCs don't specifically say you can not put a line break in a header. They do not say you should either. By including the line break, you create an edge case
- A scenarios outside of the protocol specification.
I am impressed that you have made your server as robust as you have. If I can help you with the nuts and bolts of the protocol stuff, feel free to ask. I would not want to compare the Ethernet shield with a WiFi shield just yet though. The WiFi shield has some additional failure modes and a nasty 2 Second delay inherent in servicing the transmit buffer. 2 Seconds is an age in network terms.
The WiFi shield is not entirely without merit though. My NTP clock has been running about 2 weeks now and is happy to roam across non-overlapping access points. The WiFi shield seems perfectly suitable for blatting a few 100 bytes per minute around using UDP, as far as I can see.
Whether simplicity is it's own security is an interesting debate, verging on being a thought experiment.
On the one hand, for your simple approach, you are having to write bespoke code with, limited trial and error testing, to serve a very simple page. Your code does not conform with the protocol standard. You are almost at the limit of your resources and there may still be edge cases you have yet to come across. So yes, there is not much chance of your Arduino leaking data but there is quite a chance of it not being very robust. It is robust in the scenarios you have tested, for which I congratulate you.
On the other hand, utilising a Linux SoC provides access to Apache, lighttpd, php, perl, python and all sorts of other sophistication. Of course one does not have to use all that one could use. Stopping/uninstalling unnecessary daemons will ensure they don't get hacked. What packaged code is used, will conform to protocol specifications and is extremely well tested. Should an exploit come to light in say Apache, it will be found, patched and retested by the Apache team, very quickly.
I am not saying either way is wrong, you understand. Just you need to make a choice appropriate to the purpose. For now, I feel the the SoC route is more appropriate to my purposes.