Raggiungibile con tono libero: verifica automatica di un’utenza mobile

Analizzando uno scenario applicativo reale, è possibile incontrare tra le specifiche una esigenza di dover automaticamente telefonare ad un numero ed assicurarsi che risponda con tono libero, in dettaglio riconducibile al seguente estratto:

Dato un numero di utenza telefonica mobile, corrispondente alla SIM utilizzata all’interno di un terminale per telecontrollo, è possibile contattare lo stesso numero con una chiamata voce per verificare la disponibilità della rete mobile sul terminale remoto.

In caso positivo, lo stesso terminale attenderà il tempo equivalente ad uno squillo per poi rifiutare la chiamata, l’equivalente di una linea occupata.

Determinare se il terminale corrispondente al numero ha copertura GSM sufficiente per la gestione in entrata ed uscita di chiamate vocali e SMS.

L’utilizzo di ecosistemi tecnologici M2M più evoluti consentirebbe controlli più efficaci ed immediati, ma l’indicazione in questo caso è quella di rendere operativo un sistema automatico nel breve termine evitando gli interventi di recupero, aggiornamento e reinstallazione del parco terminali già in esercizio, molti dei quali collegati a macchine operatrici a lavoro in cantieri lontani dalla sede aziendale o comunque difficili da poter raggiungere.

Applicazione: controllo del tono libero su terminali installati in cantiere

Condizioni per il tono libero

Il modello del terminale, utilizza una sezione di radiocomunicazione GSM compatibile con rete e SIM ordinarie degli operatori italiani (TIM, Vodafone, Wind) che è possibile interrogare via SMS per ricevere indicazioni sullo stato di ingressi, uscite ed altri dati. L’installazione tipica è eseguita a bordo di macchine da cantiere, a volte la posizione delle stesse a malapena consente una copertura del segnale radiomobile (es. pala meccanica al lavoro in galleria); quindi è indispensabile che un’interrogazione dalla sede sia subordinata alla bontà del segnale di rete agganciato dal terminale, per poter garantire una risposta.

La condizione ideale è che a chiamata vocale diretta, il numero risulti agganciato alla rete (ovvero raggiungibile); il terminale si preoccuperà di attendere poco tempo e rifiutare la chiamata. Quindi al chiamante la centrale telefonica segnalerà almeno un tono libero.

Tutte le altre condizioni differenti sono da considerarsi come eventi che escludono il terminale come al momento raggiungibile.

Tutto questo deve rispondere a logiche programmabili, automatiche o sovrintese da personale aziendale.

FreeSWITCH e tone_detect

Dopo aver percorso alcune opzioni, incluse quelle dei test per il tono libero con modem voce PSTN, ho scelto l’uso di FreeSWITCH poiché consente un apprendimento relativamente rapido, un buon sviluppo di applicazioni personalizzate, non richiede hardware specifico e nonostante la documentazione non sia sempre chiara gli sforzi della comunità alla base della piattaforma sono enormi. Inoltre, con l’integrazione FreeSWITCH si apre il sistema verso scenari applicativi inediti.

Per poter effettuare delle chiamate in uscita, testando alcuni fornitori VoIP, ho integrato i servizi di Messagenet che è risultato quello meglio corrispondente alle aspettative.

Il componente su cui verge l’oggetto dell’articolo è tone_detect al quale passare la frequenza di riferimento del tono libero a 425 Hz ed altri parametri minori. La ricetta è contenuta come configurazione di una extension nel dialplan (prefisso 9900), che vado a richiamare in modo asincrono dal sistema con la riga

fs_cli -x "originate loopback/9900333123456 &echo()"

Proprio all’interno della extension, inserisco delle callback (come ulteriori extension) secondo le quali gestire i diversi casi; segue un estratto della configurazione:

<extension name="ctl_verifica">
 <condition field="destination_number" expression="^9900(\d+)$">
 <action application="set" data="continue_on_fail=true"/>
 <action application="set" data="hangup_after_bridge=true"/>
 <action application="set" data="ctl_chiamato=$1"/>
 <action application="set" data="tone_detect_hits=1"/>
 <action application="set" data="execute_on_tone_detect_1=log 1 *** ONTONEDETECT ***"/>
 <action application="set" data="execute_on_tone_detect_2=transfer ctl_tonolibero"/>
 <action application="set" data="execute_on_media_1=log 1 *** ONMEDIA ***" />
 <action application="set" data="execute_on_media_2=tone_detect tono1 425 w 0"/>
 <action application="set" data="execute_on_media_3=sched_hangup +30 alloted_timeout bleg"/>
 <action application="set" data="execute_on_answer_1=log 1 *** ONANSWER ***" />
 <action application="set" data="execute_on_answer_2=transfer ctl_risponde" />
 <action application="set" data="execute_on_ring_1=log 1 *** ONRING ***" />
 <action application="bridge" data="sofia/gateway/gw_messagenet/$1"/>
 <action application="transfer" data="ctl_inesitato" />
 <action application="log" data="1 B-leg hangup cause: ${bridge_hangup_cause}"/>
 <!--<action application="javascript" data="/opt/freeswitch/report2.js $1 ${bridge_hangup_cause}"/>-->
 </condition>
</extension>

Con la configurazione in uso, viene inoltre superato l’ostacolo della eventuale segreteria dell’operatore telefonico, contenendo le singole extension derivate il comando di hangup prima della chiusura.

Pertanto l’inconveniente relativo ad una singola chiamata è un consumo di 1 secondo nei rari casi che FreeSWITCH non riesca a terminare la chiamata, nell’istante immediatamente successivo all’avviso che introduce il servizio di voicemail dell’operatore di rete. Per evitare questo inconveniente, basta semplicemente che il servizio sia disattivo per ogni SIM della flotta.

WOFF2 e correzione di MIME Type su webserver

WOFF2 è la versione con un algoritmo di compressione aggiuntivo rispetto al Web Open Font Format di base: consente l’incorporazione delle specifiche dei caratteri e dei glifi specifici per i progetti web.

Di recente, oltre che per l’utilizzo proprio, è stata utilizzata come tecnologia alla base dei kit di icone e pittogrammi in comune uso nelle interfacce utente e per la simbologia di bottoni od azioni collegate a link.

woff2

WOFF2 ed il gap attuale

Un problema di occorrenza frequente è presente appunto nel caso di utilizzo delle tecnologie Font Awesome e simili. Quando vengono inclusi i file dei framework in modo statico all’interno di un progetto, senza quindi passare per CDN esterne, ed il webserver non ha una tabella aggiornata per l’associazione di content type, il server ritorna un errore di risorsa non esistente (il canonico errore 404 File Not Found).

Quindi qualora non sia possibile utilizzare una CDN od il progetto necessita di essere appoggiato su un server con servizio HTTP legacy, possono tornare utili le seguenti configurazioni per l’impostazione dei filtri per i tipi di file.

Soluzione per IIS

La motivazione principale che mi ha portato a raccogliere informazioni è stata quando il problema si è presentato per primo con IIS. È stato frustrante continuare a trovare segnalazioni per un file non esistente durante il debug di una app… dovuto ad un semplice gap. Ho quindi utilizzato un file web.config per Internet Information Services simile al seguente:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
 <system.webServer>
 <staticContent>
 <remove fileExtension=".woff2" />
 <mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
 </staticContent>
 </system.webServer>
</configuration>

Soluzione per NGINX

In NGINX (non ho verificato l’esistenza del problema), la configurazione equivalente è la seguente:

types {
    application/font-woff2  woff2;
}

Soluzione per Apache

Ecco la versione Apache per una possibile inclusione in file .htaccess (anche in questo caso non ho individuato possibili istanze problematiche, quindi si tratta di una ulteriore equivalenza):

AddType  application/font-woff2  .woff2

Versioni PHP supportate dai principali fornitori hosting e VPS

Tra gli elementi condizionanti la scelta di un particolare fornitore fornitore di servizi tipo hosting o VPS, può essere di aiuto poter conoscere in anticipo le versioni PHP dell’interprete che l’azienda mette a disposizione ai propri clienti.

Nel caso dell’utilizzo di pacchetti standard o di software che richiedono una minima personalizzazione ovvero soluzioni da poter essere installate ed eseguite “chiavi in mano”, una raccolta delle possibilità offerte dal mercato consente di semplificare e velocizzare in particolare i tempi necessari alla messa in linea dei propri progetti.

PHP_Logo

Il progetto phpversions

Il progetto phpversions, patronato da Phil Sturgeon, in estrema sintesi classifica le versioni php disponibili per i più diffusi servizi di hosting e VPS.

Per uno sviluppatore è di indubbio vantaggio poter conoscere il panorama delle versioni offerte dal mercato, riuscendo a determinare indirettamente anche la politica relativa all’aggiornamento ed la pianificazione al supporto contemporaneo di differenti versioni.

Dal punto di vista dell’azienda che offre il servizio hosting, VPS, cloud o PHPaaS che sia, questa utilità può rappresentare un’opportunità per dimostrare il proprio impegno nella fornitura di strumenti e servizi in linea con le richieste e le aspettative dei clienti, sia quelli che sono alla ricerca delle versioni di PHP più recenti verso altri ai quali può interessare il servizio che ne supporta ancora una precedente (es. per software storicizzato o in previsione di refactorying).

Extra

Allo scopo di essere utile anche oltre lo scenario dei servizi offerti da terzi, c’è uno spazio riservato anche al riepilogo delle versioni php disponibili attraverso i repositories delle principali distribuzioni Linux comunemente utilizzate in ambito web (es. CentOS, Debian, Ubuntu), comodo riferimento nel caso di amministrazione diretta delle macchine o informazioni comunque utili come comparazione tra i vendor che tendono a supportare versioni più recenti rispetto ad altri che privilegiano aggiornamenti graduali ed upgrade meno “drastici” in ottica di rilascio di lungo termine.

MSMTP: usare GMail con la funzione mail() in PHP

Questo articolo può essere applicato a differenti scenari: una installazione Linux minimale, un’istanza virtuale o contenitore che non include un MTA, incompatibilità tra differenti interpreti, un desolante messaggio nella riga di comando da console tipo

sh: 1: /usr/sbin/sendmail: not found

In aggiunta, si può avere la necessità (anche dal punto di vista della comodità o per via di esigenze legate a razionalizzazione delle risorse) di voler utilizzare un servizio esterno all’host che si occupi dell’inoltro dei messaggi di posta elettronica, sfruttando un servizio SMTP con un profilo esistente (fornito anche all’esterno della sede locale, come per es. Google Apps for Work‎ od il comune Gmail), escludendo l’opzione di installare un servizio puro superfluo o inutile su una macchina non desinata a ricevere posta.

Sintesi: il software in questione deve occuparsi di smistare messaggi di posta elettronica, rappresentando il tratto di unione tra un interpretesendmail-compatibile ed un client SMTP. Esiste di già, ed è MSMTP.

MSMTP: requisiti ed installazione

Il progetto MSMTP manutenuto da Martin Lambers è rilasciato come codice libero in licenza GPLv3: i requisiti sono ristretti ad un compilatore e le funzioni per socket tipo Berkeley. Disponibile sui repository delle maggiori distribuzioni Linux, si può comunemente lanciare

apt-get install msmtp

per l’installazione in Debian od Ubuntu, mentre per le altre in base yum tipo RHEL / CentOS

yum install msmtp

Su Apple MacOS 10, MSMTP è disponibile con la formula homebrew

brew install msmtp

La configurazione si basa su file di testo semplici, con i percorsi predefiniti per sistema su /etc/msmtprc e ~/.msmtprc per le configurazione dei singoli utenti. Sul sito di riferimento è presente la documentazione completa (in inglese) ed un file di esempio. Davvero lineare.

google-gmail

Integrazione con PHP ed uso di account Gmail

Come riportato poco prima, MSMTP è sostituibile al comando sendmail, pertanto ci si può disporre a questo tipo di configurazione creando un file in /etc/msmtprc con la configurazione di un account SMTP esistente; il software supporta il TLS, quindi l’esempio Gmail è anche un buon esercizio per verificare questa opzione.

Contenuto del file /etc/msmtprc :

# Esempio msmtprc per Gmail
# 2014 Alessio Felicioni
# fonte: http://www.alessiofelicioni.it/msmtp-gmail-funzione-mail-php/

# valori predefiniti
defaults
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /var/log/msmtp.log

# configurazione account
account default
host smtp.gmail.com
port 587
auth on
from utente@gmail.com
user utente@gmail.com
password La(TUA)Password_va_qui

Importante garantire che il file sia leggibile dall’utente che esegue il php via processo server (es. apache, www-data o equivalente): vale a dirsi

chown www-data /etc/msmtprc
chmod 600 /etc/msmtprc

Quindi il valore di sendmail_path in php.ini potrebbe essere sostituito con la seguente sintassi

sendmail_path = "/usr/bin/msmtp -C /etc/msmtprc -t"

MSMTP supporta anche la configurazione di account multipli anche sullo stesso file: il parametro che controlla questa opzione è -a con il significato che se invocato con valori differenti, lo smistamento avverrà attraverso profili (ed eventualmente tratte/server SMTP) differenti.

La sezione di documentazione del progetto all’indirizzo http://msmtp.sourceforge.net/documentation.html è il punto di riferimento per utilizzare al meglio il programma e ricca di esempi.

Ripristinare yum su CentOS 5, con RPM

A seguito dell’introduzione di una versione incompatibile dell’interprete python o per altri eventi che abbiano in qualche modo corrotto la corretta dimensione delle dipendenze, può essere necessario ripristinare yum su CentOS 5.

Pur non essendo nello specifico la macchina con dei servizi esposti ma facente parte di una rete attivamente utilizzata per lo sviluppo, è opportuno tornare ad avere yum in efficienza.

cat /etc/redhat-release
CentOS release 5 (Final)

Le necessità al momento non prevedono un upgrade di versione (sebbene preferibile), quindi la dimensione di intervento è quella circoscritta dal mantenersi nel perimetro di CentOS 5.

Ripristinare yum su CentOS 5, con RPM

Dove recuperare file RPM

I file rpm necessari per l’attività di ripristino di yum sono disponibili all’indirizzo http://mirror.centos.org/centos-5/5/os/i386/CentOS/ e pertanto possono essere recuperati ad esempio con wget. Nel mio caso ho recuperato la seguente lista:

python-2.4.3-56.el5.i386.rpm
python-libs-2.4.3-56.el5.i386.rpm
yum-3.2.22-40.el5.centos.noarch.rpm

Completati i download, siccome intendo forzare la sostituzione dei precedenti rpm, posso lanciare

rpm -Uvh --replacepkgs *.rpm

Non sufficiente per ripristinare yum su CentOS 5?

Tutto quanto anticipato sembrerebbe formalmente aver contribuito a sistemare l’installazione di yum per riprendere ad utilizzarlo.

Infatti

yum --version

torna la versione di yum presente e le informazioni sul parser utilizzato per comunicare con le fonti, ma già un

yum list installed

frena gli entusiasmi. Uno dei mirror è in HTTPS ed un componente python m2crypto solleva un’eccezione non gestita.

Ho individuato la soluzione riprendendo dal mirror di CentOS 5 un rpm m2crypto-0.16-9.el5.i386.rpm ed in effetti sono riuscito a superare anche l’ostacolo del repository in HTTPS.

Composer Introduzione al gestore di dipendenze per PHP

Per progetti software integranti soluzioni, librerie, classi o componenti in genere rilasciati da terze parti, inclusi i framework da poter estendere per i propri lavori, poter avere strumenti per l’organizzazione e la gestione delle dipendenze diventa di estremo supporto. Questo articolo è una sorta di “Composer Introduzione ed Esempi” per verificare alcuni possibili casi di utilizzo.

Brevemente è da citare la disponibilità di PEAR (acronimo di PHP Extension and Application Repository), ispirato da CPAN di Perl, come supporto nello svolgimento degli stessi compiti, anzi il sistema di distribuzione è davvero molto diffuso, consentendo di avere direttamente a disposizione centinaia di componenti riutilizzabili.

Logo-composer-transparent

Composer: Introduzione

Composer è un gestore di dipendenze per classi, librerie, framework e software scritto in PHP. Potendo facilitare chi ha esperienza di prodotti simili in altri linguaggi, per paragone può essere associato a quello che offre Bundler per Ruby oppure NPM per Node.js

Non essendo fornita un’interfaccia grafica con cui interagire, i comandi vengono eseguiti attraverso la linea di comando, rendendo Composer veloce e compatto per la gestione delle dipendenze e la manipolazione dei file di configurazione. Essenziale l’integrazione con Packagist una vera e propria miniera per poter sfogliare e cercare componenti direttamente installabili con comandi Composer.

Requisiti ed installazione

Il principale requisito di Composer è la presenza dell’interprete PHP versione 5.3.2 o superiore. Il progetto mette a disposizione all’indirizzohttps://getcomposer.org/installer uno script per un’istallazione di tipo predefinito, da poter passare direttamente all’interprete. L’esperienza di installazione di esaurisce in un “lampo” per esempio utilizzando i seguenti comandi in una shell Linux

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

Per Windows, l’installazione è resa ancor più facile con il download e l’esecuzione di https://getcomposer.org/Composer-Setup.exe

Ad installazione avvenuta, è possibile verificare la versione disponibile lanciando il comando base con l’opzione V, es.

root@host:~# composer -V
Composer version 1.0-dev (4d134ce8a2aacb9566fee8deb8c514248fd2a983) 2015-04-08 13:43:49

Adesso Composer è disponibile sul sistema. In base alla cartella di lavoro, le dipendenze saranno gestibili attraverso file con sintassi JSON denominati composer.json da poter creare in maniera automatica anche con il comando composer init.

Per convenzione, la cartella vendor è delegata ad ospitare le dipendenze ed il file di autoload; quindi in progetti che adottano Composer sarà una costante poter vedere il codice seguente all’interno degli script PHP.

require 'vendor/autoload.php';

Definire le proprie dipendenze

Il metodo più semplice per compilare un file composer.json specifico è attraverso Composer stesso.

composer init

Basterà rispondere alla sequenza di domande, per ottenere lo schema desiderato. Per esempio è possibile specificare diverse opzioni in merito a versioni, dipendenze in fase sviluppo e produzione, licenze… incluso un metodo di ricerca interattivo e semplificato (es. creazione di un pacchetto fittizio company/helloworld che richiede symfony). Nel “prezzo” è incluso anche la generazione di un’anteprima:

root@host:/home/alessio# composer init 
This command will guide you through creating your composer.json config.
Package name (<vendor>/<name>) [home/alessio]: company/helloworld
Description []: Just saying hello to the world
Author: Alessio Felicioni <alessio@example.com>
Minimum Stability []:
License []: MIT
Define your dependencies.
Would you like to define your dependencies (require) interactively [yes]?Search for a package []: symfony
Found 15 packages matching symfony
 [0] symfony/symfony
 [1] symfony/console
 [2] symfony/yaml
 [3] symfony/filesystem
 [4] symfony/finder
 [5] symfony/process
 [6] symfony/translation
 [7] symfony/debug
 [8] symfony/routing
 [9] symfony/config
[10] symfony/stopwatch
[11] symfony/icu
[12] symfony/validator
[13] symfony-cmf/symfony-cmf
[14] symfony/intl
Enter package # to add, or the complete package name if it is not listed []: 0
Enter the version constraint to require (or leave blank to use the latest version) []:
Using version ~2.6 for symfony/symfony
Search for a package []:
Would you like to define your dev dependencies (require-dev) interactively [yes]?
Search for a package []: symfony
Found 15 packages matching symfony
 [0] symfony/symfony
 [1] symfony/console
 [2] symfony/yaml
 [3] symfony/filesystem
 [4] symfony/finder
 [5] symfony/process
 [6] symfony/translation
 [7] symfony/debug
 [8] symfony/routing
 [9] symfony/config
[10] symfony/stopwatch
[11] symfony/icu
[12] symfony/validator
[13] symfony-cmf/symfony-cmf
[14] symfony/intl
Enter package # to add, or the complete package name if it is not listed []: 0
Enter the version constraint to require (or leave blank to use the latest version) []:
Using version ~2.6 for symfony/symfony
Search for a package []:
{
 "name": "company/helloworld",
 "description": "Just saying hello to the world",
 "require": {
 "symfony/symfony": "~2.6"
 },
 "require-dev": {
 "symfony/symfony": "~2.6"
 },
 "license": "MIT",
 "authors": [
 {
 "name": "Alessio Felicioni",
 "email": "alessio@example.com"
 }
 ]
}
Do you confirm generation [yes]? yes
root@host:/home/alessio#

Composer per installare dipendenze

Supponiamo di aver bisogno di Twig per il nostro progetto. Sarà sufficiente lanciare

composer require "twig/twig:~1.0"

e vedere come Composer si preoccuperà di aggiornare il file JSON, recuperare le nuove dipendenze via Packagist, contrassegnare in file di lock le informazioni sulla versione installata.

Trasferire file via ZModem

Tra le operazioni di base più utili per una macchina connessa ad una rete, è fondamentale poter trasferire in ingresso ed uscita dei file. ZModem è un protocollo utilizzato per la sua semplicità e flessibilità per trasferimenti veloci all’interno di sessioni SSH.

Trasferire file via ZModem

ZModem

Emerso negli anni 80 come protocollo di trasferimento di file, ZModem è il risultato di miglioramenti a tecniche preesistenti. La diffusione è stata tale nel mondo delle BBS che praticamente ancora oggi le implementazioni software sono esistenti per la maggior parte delle piattaforme, da DSZ a lrzsz.

Proprio quest’ultimo è praticamente un pacchetto ubiquo e disponibile per tutti i sistemi Unix, Linux e derivati.

Installare ZModem in Linux

Di seguito l’installazione e i repository disponibili per le distribuzioni Linux più comuni:

Debian, Ubuntu

apt-get install lrzsz

RedHat, CentOS

yum -y install lrzsz

Usare ZModem in MacOSX

In MacOSX ZModem è disponibile come formula Homebrew installabile con il comando

brew install lrzsz

In caso di utilizzo in abbinamento con iTerm2, è necessario creare degli script da lanciare e configurare tra i trigger, attivandoli con le sintassi in espressione regolare intercettando l’output restituito rispettivamente da rz e sz.

Codice dal repository Github

#!/bin/bash
# Author: Matt Mastracci (matthew@mastracci.com)
# AppleScript from http://stackoverflow.com/questions/4309087/cancel-button-on-osascript-in-a-bash-script
# licensed under cc-wiki with attribution required 
# Remainder of script public domain

FILE=`osascript -e 'tell application "iTerm" to activate' -e 'tell application "iTerm" to set thefile to choose folder with prompt "Choose a folder to place received files in"' -e "do shell script (\"echo \"&(quoted form of POSIX path of thefile as Unicode text)&\"\")"`
if [[ $FILE = "" ]]; then
	echo Cancelled.
	# Send ZModem cancel
	echo -e \\x18\\x18\\x18\\x18\\x18
	echo \# Cancelled transfer
	echo
else
	echo $FILE
	cd "$FILE"
	/usr/local/bin/rz 
	echo \# Received $FILE
	echo
fi
#!/bin/bash
# Author: Matt Mastracci (matthew@mastracci.com)
# AppleScript from http://stackoverflow.com/questions/4309087/cancel-button-on-osascript-in-a-bash-script
# licensed under cc-wiki with attribution required 
# Remainder of script public domain

FILE=`osascript -e 'tell application "iTerm" to activate' -e 'tell application "iTerm" to set thefile to choose file with prompt "Choose a file to send"' -e "do shell script (\"echo \"&(quoted form of POSIX path of thefile as Unicode text)&\"\")"`
if [[ $FILE = "" ]]; then
	echo Cancelled.
	# Send ZModem cancel
	echo -e \\x18\\x18\\x18\\x18\\x18
	echo \# Cancelled transfer
	echo
else
	echo $FILE
	/usr/local/bin/sz "$FILE"
	echo \# Received $FILE
	echo
fi

Attivare un tunnel inverso per pubblicare un servizio dietro NAT

Spesso, con l’aggiunta di ulteriori opportuni accorgimenti, è utile poter utilizzare alcuni servizi disponibili all’interno di una rete locale in una sede remota. L’ostacolo in questo caso è costituito dalla funzione NAT che a meno di riconfigurazione dei nodi intermedi non consente un instradamento diretto al server oggetto di interesse: una possibile soluzione è quella di attivare un tunnel inverso.

Una delle funzionalità di OpenSSH è quella di poter attivare dei tunnel; per lo scopo prefissato l’unico prerequisito è poter avere accesso verso la macchina che intende consumare direttamente tale servizio, ovvero anche nel caso sia designato come macchina intermedia (l’idea è quella di attivare un proxy).

Esempio per tunnel inverso dietro NAT

Creare un tunnel inverso con SSH

Il caso più semplice può essere quello di pubblicare un servizio HTTP: l’opzione di nostro interesse è -R alla quale va indicato come parametro una stringa composta dalla porta sull’host remoto al quale il servizio verrà consumato, l’indirizzo della macchina che offre il servizio e la porta, separati da : pertanto la seguente sintassi riassume un classico esempio

ssh -R 10080:localhost:80 utente@macchina.esempio.it

Come anticipato, all’interno di macchina.esempio.it è disponibile alla porta 10080 il servizio HTTP che comunica con la macchina originale e rende disponibile attraverso il tunnel inverso il servizio che lì si trova alla porta 80.

Alternative

In alternativa all’utilizzo di ssh, esistono alcuni servizi che semplificano la configurazione e l’utilizzo, con dei piani introduttivi di primo utilizzo gratuiti.

Quasi sempre sono include delle funzionalità aggiuntive utili per la pubblicazione di demo o sviluppo di servizi web, console di monitoraggio delle richieste e utilità per l’analisi di webhook. I costi dei vari servizi sono piuttosto accessibili e convenienti per una disponibilità già pronta per queste necessita e con profili di offerta diversificati dal singolo utente ad entità più strutturate.

Aperto a segnalazioni per ulteriori alternative.

Età anagrafica e verifica utente maggiorenne

Nell’attività quotidiana di un sistema che utilizza delle informazioni anagrafiche, la data di nascita è tra i dati che caratterizzano un utente o comunque un profilo riferito ad una persona fisica. Altrettanto comune è l’esigenza di poter conoscere l’età anagrafica dello stesso utente, ovvero verificare che per l’accesso ed uso di servizi siano soddisfatti dei requisiti minimi di età (es. sottoscrizione di abbonamenti, siti di e-commerce per la vendita di vino o casi simili): la classica verifica che la data di nascita corrisponda ad un maggiorenne.

In questo articolo sono presentate alcune possibili soluzioni per il calcolo dell’età anagrafica e la verifica che un profilo utente risulti maggiorenne.

PHP_Logo

Come calcolare l’età anagrafica

Per il calcolo di età si tratta di operare una differenza logica tra due date, ovvero tra la data di nascita e la data odierna.

Nello specifico il metodo utilizzato è DateTime::diff, che consente di ottenere un oggetto di tipo DateInterval contenente le informazioni di differenza tra due date

Per il trattamento delle date preferisco quando possibile formati riferibili a notazioni ISO 8601, quindi lo utilizzerò anche negli esempi di codice. Brevemente ad un utente nato il 19 maggio 1991 corrisponde la notazione 1991-05-19. Qui di seguito la dimostrazione di una veloce stesura di codice:

<?php
$sData = '1991-05-19';
$oDataNascita = new DateTime($sData);
$oDataAdesso = new DateTime();
$oDataDiff = $oDataNascita->diff($oDataAdesso);
printf("La data di nascita dell'utente nato il %s è %d.", $oDataNascita->format('j F Y'), $oDataDiff->y);
?>

Il valore tornato da diff come DateInterval per il caso specifico è utilizzato solamente per la restituzione degli anni, ma permette di richiamare oltre alle altre unità anche la differenza assoluta in giorni ( $oDataDiff->days nel caso dell’esempio).

Verificare se un utente è maggiorenne

Prendendo spunto dalle istruzioni del paragrafo precedente, può essere utile costruire una funzione che possa restituire un booleano true/false se per un valore di data di nascita ci troviamo di fronte ad un profilo di un maggiorenne.

Può anche essere utile inserire un parametro opzionale per variare l’età di soglia, qualora i requisiti siano più bassi (es. per l’accesso a delle attrazioni di luna park non adatte ai bambini ma permesse ad adolescenti) o più stringenti (es. per verifiche sul diritto al voto per il Senato della Repubblica, esercitabile a partire da 25 anni).

Segue il codice con le caratteristiche introdotte:

function maggiorenne($sData=null, $nSogliaAnni=18) {
  $bRet = false;
  if($sData == null) {
    $sData = date('Y-m-d');
  }
  $oDataNascita = new DateTime($sData);
  $oDataAdesso = new DateTime();
  $nAnni = $oDataNascita->diff($oDataAdesso)->y;
  if ($nAnni >= $nSogliaAnni) {
    $bRet = true;
  }
  return $bRet;
}
$sDataDiNascita = '1991-05-19';
$bMaggiorenne = maggiorenne($sDataDiNascita);                              if ($bMaggiorenne) {                                                     
  echo 'puoi acquistare vino, liquori e tutte le altre bevande';         
} else {                                                                 
  echo 'puoi acquistare solamente acqua e bevande gassate';              
}

Versione di PHP corrente, in script o riga di comando

Tra i linguaggi di scripting di utilizzo comune, PHP è sicuramente tra i più diffusi. Ma per tale grado popolarità non significa che per ogni progetto o soluzione ci sia la sufficiente combinazione per il corretto superamento dei requisiti per il necessario funzionamento.

Un caso di esempio comune si verifica quando per alcune librerie non sono ancora disponibili versioni recenti, oppure in caso contrario delle classi potrebbero richiedere una versione minima di PHP per poter essere utilizzate. Inoltre molte estensioni sono deprecate per l’uso in versioni più mature o disponibili solamente a partire da versioni di PHP di recente rilascio.

Questo articolo raccoglie alcuni consigli su come determinare la versione di PHP disponibile per superare qualsiasi dubbio a proposito.

PHP_Logo

Versione di PHP all’interno di script e file php

Per visualizzare la versione di PHP correntemente in uso dall’interprete, è disponibile la funzione phpversion, che restituisce una stringa contentente la notazione maggiore, inferiore e di revisione (quindi una forma completa del tipo “5.3.29”) della versione.

E’ utilizzabile come nel blocco di codice seguente:

<?php
echo 'La versione di PHP attualmente in uso è ' . phpversion();
?>

La stessa informazione è disponibile come costante predefinita PHP_VERSION :

<?php
echo 'La versione di PHP attualmente in uso è ' . PHP_VERSION;
?>

Ovviamente l’informazione può essere trattata come una stringa, quindi può essere salvata all’interno di una variabile ed utilizzata nel corpo di qualsiasi script.

Versione di PHP da linea di comando (CLI)

In alternativa, è possibile conoscere la versione dell’interprete da linea di comando (CLI) utilizzando l’opzione -v .

L’esempio seguente riporta il caso restituito da un host Linux

[root@host ~]# php -v
PHP 5.3.3 (cli) (built: Oct 31 2014 09:53:00)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
[root@host ~]#