Forum: Italian Ruby user group Heroku e CORS

Posted by Andrea Reginato (reis)
on 2013-02-13 10:19
(Received via mailing list)
Ciao a tutti,

in questi giorni sto creando un Client Javascript (in AngularJS) che va 
a
chiamare delle API REST. Per aggirare le limitazioni 'same origin 
policy'
sfrutto CORS <http://www.html5rocks.com/en/tutorials/cors/>.

In locale tutto va bene. Senza andare in dettaglio, quando viene fatta 
una
request usando CORS, prima della request vera e propria viene fatta una
request con il verbo OPTIONS per vedere se il dominio da cui parte la
request  sicuro.

Al momento le API REST girano su Heroku e mi trovo davanti ad un 
problema.
La request con il verbo OPTIONS viene fatta senza l'header 
Content-Length.
Questo fa si che Heroku mi ritorni un errore 411 (Length Required), 
perch
richiede l'header Content-Length. Per ragione di sicurezza, questo 
header
non si pu settato con Javascript.

Ora, o mi sto perdendo qualcosa (molto probabile) o mi trovo costretto 
ad
abbandonare Heroku. Ho fatto qualche ricerca, ma nessun risultato. 
Chiedo
quindi a voi se avete qualche idea a riguardo e soprattutto, nel caso in
cui non fosse risolvibile, a qualche alternativa hosting passereste.

Grazie mille
--
Andrea Reginato
Lelylan | reThink your house
http://lelylan.com
Posted by Maurizio De magnis (olistik)
on 2013-02-13 10:26
(Received via mailing list)
Ho usato questo [0] su Heroku e non ho avuto problemi.

[0] https://gist.github.com/olistik/4943295


2013/2/13 Andrea Reginato <andrea.reginato@gmail.com>
Posted by Matteo Collina (Guest)
on 2013-02-13 10:56
(Received via mailing list)
Se sicuro che il problema non parta dalla tua applicazione?
In questo esempio su stackoverflow (per node) sembra che sia possibile.
Quindi se è possibile su node, deve esserlo anche su Ruby.
Cosa usi per servire gli header CORS?
Stai usando https://github.com/cyu/rack-cors?


Il giorno 13 febbraio 2013 09:26, maurizio de magnis <
maurizio.demagnis@gmail.com> ha scritto:
Posted by Andrea Reginato (reis)
on 2013-02-13 21:10
(Received via mailing list)
Intanto grazie.

Allora, i servizi che offro si basano su
rack-cors<https://github.com/cyu/rack-cors>.


La configurazione è piuttosto semplice e per adesso abilito le richieste
che arrivano
da qualsiasi host. In locale infatti tutto funziona.

Questo è il servizio al quale voglio accedere.

     http://api.lelylan.com/devices

Se lo mettete su un browser mi restituisce un 401, il che è corretto in
quanto manca
il token di autorizzazione. Se invece provo a fare la chiamata 
attraverso
JS (Angular)
il browser, invia la request OPTION in auto e mi restituisce un 411.

    OPTIONS http://api.lelylan.com/devices 411 (Length Required)
angular.js:9120

Da quello che ho visto Heroku risponde
così<http://http-status.heroku.com/411>perchè manca l'header
Content-Length.
Quindi, non riesce manco a raggiungerla l'app.

Adesso provo a capire se è Angular a mancare qualcosa. Quello che volevo
avere era
una conferma da voi che con dei client JS riuscite a raggiungere dei
servizi esposti da
Heroku. Per caso avete del codice client di esempio?

Grazie a tutti


2013/2/13 Matteo Collina <matteo.collina@gmail.com>

> > Ho usato questo [0] su Heroku e non ho avuto problemi.
> > > chiamare delle API REST. Per aggirare le limitazioni 'same origin
> > problema.
> > > abbandonare Heroku. Ho fatto qualche ricerca, ma nessun risultato.
> > > _______________________________________________
> > _______________________________________________
> > Ml mailing list
> > Ml@lists.ruby-it.org
> > http://lists.ruby-it.org/mailman/listinfo/ml
> >
> _______________________________________________
> Ml mailing list
> Ml@lists.ruby-it.org
> http://lists.ruby-it.org/mailman/listinfo/ml
>



--
Andrea Reginato
Lelylan | reThink your house
http://lelylan.com
Posted by Maurizio De magnis (olistik)
on 2013-02-13 21:21
(Received via mailing list)
2013/2/13 Andrea Reginato <andrea.reginato@gmail.com>

> Intanto grazie.
>
> Allora, i servizi che offro si basano su
> rack-cors<https://github.com/cyu/rack-cors>.
>
>
> La configurazione è piuttosto semplice e per adesso abilito le richieste
> che arrivano
> da qualsiasi host. In locale infatti tutto funziona.
>

Intendi dire che in /etc/hosts metti:

127.0.0.1 api.lelylan.com
127.0.0.1 www.lelylan.com

e avvii le due istanze delle app ruby in localhost?

Questo è il servizio al quale voglio accedere.
> angular.js:9120
> Heroku. Per caso avete del codice client di esempio?
>

Domanda forse banale: sei sicuro che ti serva il preflight?
Se devi effettuare delle semplici GET (tramite $.ajax ad esempio) allora 
il
preflight non dovrebbe servirti [0].
Qualora il preflight dovesse comunque servirti, hai provato a testare
manualmente il funzionamento di una semplice GET Ajax?

[0]
https://developer.mozilla.org/en-US/docs/HTTP/Acce...
Posted by Andrea Reginato (reis)
on 2013-02-13 21:57
(Received via mailing list)
> Intendi dire che in /etc/hosts metti:
>
> 127.0.0.1 api.lelylan.com
> 127.0.0.1 www.lelylan.com
>
> e avvii le due istanze delle app ruby in localhost?


No. Quando accedo in localhost  tutto ok e uso indirizzi locali, mentre
http://api.lelylan.com/devices  un servizio attualmente attivo su Heroku
che si pu verificare gi ora.

Domanda forse banale: sei sicuro che ti serva il preflight?
> Se devi effettuare delle semplici GET (tramite $.ajax ad esempio) allora il
> preflight non dovrebbe servirti [0].
> Qualora il preflight dovesse comunque servirti, hai provato a testare
> manualmente il funzionamento di una semplice GET Ajax?
>

Ho provato a fare quanto dici. Ho buttato gi del codice di base per
verificare la cosa

    var invocation = new XMLHttpRequest();
    var url = 'http://api.lelylan.com/devices';
    var body = {};

    invocation.open('POST', url, true);
    invocation.setRequestHeader('Content-Type', 'application/json');
    invocation.onreadystatechange = function() { console.log('Response') 
};
    invocation.send(body);

Questo codice di esempio fa un preflight e mi ritorna un errore 411. 
Questo
errore
 dato sia da Chrome che da Firefox, mentre Safari funziona. Suppongo che 
le
implementazioni di XMLHttpRequest siano differenti e che Safari setti il
content
length durante il preflight.

--
Andrea Reginato
Lelylan | reThink your house
http://lelylan.com
Posted by Maurizio De magnis (olistik)
on 2013-02-13 22:29
(Received via mailing list)
Ho la sensazione che sia proprio un problema di impostazioni del web
server.. qui [0] hanno risolto catchando direttamente su nginx le 
richieste
e restituendo a prescindere un 200.
Non e' il massimo pero', e nel caso di Heroku mi pare impraticabile.

Curiosita' 1: con le chiamate GET semplici non ti viene generato un
preflight, e' corretto?

Curiosita' 2:

Per ragione di sicurezza, questo header non si può settato con 
Javascript.


come mai?

[0]
http://stackoverflow.com/questions/13251926/cors-o...


2013/2/13 Andrea Reginato <andrea.reginato@gmail.com>
Posted by francesco agati (francescoagati)
on 2013-02-13 23:13
(Received via mailing list)
Non centra molto ma guarda la libreria easyxdm per fare cors con gli 
iframe
e il crossdomain
Il giorno 13/feb/2013 10:18, "Andrea Reginato" 
<andrea.reginato@gmail.com>
ha scritto:
Posted by Matteo Collina (Guest)
on 2013-02-13 23:51
(Received via mailing list)
Temo di aver trovato il problema:  la tua app che non ritorna
content-length.
Verifica dal log se viene chiamata realmente, dovrebbe, e non credo
inserisca l'header Content-Length.

Verificando via curl:
$ curl -v -X OPTIONS
http://api.lelylan.com/devices/50c61ff1d033a9b610000001
* About to connect() to api.lelylan.com port 80 (#0)
*   Trying 107.21.95.3...
* connected
* Connected to api.lelylan.com (107.21.95.3) port 80 (#0)
> OPTIONS /devices/50c61ff1d033a9b610000001 HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0
OpenSSL/0.9.8r zlib/1.2.5
> Host: api.lelylan.com
> Accept: */*
>
< HTTP/1.1 411 Length Required
< Server: nginx
< Date: Wed, 13 Feb 2013 22:40:56 GMT
< Content-Type: text/html
< Content-Length: 174
< Connection: Keep-Alive
<
<html>
<head><title>411 Length Required</title></head>
<body bgcolor="white">
<center><h1>411 Length Required</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host api.lelylan.com left intact
* Closing connection #0

Facendo invece la stessa chiamata ad un'altra app:

$ curl -v -X OPTIONS http://www.matteocollina.com

* About to connect() to www.matteocollina.com port 80 (#0)
*   Trying 23.23.113.171...
* connected
* Connected to www.matteocollina.com (23.23.113.171) port 80 (#0)
> OPTIONS / HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0
OpenSSL/0.9.8r zlib/1.2.5
> Host: www.matteocollina.com
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Content-Type: text/plain
< Date: Wed, 13 Feb 2013 22:46:21 GMT
< X-Powered-By: Express
< Content-Length: 16
< Connection: Keep-Alive
<
* Connection #0 to host www.matteocollina.com left intact
Cannot OPTIONS /* Closing connection #0


Il giorno 13 febbraio 2013 22:13, francesco agati <
francescoagati1975@gmail.com> ha scritto:
Posted by Matteo Collina (Guest)
on 2013-02-14 00:14
(Received via mailing list)
Quello che mi suona strano  che ci sia nginx di mezzo, eppure tu ce 
l'hai.
Vedi:

$ curl -v http://api.lelylan.com
* About to connect() to api.lelylan.com port 80 (#0)
*   Trying 107.21.95.3...
* connected
* Connected to api.lelylan.com (107.21.95.3) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0
OpenSSL/0.9.8r zlib/1.2.5
> Host: api.lelylan.com
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Server: nginx
< Date: Wed, 13 Feb 2013 23:10:34 GMT
< Content-Type: application/json; charset=utf-8< Status: 401 
Unauthorized
< X-Request-Id: fe615e06e88c8cae761407fabad42244
< X-Runtime: 0.127109
< X-Rack-Cache: miss
< Cache-Control: no-cache, proxy-revalidate
< Transfer-Encoding: chunked
< Connection: Keep-Alive
<
* Connection #0 to host api.lelylan.com left intact

Usi per caso un buildpack strano? Sei su bamboo?


Il giorno 13 febbraio 2013 22:50, Matteo Collina
<matteo.collina@gmail.com>ha scritto:
Posted by Andrea Reginato (reis)
on 2013-02-14 11:30
(Received via mailing list)
@Matteo

Al momento uso Stack Cedar sia sul proxy fatto con Node.js 
(api.lelylan.com)
che sul
servizio vero e proprio fatto con Rails (devices.lelylan.com). Da come 
si
pu vedere
dalle requests ritorna nginx come server (tutti e due). Non  normale? 
Non
sei il primo
che mi pone questa domanda.

Ho fatto qualche test in pi ed in qualche modo la cosa si sta chiarendo.
Se faccio le mie
calls alle API fatte con Rails (devices.lelylan.com) tutto funziona 
bene. I
problemi ci sono
nel momento in cui passo per il Proxy fatto con Node
Proxy<https://github.com/nodejitsu/node-http-proxy>
 (api.lelylan.com), quindi il
problema si sposta.

Grazie per avermi ricordato che c'ho un proxy :)

@Maurizio

Si, quel link l'avevo visto e non mi faceva sperare bene.

@Francesco

Adesso me la guardo.


2013/2/14 Matteo Collina <matteo.collina@gmail.com>

> OpenSSL/0.9.8r zlib/1.2.5
> < Cache-Control: no-cache, proxy-revalidate
>
> > *   Trying 107.21.95.3...
> > < Date: Wed, 13 Feb 2013 22:40:56 GMT
> > </html>
> > * Connected to www.matteocollina.com (23.23.113.171) port 80 (#0)
> > < Content-Length: 16
> iframe
> >> a
> >> >
> >> > Ora, o mi sto perdendo qualcosa (molto probabile) o mi trovo costretto
> >> > Lelylan | reThink your house
> >>
> >
> >
> _______________________________________________
> Ml mailing list
> Ml@lists.ruby-it.org
> http://lists.ruby-it.org/mailman/listinfo/ml
>



--
Andrea Reginato
Lelylan | reThink your house
http://lelylan.com
Posted by Matteo Collina (Guest)
on 2013-02-14 11:33
(Received via mailing list)
Il giorno 14 febbraio 2013 10:29, Andrea Reginato 
<andrea.reginato@gmail.com
> ha scritto:

>
Secondo me no.

Ho fatto qualche test in pi ed in qualche modo la cosa si sta chiarendo.
> Se faccio le mie
> calls alle API fatte con Rails (devices.lelylan.com) tutto funziona bene.
> I
> problemi ci sono
> nel momento in cui passo per il Proxy fatto con Node
> Proxy<https://github.com/nodejitsu/node-http-proxy>
>  (api.lelylan.com), quindi il
> problema si sposta.
>

Lo uso anche io e non mi ha mai dato problemi :(,
per non l'ho mai usato per CORS.
Prova a fare lo stesso setup in locale e vedi se ti d gli stessi 
problemi.

Grazie per avermi ricordato che c'ho un proxy :)
>

mannaggia!
Posted by Andrea Reginato (reis)
on 2013-02-14 11:36
(Received via mailing list)
>
>  Nginx. Non  normale? Non sei il primo che mi pone questa domanda.
>
> Secondo me no.


Why not?


> Lo uso anche io e non mi ha mai dato problemi :(,
> per non l'ho mai usato per CORS.
> Prova a fare lo stesso setup in locale e vedi se ti d gli stessi problemi.


In locale funziona tutto bene. In produzione pure funziona bene. Mi da
problemi solo
con CORS per adesso.

--
Andrea Reginato
Lelylan | reThink your house
http://lelylan.com
Posted by Matteo Collina (Guest)
on 2013-02-14 12:22
(Received via mailing list)
Il giorno 14 febbraio 2013 10:36, Andrea Reginato 
<andrea.reginato@gmail.com
> ha scritto:

> >
> >  Nginx. Non  normale? Non sei il primo che mi pone questa domanda.
> >
> > Secondo me no.
>
>
> Why not?


https://devcenter.heroku.com/articles/http-routing
Citando testualmente:
"Since requests to Cedar apps are made directly to the application 
server
*not proxied through an HTTP server like nginx*  any compression of
responses must be done within your application."


> > Lo uso anche io e non mi ha mai dato problemi :(,
> > per non l'ho mai usato per CORS.
> > Prova a fare lo stesso setup in locale e vedi se ti d gli stessi
> problemi.
>
>
> In locale funziona tutto bene. In produzione pure funziona bene. Mi da
> problemi solo
> con CORS per adesso.


Ho un node-http-proxy in produzione anche io, eccoti una traccia HTTP.
Sembra che per OPTIONS non trasmetta Content-Length, come in generale
per tutte le risposte "a body vuoto".
E' un bug suo.

Esempio dalla  ia macchina linode (con node-http-proxy):

$ curl -v -X OPTIONS http://qest.me
* About to connect() to qest.me port 80 (#0)
*   Trying 176.58.120.151...
* connected
* Connected to qest.me (176.58.120.151) port 80 (#0)
> OPTIONS / HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0
OpenSSL/0.9.8r zlib/1.2.5
> Host: qest.me
> Accept: */*
>
< HTTP/1.1 404 Not Found
< x-powered-by: Express
< content-type: text/plain
< set-cookie:
connect.sid=s%3ATqy8Wh9Q%2Fdgd49Oq%2FhluH8PM.1vdcbjqo7%2BXlLBy%2BrRoQmzWTSSHQH6BE%2FJsAEXORtjs;
Path=/; HttpOnly
< date: Thu, 14 Feb 2013 11:15:39 GMT
< connection: close
< transfer-encoding: chunked
<
* Closing connection #0
Posted by Andrea Reginato (reis)
on 2013-02-14 12:43
(Received via mailing list)
Thanks for the links. Alla fine ho fatto un fork al volo e fatto una
patch<https://github.com/andreareginato/node-http-proxy/...
Node Proxy
e adesso tutto funziona bene. Ho forzato il setting dell'header
Content-Length quando
le request sono fatte con il verbo OPTIONS. Quando ho un attimo la 
sistemo
un p e
faccio una pull request.

Per quanto riguarda il discorso nginx, no idea for now.

Grazie mille dell'aiuto :)


On Thu, Feb 14, 2013 at 12:21 PM, Matteo Collina
<matteo.collina@gmail.com>wrote:

> > Why not?
> > > per non l'ho mai usato per CORS.
> Sembra che per OPTIONS non trasmetta Content-Length, come in generale
> > OPTIONS / HTTP/1.1
> 
connect.sid=s%3ATqy8Wh9Q%2Fdgd49Oq%2FhluH8PM.1vdcbjqo7%2BXlLBy%2BrRoQmzWTSSHQH6BE%2FJsAEXORtjs;
>
--
Andrea Reginato
Lelylan | reThink your house
http://lelylan.com
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.