Heroku e CORS

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 R.
Lelylan | reThink your house
http://lelylan.com

Ho usato questo [0] su Heroku e non ho avuto problemi.

[0] Handle CORS with Rails · GitHub

2013/2/13 Andrea R. [email protected]

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 GitHub - cyu/rack-cors: Rack Middleware for handling Cross-Origin Resource Sharing (CORS), which makes cross-origin AJAX possible.?

Il giorno 13 febbraio 2013 09:26, maurizio de magnis <
[email protected]> ha scritto:

2013/2/13 Andrea R. [email protected]

Intanto grazie.

Allora, i servizi che offro si basano su
rack-corshttps://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]

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 R.
Lelylan | reThink your house
http://lelylan.com

Intanto grazie.

Allora, i servizi che offro si basano su
rack-corshttps://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/411perchè 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 C. [email protected]

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
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Andrea R.
Lelylan | reThink your house
http://lelylan.com

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]

2013/2/13 Andrea R. [email protected]

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 R.”
[email protected]
ha scritto:

Quello che mi suona strano che ci sia nginx di mezzo, eppure tu ce
l’hai.
Vedi:

$ curl -v http://api.lelylan.com

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
<

Usi per caso un buildpack strano? Sei su bamboo?

Il giorno 13 febbraio 2013 22:50, Matteo C.
[email protected]ha scritto:

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

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
<

411 Length Required

411 Length Required


nginx * 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

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
<

Il giorno 13 febbraio 2013 22:13, francesco agati <
[email protected]> ha scritto:

@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
Proxyhttps://github.com/nodejitsu/node-http-proxy
(api.lelylan.com), quindi il
problema si sposta.

Grazie per avermi ricordato che c’ho un proxy :slight_smile:

@Maurizio

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

@Francesco

Adesso me la guardo.

2013/2/14 Matteo C. [email protected]

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
* 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
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Andrea R.
Lelylan | reThink your house
http://lelylan.com

Il giorno 14 febbraio 2013 10:29, Andrea R.
<[email protected]

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
Proxyhttps://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 :slight_smile:

mannaggia!

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 R.
Lelylan | reThink your house
http://lelylan.com

Thanks for the links. Alla fine ho fatto un fork al volo e fatto una
patchhttps://github.com/andreareginato/node-http-proxy/commit/8d3c9a7d2d60f2b6f3821a6f619889531de63173su
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 :slight_smile:

On Thu, Feb 14, 2013 at 12:21 PM, Matteo C.
[email protected]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 R.
Lelylan | reThink your house
http://lelylan.com

Il giorno 14 febbraio 2013 10:36, Andrea R.
<[email protected]

ha scritto:

Nginx. Non normale? Non sei il primo che mi pone questa domanda.

Secondo me no.

Why not?

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