Autor | Zpráva | ||
---|---|---|---|
Prefin Profil |
#1 · Zasláno: 21. 8. 2012, 20:43:56
Ahojda všichni.
Prosím o radu co dělám špatně či o zdroj informací v cz. Píšu script na vygenerování textu placené SMS (Airtoy). Přesně však nevím, jak si poradit s požadavkem na odpověď která má být HTTP 200 OK, musí být text/plain a obsahovat content-lenght. Příklad odpovědi: Vas pristupovy kod je ASBCDE;1. Po ověření potřebných věcí vypisuju tohle: $zprava_OK = "Vas kod je ".$kod.";1"; Header("HTTP/1.1 200 OK"); Header("Content-type: text/plain"); header("Content-Length: ".strlen($zprava_OK)); echo $zprava_OK; Content-Type: text/html Content-Length: 3 HTTP Status code: 200 Odpověď serveru:  Ve zpracování se nic nevypisuje (echo), za začátku stránky mám ob_start(). Moc díky za radu. Celý scriptík (je tam balast která ještě odstraním): <?php ob_start(); include "sql_pripojeni.php"; if($HTTP_SERVER_VARS["REMOTE_ADDR"]!="195.47.87.164" or $HTTP_SERVER_VARS["REMOTE_ADDR"]!="193.86.73.148") { exit(); } else { // Zjištění zda jde o volání na základě zaslání SMS if(isset($_GET["phone"]) and isset($_GET["sms"]) and isset($_GET["ts"]) and isset($_GET["uid"]) and isset($_GET["sc"]) and isset($_GET["o"])) { // Kontrola tvaru zaslané SMS a tel. čísla pro zasílání SMS /*$v = mysql_fetch_assoc(mysql_query("SELECT * FROM nastaveni_sms WHERE id_nastaveni_sms='1'")); if(($_GET["sms"])!=$v["text_nastaveni_sms"]) { Header("HTTP/1.1 204 NO_CONTENT"); exit; } if($_GET["sc"]!=$v["cislo_nastaveni_sms"]) { Header("HTTP/1.1 204 NO_CONTENT"); exit; }*/ // Vygenerování kodu pro SMS $kod = rand(1,9).rand(1,9).rand(1,9).rand(1,9).rand(1,9).rand(1,9).rand(1,9).rand(1,9); // Uložení záznamu o vygenerovaném kódu do tabulky s informacemi o generovaných a ověřených SMS if(mysql_query("INSERT INTO sms VALUES ('','".$kod."','".$_GET["phone"]."','0','".$_GET["ts"]."','".$_GET["uid"]."','".$_GET["sms"]."','','0')")) { // Odeslání odpovědi $zprava_OK = "Vas kod je ".$kod.";1"; Header("HTTP/1.1 200 OK"); Header("Content-type: text/plain"); header("Content-Length: ".strlen($zprava_OK)); echo $zprava_OK; /*exit;*/ } } elseif(isset($_GET["ds"]) and isset($_GET["dt"])) { // Zjištění zda volání je doručení statusu zprávy // Návratové hodnoty ds - status $ds["DELIVERED"] = "SMS byla doručena"; $ds["UNDELIVERED"] = "SMS nebyla a nebude doručena"; $ds["WAITING"] = "SMS čeká na doručení"; $ds["PENDING"] = "SMS je nevyřízena (dojde k jejímu pozdějšímu vyřízení)"; $ds["UNKNOWN"] = "Stav SMS není možné zjistit"; $ds["EXPIRED"] = "Platnost SMS vypršela (již nedojde k jejímu doručení)"; // Návratové hodnoty dm - zpráva $dm["INTERNAL_ERROR"] = "Vnitřní chyba operátora"; $dm["NOT_ENOUGHT_CREDIT"] = "Uživatel nemá dostatečný kredit"; $dm["SERVICE_NOT_ALLOWED"] = "Uživatel má blokovanou službu PREMIUM SMS"; $dm["NO_OPERATOR_CUSTOMER"] = "Uživatel není zákazníkem operátora, ke kterému byla SMS zaslána"; $dm["USAGE_RATE_EXCEEDED"] = "Uživatel překročil povolený limit svého účtu"; $dm["MT_SERVICE_NOT_ALLOWED"] = "Uživatel má blokované MT biling zprávy"; $dm["CUSTOMER_IS_BLOCKED"] = "Uživatel je operátorem blokován"; $dm["DAILY_LIMIT_EXCEEDED"] = "Uživatel překročil denní limit pro platby PR SMS"; $dm["UNKNOWN"] = "Důvod nedoručení je neznámý"; $dm["USER_BLACKLISTED"] = "Uživatel je operátorem blokován pro nehrazení služeb"; $status = $_GET["ds"]; $zprava = $_GET["dm"]; // Uložení statusu do db // Tvar záznamu v buňce status_sms: Doručena/Nedoručena;pokud ne tak dúvod;čas doručení; číslo doručenky; Request ID $sql = "UPDATE sms SET "; if($status == "UNDELIVERED") { $sql .= "status_sms='".$ds[$status].";".$dm[$zprava].";".$_GET["dt"].";".$_GET["dn"].";".$_GET["rid"]."'"; } else { $sql .= "status_sms='".$ds[$status].";;".$_GET["dt"].";".$_GET["dn"].";".$_GET["rid"]."',overeni_sms='1'"; } $sql .= " WHERE ident_airtoy_sms='".$_GET["rid"]."'"; //echo $sql; @mysql_query($sql); exit; } else { // Nebyly předány všechny parametry Header("HTTP/1.1 204 NO_CONTENT"); Header("Content-type: text/plain"); exit; } } ?> |
||
Majkl578 Profil |
#2 · Zasláno: 21. 8. 2012, 20:48:49
Ty tři podivné znaky na výstupu jsou BOM.
Seš si jistý, že se ti to dostane do bloku, kde předpokládáš výstup? Dále na prvni pohled (kromě nepřehledného kódu náchylného k SQL injection) vidím ob_start, ale už nikde nevidím ob_flush/ob_end_flush. |
||
Davex Profil |
Majkl578:
„nikde nevidím ob_flush/ob_end_flush“ Není nutné je používat. Obsah bufferu se odešle při ukončení skriptu. Prefin: V závislosti na verzi a nastavení PHP nemusí existovat pole $HTTP_SERVER_VARS . V nových PHP verzích vydaných za posledních 10 let by se mělo používat pole $_SERVER .
|
||
Prefin Profil |
#4 · Zasláno: 21. 8. 2012, 21:37:56
Já nejsem žádný programátor, jenom si stavím sám co potřebuju protože mě to baví.
Injection ještě spravím, to by bylo při GETu fakt blbý. Fakt je, že s tím co jsem popsal nemám žádné zkušenosti. Takže zkusím prohodit $_SERVER za $HTTP_SERVER_VARS (už jsem to párkrát dělal a vždycky se zase nachytám) a zkusím co to provede. Co se týče odpovědi serveru, tak je to v podstatě status (?), který se pošle volané stránce v HTTP. Pak by se měly vypsat důležité hlavičky a poté text. Je to tedy takhle správně? Header("HTTP/1.1 200 OK"); Header("Content-type: text/plain"); Header("Content-Length: ".strlen($zprava_OK)); echo $zprava_OK; |
||
Amunak Profil |
#5 · Zasláno: 21. 8. 2012, 22:07:08
Pokud vím, content-length většina serverů posílá automaticky, nemusíš to dělat ručně. To samé platí pro kód 200. Co se týče content-type, je v pořádku. A ano, hlavičky obsahují různé info o serveru, vlastnostech obsahu a tak.
|
||
Prefin Profil |
#6 · Zasláno: 22. 8. 2012, 08:50:59
Amunak:
„Pokud vím, content-length většina serverů posílá automaticky, nemusíš to dělat ručně. To samé platí pro kód 200. Co se týče content-type, je v pořádku. A ano, hlavičky obsahují různé info o serveru, vlastnostech obsahu a tak.“ Znamená to tedy že by stačilo: $zprava_OK = "Vas pristupovy kod je ASBCDE;1"; echo $zprava_OK; Content-Type: text/plain Content-Length: (pocet znaků $zprava_OK) HTTP Status code: 200 Odpověď serveru: Vas pristupovy kod je ASBCDE;1 Dík |
||
Amunak Profil |
Prefin:
Stačí prakticky něco jako header('Content-Type: text/plain'); echo 'Vas kod je '.$kod.';1'; Ale můžeš použít třeba i něco jako header('Content-Type: text/plain; charset=UTF-8'); echo 'Váš kód je '.$kod.';1'; A jinak nevím proč máš na konci zprávy ten středník a jedničku, ale uživatele by to mohlo mást. Udělej to tak, ať to nevypadá jako součást kódu. Hlavičky si můžeš i sám prohlížet - použij FireBug (ve FF) nebo ve chrome klikni na stránku pravým, pak zkontrolovat prvek. Potom vyber kartu network a tam si rozklikni první položku (stránku). Vpravo uvidíš request i response hlavičky. |
||
Prefin Profil |
#8 · Zasláno: 22. 8. 2012, 15:36:24 · Upravil/a: Prefin
Moc díky za info. Strávil bych na tom týden než bych to pochopil (možná).
Ta jednička na konci zprávy je přesně podle požadovaného formátu - Airtoy tak má označen cenový level (lze měnit podle typu služby). Ke klientovi se odešle pouze to co je před středníkem. Pomohlo to, odpověď je správná. Teď zase musím zjistit jak správně poslat 204, protože Header("HTTP/1.1 204 NO_CONTENT"); Content-Type: text/html Content-Length: 3 HTTP Status code: 200 Odpověď serveru:  |
||
Amunak Profil |
#9 · Zasláno: 22. 8. 2012, 17:39:26
Prefin:
protože tam pořád ještě máš BOM. Zkontroluj, jestli .php souboty opravdu ukládáš v UTF-8 a ideálně si v editoru vypni vkládání BOM. Pak všechny soubory "přeulož" ať to zmizí. PHP má prostě někdy problém když na BOM narazí, takže se dějí různé nepředvídatelné věci. Jinak na té hlavičce není nic špatného. |
||
Prefin Profil |
No to je, ale nevím proč. Zásadně všechno dělám v utf-8 a BOM mám vypnutý, s tím jsem se vycukal už dřív při jiné situaci.
Fakt je, že dělám v interním editoru Krusaderu (Linux). Zkusím to přehodit do woken a prověřit v pspadu. Mimo to, přestože se pokusím vypsat 204, pošle to 200. |
||
Časová prodleva: 3 dny
|
|||
Prefin Profil |
#11 · Zasláno: 25. 8. 2012, 11:07:04
Ještě bych požádal o drobnost.
Dočetl jsem se, že 204 NO_CONTENT odpoví server vždy, když neprovede žádnou akci - tedy neodešle žádnou odpověď. To znamená, že běh scriptu skončí bez bez výpisu. Musím v takovém případě upravovat hlavičky pomocí header()? Záleží na Content-type? Protože odpověď serveru je i v tomto případě pořád 200. |
||
Keeehi Profil |
#12 · Zasláno: 25. 8. 2012, 11:21:50
http://web-sniffer.net/ je pro vás velmi užitečný nástroj.
|
||
Prefin Profil |
#13 · Zasláno: 25. 8. 2012, 11:24:05
Moc díky. Bezva věc.
Ale pořád nevím, proč mi server posílá i při nevypisování ničeho 200. Nebo co musím udělat aby odpověď byla 204. Díky |
||
Keeehi Profil |
#14 · Zasláno: 25. 8. 2012, 11:29:17
Řekl bych, že
header("HTTP/1.1 204 No Content"); |
||
Prefin Profil |
#15 · Zasláno: 25. 8. 2012, 11:35:04
No právě že ne.
Když vypíšu header("HTTP/1.1 204 No Content"); header('Content-Type: text/plain; charset=UTF-8'); exit; Chybný navrácený content-type. Musí být text/plain Chybný navrácený content-length. Musí být uveden a větší 0. Chybný formát odpovědi Vašeho serveru. Neplatný navrácený status kód. Musí být 200 nebo 204. Takže to rozhodí veškeré serverem posílané hlavičky. Když odstraním header("HTTP/1.1 204 No Content"); Tak je vše v pořádku, jenom to vrací pořád 200. Asi si z toho už šlehnu. |
||
Keeehi Profil |
Prefin:
Spíš by bylo dobré říct, ukazuje web-sniffer. Ten totiž řekne co bylo doopravdy vráceno a ne jen co by mělo být vráceno. Na <?php header("HTTP/1.1 204 No Content"); header('Content-Type: text/plain; charset=UTF-8'); exit; Status: HTTP/1.1 204 No Content Date: Sat, 25 Aug 2012 09:40:14 GMT Server: Apache Content-Length: 0 Connection: close Content-Type: text/plain; charset=UTF-8 |
||
Prefin Profil |
#17 · Zasláno: 25. 8. 2012, 12:14:43
To je pravda.
Když pošlu dotaz z web-snifferu na toto: <?php header("HTTP/1.1 204 No Content"); header('Content-Type: text/plain; charset=UTF-8'); exit; ?> ............. } else { header("HTTP/1.1 204 No Content"); header('Content-Type: text/plain; charset=UTF-8'); exit; } Proč to tedy odešle v případě úspěchu všechno správně. Konkrétně: Správné volání scriptu je s těmito parametry ?phone=6e11b2559c9360d23d7d0b4481d1132b&sms=KPP+499&ts=2012-08-25T12%3A04%3A42&uid=134&o=TM_CZ&sc=90333&t=1 Chybné když v sms je něco jiného než KPP+(499/399/299) nebo chybí parametry apod. Tahle validace je ok, nicméně nevrací to 204 ani na web-snaffu. Tady je script: ob_start(); include "sql_pripojeni.php"; include "funkce.php"; // Kontrola IP if($_SERVER["REMOTE_ADDR"]=="195.86.73.148") { // Testovací adresa Airtoy $x = 1; } else { $ip = explode(".",$_SERVER["REMOTE_ADDR"]); // Běžný rozsah ip Airtoy if($ip[0]=="195" and $ip[1]=="47" and $ip[2]=="87" and $ip[3]>="160" and $ip[3]<="191") $x = 1; } if($x!=1) { // Konec při nesprávné ip ZapisDoLogu("!!!! Pokus o vygenerování kódu k SMS z nepovolené IP adresy: ".$_SERVER["REMOTE_ADDR"].","); exit(); } else { // Zjištění zda jde o volání na základě zaslání SMS if($_GET["phone"]!="" and $_GET["sms"]!="" and $_GET["ts"]!="" and $_GET["uid"]!="" and $_GET["sc"]!="") { // kontrola zaslaného textu sms $text = substr($_GET["sms"],-3); if(strlen($_GET["sms"])==7 and ($text=="299" or $text=="399" or $text=="499")) { // Vygenerování kodu pro SMS $kod = rand(1,9).rand(1,9).rand(1,9).rand(1,9).rand(1,9).rand(1,9).rand(1,9).rand(1,9); // Uložení záznamu o vygenerovaném kódu do tabulky s informacemi o generovaných a ověřených SMS if(mysql_query("INSERT INTO sms VALUES ('','".$kod."','".$_GET["phone"]."','0','".$_GET["ts"]."','".$_GET["uid"]."','".$_GET["sms"]."','','0')")) { // Nastavení cenových levelů $level[299] = "37";$level[399] = "34";$level[499] = "36"; // Odeslání odpovědi $zprava_OK = "Vas kod je ".$kod.";".$level[$text]; header('Content-Type: text/plain; charset=UTF-8'); echo $zprava_OK; exit; } } else { header("HTTP/1.1 204 No Content"); header('Content-Type: text/plain; charset=UTF-8'); exit; } } elseif($_GET["ds"]!="") { // Zjištění zda volání je doručení statusu zprávy // Návratové hodnoty ds - status $ds["DELIVERED"] = "SMS byla doručena"; $ds["UNDELIVERED"] = "SMS nebyla a nebude doručena"; $ds["WAITING"] = "SMS čeká na doručení"; $ds["PENDING"] = "SMS je nevyřízena (dojde k jejímu pozdějšímu vyřízení)"; $ds["UNKNOWN"] = "Stav SMS není možné zjistit"; $ds["EXPIRED"] = "Platnost SMS vypršela (již nedojde k jejímu doručení)"; // Návratové hodnoty dm - zpráva $dm["INTERNAL_ERROR"] = "Vnitřní chyba operátora"; $dm["NOT_ENOUGHT_CREDIT"] = "Uživatel nemá dostatečný kredit"; $dm["SERVICE_NOT_ALLOWED"] = "Uživatel má blokovanou službu PREMIUM SMS"; $dm["NO_OPERATOR_CUSTOMER"] = "Uživatel není zákazníkem operátora, ke kterému byla SMS zaslána"; $dm["USAGE_RATE_EXCEEDED"] = "Uživatel překročil povolený limit svého účtu"; $dm["MT_SERVICE_NOT_ALLOWED"] = "Uživatel má blokované MT biling zprávy"; $dm["CUSTOMER_IS_BLOCKED"] = "Uživatel je operátorem blokován"; $dm["DAILY_LIMIT_EXCEEDED"] = "Uživatel překročil denní limit pro platby PR SMS"; $dm["UNKNOWN"] = "Důvod nedoručení je neznámý"; $dm["USER_BLACKLISTED"] = "Uživatel je operátorem blokován pro nehrazení služeb"; $status = $_GET["ds"]; $zprava = $_GET["dm"]; // Uložení statusu do db // Tvar záznamu v buňce status_sms: Doručena/Nedoručena;pokud ne tak dúvod;čas doručení; číslo doručenky; Request ID $sql = "UPDATE sms SET "; if($status == "UNDELIVERED") { $sql .= "status_sms='".$ds[$status].";".$dm[$zprava].";".$_GET["dt"].";".$_GET["dn"].";".$_GET["rid"]."'"; } else { $sql .= "status_sms='".$ds[$status].";;".$_GET["dt"].";".$_GET["dn"].";".$_GET["rid"]."'"; } if($status == "DELIVERED") $sql .= ",overeni_sms='1'"; $sql .= " WHERE ident_airtoy_sms='".$_GET["rid"]."'"; //echo $sql; @mysql_query($sql); exit; } else { // Nebyly předány všechny parametry header('Content-Type: text/plain; charset=UTF-8'); exit; } } |
||
Keeehi Profil |
#18 · Zasláno: 25. 8. 2012, 12:19:09
zkuste vynechat ob_start()
|
||
Prefin Profil |
#19 · Zasláno: 25. 8. 2012, 12:30:17
To jsem už zkoušel.
Když ho vynechám, tak to pošle BOM: Vas kod je 87926922;36 Kód je v utf-8 a ukládání BOM mám vypnuté. |
||
Keeehi Profil |
#20 · Zasláno: 25. 8. 2012, 12:52:17
Bom může být i v těch includovaných scriptech.
|
||
Mike8748 Profil |
#21 · Zasláno: 25. 8. 2012, 14:04:02
Prefin:
hlavně je třeba znovu vytvořit (tím nemyslim uložit) ten soubor. jak už v něm jednou BOM je, tak vypnutí vkládání v editoru nepomůže (pokud tam BOM je tak ji editor sám od sebe nevymaže) |
||
Keeehi Profil |
#22 · Zasláno: 25. 8. 2012, 14:19:48
Mike8748:
„jak už v něm jednou BOM je, tak vypnutí vkládání v editoru nepomůže“ Toto nemusí být pravda. Například PSPad BOM aktivně maže. |
||
Prefin Profil |
#23 · Zasláno: 25. 8. 2012, 16:42:34
Už jsem na to přišel a jako vždy - chyba je mezi židlí a klávesnicí.
Žádné vypisování před hlavičkou, žádný BOM jenom moje blbost. 1. Když jsem to testoval z web-snifferu tak jsem zapoměl povolit další ip takže mi to padalo do větve, kde jsem ještě header(...204) neměl. 2. Testovací script Airtoy asi neumí validovat odpovědi jiné než 200 - povolenou chybu 204 označuje pravděpodobně za chybný status. Takže to pořád mátlo ze dvou stran, přitom to běží správně. Díky za pomoc. |
||
Časová prodleva: 12 let
|
0