Domande da principiante per iniziare ad usare WiFi/Ethernet shield

ciao a tutti
da qualche giorno ho tra le mani una WiFi shield, ho già fatto l'aggiornamento del firmware per l'IDE 1.0.5 e provando gli esempi funziona..
al momento non ho alcun progetto in mente ma mi piacerebbe impare ad usarla bene, l'ho presa un po' come quando ho preso il primo arduino un paio di anni fà, avevo solo idea di cosa fosse, ma non avevo idea di cosa potevo farci :slight_smile:

la mia idea sarebbe quella di comunicare con qualche social network ma è da vedere la fattibilità.. negli ultimi giorni ho letto un bel po' di topic nel forum italiano e non a riguardo, quello che ho capito è che mi mancano un po' le competenze riguardo la struttura delle reti e dei sistemi di comunicazione... poi ho visto che molti social network per chiamare le api usano l'HTTPS che però non è supportato da arduino e per cui bisognerebbe ricorrere ad altri supporti...

ma partendo dall'inizio, il processo di connessione al WiFi è sempre quello e l'ho capito, quello che non capisco è il funzionamento delle richieste HTTP, ho provato l'esempio WiFiWebClient che mi scarica tutto il codice HTML della pagina di google che cerca "arduino", ma se io non volessi accedere a google ma ad una qualsiasi pagina web come dovrei fare? per esempio se io volessi accedere alla mia pagina facebook devo per forza passare per le api?
chiaro che se non passo per le api e se cambiano la grafica del sito poi mi perdo nella pagina, però intanto per provare va bene :slight_smile:

per il momento mi piacerebbe capire questo, poi vediamo se riesco a fare progressi :wink:
grazie in anticipo!

se io volessi accedere alla mia pagina facebook devo per forza passare per le api?

no, ma se ti sgamano ti bannao l'account. Quindi sì. :grin:

se cambiano la grafica

no, se cambiano i nomi dei form html. Le api non cambiano mai.

In oltre sicuramente per le ichieste http usano HTTPS (quel s sta per over SSH), protocollo che non credo sia implementabile sulla UNO, o almenbo non l'ho mai visto. La stessa cosa probabilmente vale per le API. In pratica sei fregato in partenza, se non usi un pc/altro che fa da ponte

lesto:

se io volessi accedere alla mia pagina facebook devo per forza passare per le api?

no, ma se ti sgamano ti bannao l'account. Quindi sì. :grin:

ma se per esempio io voglio solo vedere quanti "likes" ho sulla mia pagina facebook o quanti followers ho su twitter posso farlo anche senza fare il login, come ho scaricato tutto il codice HTML della pagina di google non posso farlo anche su una pagina qualsiasi?
grazie

sì esattamente. da HTTP - Wikipedia

per richiedere la pagina index.html nella root del server www.example.com, ti conneccti via TCP alla porta 80 o 8080 o 8000 di www.example.com e mandi la richiesta get

GET /index.html HTTP/1.0
Host: www.example.com

seguita da 2 a capo. (oltre ad Host ci possono essere altri header, vedi il link e cerca su google quello che ti interessa, anche intercettare le get dei browser è interessante)

poi a quel punto il server risponde con l'header di risposta, 2 a capo, l'html della pagina, ed infine chiude la connessione (se HTTP/1.0) o resta in attesa della prossima get (se HTTP/1.1)

esempio di risposta:

HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Etag: "3f80f-1b6-3e1cb03b"
Content-Type: text/html; charset=UTF-8
Content-Length: 131
Connection: close

<html>
<head>
  <title>An Example Page</title>
</head>
<body>
  Hello World, this is a very simple HTML document.
</body>
</html>

Bello :slight_smile: Grazie mille della risposta! Appena possibile provo! :wink:

ok provando con facebook questo codice:

#include <SPI.h>
#include <WiFi.h>

char ssid[] = "Alice-54464281";
char pass[] = "xxxxxxx";
int keyIndex = 0;           

int status = WL_IDLE_STATUS;

char server[] = "www.facebook.com";    // name address for Google (using DNS)

WiFiClient client;

void setup() {
  Serial.begin(9600);
  while(Serial.available()==0){}
  while (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    delay(1000);
  } 
  
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
   status = WiFi.begin(ssid, pass);
     delay(10000);
  } 
  Serial.println("Connected to wifi");
  printWifiStatus();
  
  Serial.println("\nStarting connection to server...");

  if (client.connect(server, 80)) {
    Serial.println("connected to server");

    client.println("GET /vicenza.thunders HTTP/1.0");
    client.println("Host: www.facebook.com");
    client.println("Connection: close");
    client.println();
  }
}

void loop() {
  while (client.available()) {
    char c = client.read();
    Serial.write(c);
    if(c=='>'|| c==';')
    Serial.println("");
  }

  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting from server.");
    client.stop();

    while(true);
  }
}


void printWifiStatus() {
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

mi risponde male dicendo che i P3P non sono supportati (non ho idea di cosa voglia dire :roll_eyes: )

Attempting to connect to SSID: Alice-54464281
Connected to wifi
SSID: Alice-54464281
IP Address: 192.168.1.14
signal strength (RSSI):-78 dBm

Starting connection to server...
connected to server
HTTP/1.0 302 Found
Location: http://www.facebook.com/unsupportedbrowser
P3P: CP="Facebook does not have a P3P policy. Learn why here: http://fb.me/p3p"
X-Content-Type-Options: nosniff
Set-Cookie: datr=UQPXUWBwrmKBwA1VCCIkvGvm;
 expires=Sun, 05-Jul-2015 17:33:05 GMT;
 path=/;
 domain=.facebook.com;
 httponly
Content-Type: text/html;
 charset=utf-8
X-FB-Debug: M/qRpghwpXOBpepnxcIwKlRa7yDHHsP/u5/pu4HJtzY=
Date: Fri, 05 Jul 2013 17:33:05 GMT
Connection: close
Content-Length: 0


disconnecting from server.

quindi devo arrendermi a cercare di usare le api? :cold_sweat:

[EDIT] Cancellato password dal sketch. Ciao Uwe[/EDIT]

sto notando che su buona parte dei social network questo metodo non funziona, su instagram e twitter mi viene l'errore "301 Moved Permanently" e su facebook quello che ho scritto prima... non so se sbaglio io qualcosa, magari il nome del server :roll_eyes: o se effettivamente non posso accedere a quelle pagine, il fatto che sono in HTTPS comporta che non posso accedervi?
con youtube che non è in HTTPS va, ma anche instagram non è HTTPS eppure non ci entro...

mi sa che mi tocca fare come si fa con la libreria twitter, cioè abilitare una applicazione sul mio twitter ed ottenere un token e con quello si possono fare un po' di cose.. visto che le api sono inacessibili usando solo arduino per via dell'HTTPS

anche se le pagine sono fornite in HTTP, TUTTE le autenticazoni sono eseguite via HTTPS.

BTW la risposta che ottieni è perchè l'header che fornisci è troopo scarno (se vedi gli header della risposta da qualche parte ho visto "unsupported browser")

un sito che mostra i tuoi header: http://www.lammertbies.nl/comm/info/browser-header-checker.html

ti posto i miei, per compararli:

Host www.lammertbies.nl
User-Agent Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language en-US,en;q=0.5
Accept-Encoding gzip, deflate
Connection keep-alive

per il resto wikipedia, List of HTTP header fields - Wikipedia

scusa l'ulteriore domanda, ma le mie conoscienze in questo campo sono molto limitate, come faccio a cambiare l'header?

intendi del tuo browser? con dei plugin.

Intendi con arduno? li aggiungi!
host:blabla.com
è un header, e come vedi gli header che ti ho postato sono esattamente come spediti, puoi farne copia incolla :slight_smile:

se non sei convinto, wireshark e passa la paura!!

sto provando così:

if (client.connect(server, 80)) {
Serial.println("connected to server");

client.println("GET /vicenza.thunders HTTP/1.0");
client.println("Host: www.facebook.com");
client.println("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36");
client.print("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/"); client.println(";q=0.8");
client.println("Accept-Language: en-US,en;q=0.8");
client.println("Accept-Encoding: gzip,deflate,sdch");

client.println("Connection: close");
client.println();
}

ma non ricevo risposta, cosa sto sbagliando? :roll_eyes:

2 "a capo" alla fine, quindi serve un altro client.println();

ancora niente :disappointed_relieved:

X iscrizione

ho fatto copia incolla sdel tuo codice da telenet e la risposta del server arriva:

HTTP/1.0 301 Moved Permanently
Cache-Control: private, no-cache, no-store, must-revalidate
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Location: https://www.facebook.com/vicenza.thunders
P3P: CP="Facebook does not have a P3P policy. Learn why here: http://fb.me/p3p"
Pragma: no-cache
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 0
Set-Cookie: datr=3J3YUcrWeFkCqdw9vp-hUtZ9; expires=Mon, 06-Jul-2015 22:44:44 GMT
; path=/; domain=.facebook.com; httponly
Content-Type: text/html; charset=utf-8
X-FB-Debug: sWR59dYDp7tZZ6ehjnkyMhzOkf5gtDR8BhsB5Co5miU=
Date: Sat, 06 Jul 2013 22:44:44 GMT
Connection: close
Content-Length: 0

immagino sia identica alla risposta che ottieni (anceh se SEMBRA che tu non ottenga nulla... assai strano direi)
partiamo dalla prima riga:

HTTP/1.0 301 Moved Permanently

urca, la pagina non è quì, è stata spostata!

Location: https://www.facebook.com/vicenza.thunders

ed ecco dove: httpS, ovvero DEVI usare l'https.

facendo delle prove ho scoperto che risponde mettendo solo una opzione nella stringa degli User-Agent
la risposta che ottengo è quella che ottieni anche te, ma se scrivo HTTPS mi da l'errore 400 bad request

al momento il mio codice è così:

client.println("GET /vicenza.thunders HTTPS/1.0");
client.println("Host: www.facebook.com");
client.println("User-Agent: Mozilla/5.0");
client.print("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/");client.println(";q=0.8");
client.println("Accept-Language: en-US,en;q=0.8");
client.println("Accept-Encoding: gzip,deflate,sdch");
client.println("Connection: keep-alive");
client.println();

Mi dispiace non essere a casa per fare delle prove.
Leo non ho capito una cosa, ma i siti HTTPS quindi secondo te possono essere almeno letti ma non interrogati ?
Consiglio gare prove con google.com che risponde sia a http che ad HTTPS. Nel primo caso via Arduino si può sia leggere la pagina sia fare una query e ricevere risposta, mentre usando HTTPS si potrà solo leggere la pagina ? Per capirci potrò su HTTPS capite che doodle sta usando perché il nome del doodle è in chiaro ?

ma se scrivo HTTPS mi da l'errore 400 bad request

eccerto! il protocollo di comunicazione è sempre in HTTP, solo che il layer sottostante anzichè essere direttamente in TCP, è su un layer SSL che fornisce la critazione.
Quindi i comandi NON cambiano, solo sono criptati prima di essere inviati.

Leo non ho capito una cosa, ma i siti HTTPS quindi secondo te possono essere almeno letti ma non interrogati ?

no, sia richiesta che risposta sono via HTTPS, poi alcuni siti fanno il login in HTTPS e poi rispediscono su HTTP, ma stanno scomparendo.

il problema è con l'HTTP per un eventuiale Man-In-The-Middle, lo spoof della sessione è una baggianata. Mi direte che è quasi impossibile beccare una persona, ma se stai spoofando in modo automatico le utenze a siti molto usati come twitter e simila, magari attraverso un router wifi senza password strategicamente piazzato vicino alla finestra che da sulla piazza...

E quindi come si fa a leggere delle pagine in https?

non con arduino, almeno fuichè primanon troviun modo per fargli criptare tutto in SSL, e ionon ho mai rtovato nulla (è molto pesante come algoritmo..)