31 agosto 2016

Un pranzo e dei buoni commensali

Sono questi gli ingredienti che mi danno gioia e mi fanno sentire vivo, felice di essere in mezzo alle persone e lontano dalla gente. Raccontare cose senza senso mettendo nella condivisione del punto di vista il significato, scherzare su un mondo buffo come se non ci fosse quello amaro e poi con quel sorriso ancora impressi affrontare il lato brutto delle cose. Passare del tempo consapevolmente, invece che semplicemente invecchiare inconsapevoli, creare ponti e contatti, mescolare storie, attraversare incroci improbabili.
Guardare video stupidi alla televisione o parlare di zingari e razzismo. Scontrarsi per rimbalzare, scontrarsi per incontrarsi.
Selezionare i raccontastorie ma non la sceneggiatura, cambiare registro e mescolare le carte in tavola, Lasciarsi stupire dal diverso senza temerlo, spendere del tempo con grandi e bambini come se, per pochi attimi, fossero tutti membri alla pari della stessa tribù.

Mi piace preparare i momenti e poi non governarli, mi piace seguire il flusso di una buona situazione, mi piace sentirmi a mio agio nel poter dire le mia e anche nel non dirla. Mi piace quando un errore diventa uno scherzo, mi piace quando si può andare due parole troppo in là e poi recuperare. Mi piace anche non sapere dov'è il troppo ed esplorarsi sino a scoprirlo. Non sono mai stato buono a stare fra la gente, ma mi piace stare con le persone, mi piace quando pensano cose che io non penso, mi piace anche quando mi dà fastidio quello che pensano ma lo vivono in modo organico. Mi piace non sapere cosa aspettarmi e mi piace immaginare cosa pensano gli altri e vedere se indovino. Mi piace giocare a leggere le persone che conosci e anche quelle che non conosci. Mi piace ricredermi.

Mi piace farlo mangiando assieme, condividendo uno dei principali momenti animali. Mi piace parlare con le teste umane e condividere con loro gesti animali. Mi piace ricordarmi che non sono che una scimmia poco pelosa. Mi piace vedere chi si atteggia a non esserlo.

Mi piace ripensarci quando è finita, rielaborare le voci e rivivere i momenti. Mi piace poi stare per i cazzi miei o ridurre il contesto a pochissimi intimi, o anche no...
Ho bisogno anche di un circolo ristretto, ma amo allargarlo per qualche ora ed espandermi io stesso con esso, purché non si allarghi troppo, perché fra la gente mi perdo e non sto bene.

Questo mi serve per vivere bene, in prima istanza.

...e sì, anche del buon vino.
Read more

30 agosto 2016

CORS, apache e jQuery, ovvero "il triangolo di ajax"

Cosa sono le chiamate CORS? 

Le chiamate CORS (cross-origin HTTP request) sono da sempre una bestia nera di cui il programmatore medio del web sa poco o niente.
Nella sostanza si classificano come chiamate CORS tutte le chiamate a servizi che risiedono su un dominio differente da quello della pagina che origina la chiamata.

Se dalla splendida homepage del mio sito:
http://miosito.mio/index.html
voglio chiamare un servizio sul server del mio amico all'indirizzo:
http://serverdelmioamico.suo/servizio.php

La chiamata tipica ad un servizio tramite ajax con jQuery è:
  $.ajax("http://serverdelmioamico.suo/servizio.php",
    {data:jsondidati,
     success:function(data){ //qualcosa col risultato}
  });

questa chiamata ricade nella categoria CORS.
Cosa significa? Che il browser la effettua, la chiamata arriva al server che la elabora e invia la risposta, il browser riceve la risposta e....la scarta.
Perché? Perché di default le chiamate CORS sono disabilitate dal browser e dal server, per motivi di sicurezza.


Come si abilitano le chiamate CORS?

Servono 2 interventi, uno sul client e uno sul server. Il client deve dichiarare di fare una CORS, il server deve acconsentire al client dicendo esplicitamente che acconsente alla richiesta.
Spezziamo quindi l'intervento in 2 parti.

Abilitazione sul client (jQuery)

Il client aggiunge un parametro che consente a jQuery la corretta gestione della chiamata, in termini di header inviati e gestione della risposta. La chiamata usata sopra a titolo d'esempio, diventa:

  $.ajax("http://serverdelmioamico.suo/servizio.php",
    {data:jsondidati,
     success:function(data){ //qualcosa col risultato},
     xhrFields: {withCredentials: true }
  });

Perché questo funzioni è opportuno usare almeno la versione 1.5.2 di jQuery, cosa che, di questi tempi, è assai probabile, ma in caso di vecchio codice da estendere potrebbe non essere scontato.

Abilitazione sul server (Apache)

Prima di tutto è indispensabile abilitare il modulo headers di apache (a2enmod headers su debian e ubuntu).
A questo punto la via semplice, se tutto funziona, è aggiungere un header sul server. Assumendo che si tratti di apache 2.4, l'operazione è piuttosto facile. Nel VirtualHost, o nel file ".htaccess" basta aggiungere la riga:

Header set Access-Control-Allow-Headers "*"

I dettagli sono qui (http://httpd.apache.org/docs/current/mod/mod_headers.html)*.
Nella sostanza questa riga imposta all'header della risposta una informazione che dice: non importa chi mi chiama, a me va bene comunque, browser caro, mostra pure la risposta.

Questa operazione apre il servizio a tutti i chiamanti, senza restrizioni. Per fare in modo che le chiamate siano limitate a quelle provenienti da pagine del server "http://miosito.mio/", la riga dovrà essere:
Header set Access-Control-Allow-Headers "http://miosito.mio/"

Giusto per stare sicuri si possono aggiungere queste 2 righe

Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

Che dovrebbero essere autoesplicative, ma nel dubbio dicono che si permette l'accesso se la chiamata arriva con uno degli header e uno dei metodi elencati fra virgolette.

Purtroppo l'intreccio delle regole di chiamata fa si che questa base non sia sufficiente se vogliamo che il chiamante non sia limitato ad una sola origine (cioè se siamo nel caso in cui ci serve "*" invece di un nome server specifico).
La richiesta withCredentials infatti richiede che Access-Control-Allow-Headers abbia come valore il server d'origine e non un wildchar ("*"), ma togliendola il server non manda l'header per abilitare la CORS.
Quindi serve un piccolo sforzo in più lato server, una volta per tutte.
Il server deve leggere il,l'origine del chiamante (comprensivo di protocollo e porta) e usarlo per impostare l'header di risposta.
Questa operazione, apparentemente ardua, si risolve in realtà con uno sforzo piuttosto piccolo (a sapere come), basta tramutare la nostra riga in:

SetEnvIfNoCase Origin "https?://(www\.)?(.*)(:\d+)?$" ACAO=$0
Header set Access-Control-Allow-Origin %{ACAO}e env=ACAO

Questa diavoleria legge l'header Origin, controlla se ha l'aspetto indicato (che poi è qualunque cosa inizzi con http:// o https:// e mette il valore in una variabile (ACAO, visto l'amore degli informatici per gli acronimi).
L'header a questo punto viene impostato con il valore della variabile ACAO, che poi è quello dell'origine.

Giusto per stare sul sicuro si può aggiungere

Header set Vary Origin

agli header restituiti, che serve a gestire alcune situazioni piuttosto particolari, ma visto che male non ne fa, tanto vale averlo.

Il blocco complessivo diventa:

SetEnvIfNoCase Origin "http(s)?://(www\.)?(.*)(:\d+)?$" ACAO=$0
Header set Access-Control-Allow-Origin %{ACAO}e env=ACAO
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
Header set Vary Origin


Ultima nota: se si vuole aprire ad una serie di server e non a tutti, la riga del SetEnvIfNoCase deve essere modificata di conseguenza. Per fare un breve esempio, se vogliamo che a chiamare possa essere miosito.mio con tutti i suoi domini di terzo livello (es: test.miosito.mio, prova.miosito.mio, blog.miosito.mio, ...) e serverdimiocugino.suo con i suoi domini di terzo livello, la riga diventerà:

SetEnvIfNoCase Origin "http(s)?://(.*\.)?(miosito\.mio|serverdimiocugino\.suo)(:\d+)?$" ACAO=$0

Si tratta (come l'altra, del resto) di una espressione regolare, che si legge più o meno così:
http con o senza "s" seguito da "://", eventualmente qualcosa, ma se c'è deve essere seguita da un ".", (come potrebbe essere "www.", "test." o altro) seguito da miosito.mio oppure serverdimiocugino.suo, seguito eventualmente da un ":" e dei numeri (indicazione della porta).


* Una piccola nota a riguardo per chi giustamente ha scelto di saltare il manuale: "Header set" imposta un header, mentre "Header add" lo aggiunge. Ai nostri fini la differenza è probabilmente nulla, ma i problemi sorgono quando da codice viene già impostato l'header in questione. Nel caso di "add" l'header viene raddoppiato (e alcuni client un po' permalosi non la prendono bene, specie se non hanno lo stesso valore), mentre "set" sovrascrive il valore. Esistono anche "setifempty", che imposta il valore solo se non era già presente e "merge" che prova ad estendere una lista di valori per gli header a valore multiplo.
La realtà è che manipolare gli stessi header a livello di codice di servizio e di configurazione del web server può portare a una serie di situazioni impreviste e richiede un coordinamento che difficilmente si mantiene nel tempo. Sarebbe buona norma quindi decidere a priori quali header siano da impostare a livello di apache e quali a codice, evitando sovrapposizioni, dove non sia strettamente necessario.
Read more

25 agosto 2016

No One Wished To Settle Here

Oggi mi piace pensare che il qui di cui si parla non sia un luogo fisico, bensì concettuale.
In particolare un "qui" artistico, come metafora di un qui dell'anima, troppo astratto per essere identificato.



Ogni volta che ascolto questo brano, mi si illumina dentro qualcosa, entro in risonanza col lo straziante disagio che esprime questo pezzo e, oggetto di una catarsi inevitabile, mi elevo di un gradino, vedendo come tante cose che normalmente trovo molto belle siano in realtà poca cosa a confronto con certe pietre miliari. Mi ritrovo sulla torre d'avvistamento di un muro di confine.
Fuori l'ignoto, dove vanno gli avanguardisti, gli avventurieri, ma anche alcuni disadattati o reietti a modo loro illuminati.
Dentro i territori conosciuti e colonizzati, ricchi di agi, dove le sfide sono mitigate da un contesto accogliente quanto ovattante.
La zona di confine è un luogo particolare, perché da lì si può osservare il selvaggio mondo inesplorato, restando riconoscibili e a contatto con chi vive entro i confini.

Nessuno ha voluto insediarsi qui, sui territori di confine.

inconsistenti miraggi.
Inizia quindi per i grandi, quelli veri un percorso che va oltre la frontiera e li porta in territori inospitali, da cui magari torneranno, ma saranno così cambiati da non essere più quelli che erano arrivati alla grandezza comunicabile. In genere quando tornano sono dei "selvaggi" che hanno scelto di tornare all'agio, ma ci staranno per sempre stretti, ma accettano di restare delle copie sbiadite di loro stessi, in cambio della quiete dei luoghi noti.

Alcuni ci arrivano con uno sforzo incredibile, una volta nella vita, e non sono in grado di restare lì, ma non perché non possano, bensì perché non vogliono sostenere l'immenso sforzo dell'anima che è partorire un'opera immortale, restare sempre con un occhio sulla vastità oltre il confine senza attraversarlo.
Si ritirano, allora, in territori meno gloriosi, illuminati comunque dalla grandezza a cui sono giunti almeno una volta nella vita e contemporaneamente sollevati dal peso che deriva dalla creazione di capolavori unici.

Nessuno vuole insediarsi qui, in questa landa di confine.
Nessuno l'ha voluto fare.
Il confine estremo non è un luogo dove insediarsi: o si va oltre in un viaggio d'esplorazione in cui ci si potrebbe anche smarrire o si torna indietro.

No One Wished To Settle Here.

Read more