Ho abilitato da molto tempo l'accesso cross-domain per elaborare dati da un altro sito.
Da ieri inspiegabilmente non mi funziona più.
Sapete dirmi perchè?
Ho abilitato da molto tempo l'accesso cross-domain per elaborare dati da un altro sito.
Da ieri inspiegabilmente non mi funziona più.
Sapete dirmi perchè?
Intendi il supporto server to server? Puoi riportare il codice che utilizzi?
In pratica accedo a un sito con diverso dominio e genero una pagina con il risultato (un oggetto JSON):
Codice PHP:
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: X-PINGARUNER');
header('Content-Type: text/html');
$url = "http://www.viaggiatreno.it/viaggiatrenonew/resteasy/viaggiatreno/cercaNumeroTreno/23355";
echo $url;
echo "<br><br>";
$options = array('http' => array(
'method' => 'GET',
'header'=>"Host: www.viaggiatreno.it "
));
$result = file_get_contents($url);
echo "<br>Risultato:<br>";
echo $result;
?>
Ultima modifica di karl94 : 31-03-2016 alle ore 15.51.35 Motivo: Formattazione
Il codice che hai indicato mi sembra funzionare correttamente, non mi è però chiaro per quale ragione aggiungi gli header CORS. Stai cercando di usare lo script PHP come proxy per richieste XHR?
Esatto, questa è solo una pagina di prova con indirizzo fisso; per la mia applicazione ho un proxy.
Comunque entrambi hanno sempre funzionato fino a ieri.
Non è che è cambiato qualcosa sulla gestione delle richieste cross-server?
Mi ricordo di aver abilitato questa funzione tramite codice sul cellulare.
Le connessioni server to server sono correttamente abilitate sul tuo account. Puoi indicare l'indirizzo di una pagina in cui è possibile vedere in azione il tutto?
Ho una pagina di prova che richiede semplicemente un oggetto JSON (codice sopra):
http://trenografico.altervista.org/prova.php
Poi il proxy vero e proprio, che richiede la pagina finale come argomento:
http://www.trenografico.altervista.o...eroTreno/23378
E l'applicazione finale:
http://www.trenografico.altervista.org/trenografico.htm
effettuando una prova come proposto nel codice sopra a me funziona anche se non capisco l'utilità di $options.
1)Per avere un riscontro puoi utilizzare questo in testa lo scriptovviamente dovresti controllare se le variabili esistono (classico esempio di $_POST o $_GET)Codice PHP:
<?php
error_reporting(E_ALL | E_NOTICE | E_STRICT | E_DEPRECADED);
ini_set("display_errors" , "stdout");
ini_set("display_startup_errors" , 1);
?>.Codice PHP:
if(isset($_POST['nome_input'])){
qualcosa
}
2)Cosa utilizzi per decodificare il json, json_decode? Se è si devi preoccuparti di verificare se sono dati validi in utf-8 altrimenti non sarà un json valido.
3)Hai un intero json (il contenuto del file è una stringa) maggiore di 2^31-1 (ovviamente questo devi considerarlo solo se effettui una decodifica del json o comunque se devi trasformare questo numero in un intero php) se usi json_decode viene convertito in float altrimenti con la bitmask appropriata in una stringa.
4)Perché nella query-string del proxy non usi urlencode? (es. ?prova@ in ?prova%40 con la get appena creata non sarà possibile recuperare $_GET['prova%40'] ma un qualcosa del genere $_GET['prova_40'] perché segue le regole di sintassi per un nome di variabile anche per un elemento di un array,appunto la key). http://php.net/manual/en/language.variables.basics.php quindi dopo aver recuperato l'url la dovresti inserire nel proxy es. ?a=prova%40 $_GET['a']=urlencode('prova@');
In mancanza di codice esatto ed escludendo che non ti funziona il server to server,si possono fare solo supposizioni per aiutarti, spero che possa servirti.
ps. puoi anche togliere il www nel link dal tuo sito, se non hai modificato tale comportamento puoi accedere con http://nick.altervista.org
Ultima modifica di darbula : 02-04-2016 alle ore 15.46.17
E' vero, $options non seve, era rimasto da prove precedenti.
Inserendo la tua riga ottengo:
Warning: file_get_contents(http://www.viaggiatreno.it/viaggiatr...eroTreno/23355) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden in /membri/trenografico/prova.php on line 19
Line 19 è:
$result = file_get_contents($url);
Secondo me non ho più i diritti per richieste del genere.
Amministratori, potete controllare di nuovo?
Se funziona file_get_contents(url) non ho problemi, il sito ha funzionato per anni.
Il codice di stato (cioè http o https) 403 indica un errore da parte del cliente che chiama una url. Dobbiamo capire cosa sbagli. Ci sto riflettendo.
Quindi non è al momento il problema di connessioni server to server.
Come da descrizione presa da Wikipedia.org "403 Forbidden
La richiesta è legittima ma il server si rifiuta di soddisfarla. Contrariamente al codice 401 Unauthorized, l'autenticazione non ha effetto."
Se indichi una url differente cosa ti dice? Prova http://www.google.com/ cerco di dividere il problema, cioè mi baso su supposizioni che nel caso se questo ti funziona, allora il problema sarà da altervista per qualche oscura motivazione. Intendo "se" non sto gettando fango ad altervista sia chiaro.
warring non esaustivi per la funzione file_get_contents() "An E_WARNING level error is generated if filename cannot be found, maxlength is less than zero, or if seeking to the specified offset in the stream fails." per maggiori info si indirizza nel manuale php.net
Ultima modifica di darbula : 05-04-2016 alle ore 13.36.45
No, stesso messaggio:
Warning: file_get_contents(http://www.google.it) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden in /membri/trenografico/prova.php on line 20
@trenografico Le connessioni server-to-server dal tuo account sono state bloccate perché venivano usate in modo improprio, per esempio collegandosi al sito stesso facendo poi un'ulteriore connessione. Dovresti verificare tutte le connessioni che fai e accertarti che non vengano fatte azioni che possono essere ritenute dannose.
Come pensavo, ma non potevate avvertirmi?
Riguardo all'uso improprio, ho attivo da anni un proxy dedicato solo a un sito (www.viaggiatreno.it) che non fa altro che rigenerare i dati dell'orario treni in modo da poterli elaborare e visualizzare in modo grafico.
E'usato da 5 o 10 utenti al massimo, e non ha scopo di lucro.
Che tipo di uso improprio sarebbe?
Hai idea di come potrei elaborare quei dati in maniera diversa (il sito originale non è ovviamente accessibile per le note restrizioni cross-domain negli script)?
Io non faccio parte dei membri dello staff. Ma se uno script viene lanciato su un'altro script nel proprio spazio in remoto, suppongo che altervista lo ritenga dannoso per cautelare l'utente da possibili attacchi informatici, ovvero anche altervista avrebbe uno spreco di risorse (anche se con la mia modesta opinione, basterebbe semplicemente creare un token rinnovabile con user e password per prevenire abusi, lo so siamo ot) inutili non potendo identificare se è stato effettivamente l'utente ad attivare ciò. Nella pagina di proxy prelevi i dati e fai un redirect in una pagina diversa,dove appunto mostrerai i dati come meglio ritieni opportuno, se l'output è sempre destinato ad un browser.
Ultima modifica di darbula : 08-04-2016 alle ore 03.30.32
Il problema è che i tuoi script PHP non effettuano controlli efficaci sull'URL della richiesta da effettuare, e sono di fatto pericolosi in quanto chiunque può usarli anche per compiere azioni malevole.
Riporta l'esatto codice PHP che utilizzi, così ti posso indicare come correggerli.
Certo, ecco il mio script di proxy:
Ho un controllo sulla URL di destinazione.Codice PHP:
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: X-PINGARUNER');
header('Content-Type: text/html');
$url = $_SERVER['QUERY_STRING'];
if(stristr($url,"http://mobile.viaggiatreno.it")==0 || stristr($url,"http://www.viaggiatreno.it")==0){
$result = "";
if(count($_POST)!=0){
$options = array('http' => array(
'method' => 'POST',
'content' => http_build_query($_POST)
));
$context = stream_context_create($options);
for($i=0;$i<10&&$result=="";$i++) $result = file_get_contents($url, false, $context);
}
else for($i=0;$i<10&&$result=="";$i++) $result = file_get_contents($url);
echo $result;
}
?>
Magari sarebbe meglio anche uno sull'origine?
Dal codice non è ben chiaro se sai i presupposti per elaborare uno script, puoi descriverlo a parole (tutti gli script)? $_SERVER['QUERY_STRING'] recupera la parte dopo ? sempre che sia presente nella pagina in questione,poi con l'if vorresti controllare se sia effettivamente l'url, trattandosi di una query devi controllare la query con === FALSE (non == 0). Inoltre se devi controllare più condizioni (uguali) in questo caso false devi utilizzare l'operatore AND e non || altrimenti basta solo una condizione falsa per essere considerato l'intero if falso che viene valutato come true es if(($a=FALSE) === FALSE || ($b=TRUE) === FALSE){
// codice
} la seconda condizione non viene valutata in quanto la prima è falsa.e per finire io utilizzerei strpos così sono sicuro che inizi dalla partenza zero. (l'inizio)Codice PHP:
<?php
$url =
'http://www.viaggiatreno.it/viaggiatrenonew/resteasy/viaggiatreno/cercaNumeroTreno/23378';
if((($var=stristr($url,"http://mobile.viaggiatreno.it")) === FALSE) AND (($var2=stristr($url,"http://www.viaggiatreno.it")) === FALSE))
{
echo 'non trovato';
}else{
echo 'trovato';
}
var_dump($var,$var2);
?>
EDIT: a ecco http://www.trenografico.altervista.o...eroTreno/23378 recuperi questa query, mi ripeto creala coni get vanno urlencode come ho scritto prima.Codice:?a=valore
Comunque io rimango dell'opinione che altervista dopo tot dannose disattiva di nuovo il server to server. (secondo me viene bloccato in automatico da uno script)
script aggiornato
EDIT2: In questa url ?a=http%3A%2F%2Fwww.viaggiatreno.it%2Fviaggiatreno new%2Fresteasy%2Fviaggiatreno%2FcercaNumeroTreno%2 F23355Con contesto ottengo method not allowed 405 e senza ottengo No content 204 in entrambi i casi per la funzioneCodice PHP:
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: X-PINGARUNER');
header('Content-Type: text/html');
if((isset($_SERVER['QUERY_STRING']) !== FALSE) AND ($url=urldecode(($url = $_SERVER['QUERY_STRING']))) AND (($var=strpos($url,'a=http://mobile.viaggiatreno.it')) === 0) || (($var2=strpos($url,'a=http://www.viaggiatreno.it')) === 0)){
$url = substr($url,2);
$options = array('http' => array(
'method' => 'GET'
));
$i=0;
if(isset($_POST) != 0){
$options = array('http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($_POST)
));
}
$context = stream_context_create($options);
//for($i;$i<10&&$result=='';$i++)
$result = file_get_contents($url, false, $context);
echo $result;
}
?>dove starebbe l'errore?Codice:file_get_contents();
EDIT3:adesso anche chiamando il sito dal browser da risposta 204
Perché la eseguì 10 volte questa chiamata? Non capisco neanche $result a vuoto e $_POST che dati dovrebbe inviare nello specifico?.Spiegazione script solo quando è presente la query senza o con dati POST facciamo la chiamata per 10 volte di una url esterna. Altrimenti non faccio nulla!
Ultima modifica di darbula : 10-04-2016 alle ore 13.24.29
Scusate il post consecutivo ma ho scoperto dove sta l'errore. Praticamente risulta sempre l'array $_POST vuoto e di fatto esegue una connessione POST che se non supportato nel server di destinazione, si viene avvisati con "method not allowed 405" basta sostituire il codice di prima con questo, è doveroso anche aggiungere l'header Content-length per una corretta transizione POST.Codice PHP:
if(count($_POST) != 0){
$options['http'] = array(
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded\r\n"
. "Content-Length: " . strlen(http_build_query($_POST)) . "\r\n",
'content' => http_build_query($_POST)
);
}
@trenografico volevi fare questo se non ho capito male?
Ultima modifica di darbula : 11-04-2016 alle ore 15.54.33
Cercherò di rispondere secondo le mie conoscenze.
Lo scopo del gioco è inoltrare la risposta di un sito esterno specificato nella url dopo il "?"
Cioè il client scriveCome prima cosa prendo la url richiesta con:Codice:http://www.trenografico.altervista.org/proxy2.php?[url_da_inoltrare]
Faccio un controllo per restringere il campo ai siti viaggiatreno.it; mi suggerisci di usare FALSE come condizione: va bene, ma non capisco il resto del consiglio; lo script deve continuare se viene richiesto uno dei possibili domini.Codice:$url = $_SERVER['QUERY_STRING'];
Sono contemplati 2 casi di richieste: se c'è una _POST viene ricreato un header con la stessa richiesta.
Altrimenti viene richiesta la pagina semplice.
Il contatore a 10 serve nei casi in cui la risposta non arriva; in realtà ciò è molto raro e si potrebbe anche togliere.
Comunque non è un problema di funzionalità: il codice ha funzionato per anni.
Vorrei capire cosa è che dà fastidio ad Altervista e possibilmente correggerlo.
Hai testato effettivamente il codice che hai scritto? Quella condizione sarà sempre vera a prescindere dal valore di $url.
Una condizione efficace potrebbe essere:Codice PHP:
strpos($url, 'http://mobile.viaggiatreno.it/') === 0 || strpos($url,'http://www.viaggiatreno.it/') === 0
@trenografico quindi è quello che avevo previsto anche io nel mio script eccetto per il contatore e di conseguenza più connessioni.
Io ho messo la possibilità di ritentare per 10 volte, ma bada bene che se viene usato un pò di più del giusto, ti si blocca il server to server.
Questo è il codice di proxy.php guarda che io ho una query ?a=url.
Questo script nella prima if verifica se è presente una query successivamente creo la variabile $url e impongo una restrizione nella url, creo $options dopo verifico se riceve dati POST è tento la connessione per un massimo di 10 volte. Mi ripeto faccio queste operazioni solo quando trovo la query consentita.Codice PHP:
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: X-PINGARUNER');
header('Content-Type: text/html');
if((isset($_SERVER['QUERY_STRING']) !== FALSE) AND ($url=urldecode(($url = $_SERVER['QUERY_STRING']))) AND (strpos($url,'a=http://mobile.viaggiatreno.it') === 0) || (strpos($url,'a=http://www.viaggiatreno.it') === 0)){
$options = array('http' => array(
'method' => 'GET'
)
);
if(count($_POST) != 0){
$options['http'] = array(
'method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded\r\n"
. 'Content-Length: ' . strlen(http_build_query($_POST)) . "\r\n",
'content' => http_build_query($_POST)
);
}
$context = stream_context_create($options);
$i=0;
$max=10;
do {
if(FALSE != ($result=file_get_contents(substr($url,2),false,$context))){
$max=0;
break;
}
$i++;
} while ($i < $max);
echo $result;
}
?>
Ultima modifica di darbula : 12-04-2016 alle ore 03.06.28
Hai ragione, il controllo non era efficace.
Ho modificato il codice e ora va avanti solo per i siti specificati.
Va bene così o servono altre modifiche?
Perfetto, funziona di nuovo!
Grazie mille