Changeset 103:aa91d1c6d4c1
- Timestamp:
- 07/01/12 14:43:21 (13 years ago)
- Author:
- František Kučera <franta-hg@…>
- Branch:
- default
- Message:
-
#20 Skriptování: možnost spouštět skripty ze souborů (atribut: src).
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r102
|
r103
|
|
| 22 | 22 | |
| 23 | 23 | <p> |
| 24 | | Díky skriptování můžeme stránky obohatit o prakticky libovolný obsah. |
| 25 | | Tato funkce ale může být nebezpečná – pokud byste spustili generátor na stránkách, |
| | 24 | Díky skriptování můžeme stránky obohatit o prakticky libovolný obsah – |
| | 25 | jak prostý text, tak i XHTML fragmenty.<m:podČarou>zapíná se pomocí atributu |
| | 26 | <code>výstup="xml"</code> a generátor pak kontroluje správné formátování – |
| | 27 | nestane se vám, že byste omylem vygenerovali stránky s překříženými nebo neuzavřenými značkami.</m:podČarou> |
| | 28 | </p> |
| | 29 | <p> |
| | 30 | Skriptování ale může být nebezpečné, pokud byste spustili generátor na stránkách, |
| 26 | 31 | které psal někdo nedůvěryhodný a vložil do nich škodlivý kód. |
| | 32 | Kromě toho, ukázková sada stránek by měla být přeložitelná kdekoli a mít minimum závislostí |
| | 33 | (ne každý musí mít nainstalovaný Perl nebo Python či další podporované interprety). |
| 27 | 34 | Proto je skriptování ve výchozím stavu vypnuté – je potřeba ho povolit v souboru <code>web.conf</code>. |
| 28 | 35 | </p> |
| … |
… |
|
| 41 | 48 | </thead> |
| 42 | 49 | <tbody> |
| 43 | | <m:skript jazyk="perl" výstup="xml"><![CDATA[ |
| | 50 | <m:skript jazyk="perl" výstup="xml"><![CDATA[ |
| 44 | 51 | use strict; |
| | 52 | use warnings; |
| 45 | 53 | |
| 46 | 54 | open(JAVA, "<", $ENV{"XWG_SKRIPTOVANI_JAVA"}) or die $!; |
| … |
… |
|
| 63 | 71 | <pre><m:skript jazyk="perl"><![CDATA[ |
| 64 | 72 | use strict; |
| | 73 | use warnings; |
| 65 | 74 | |
| 66 | 75 | open(XML, "<", $ENV{"XWG_STRANKA_SOUBOR"}); |
| … |
… |
|
| 110 | 119 | </thead> |
| 111 | 120 | <tbody> |
| 112 | | <m:skript jazyk="perl" výstup="xml"><![CDATA[ |
| 113 | | use strict; |
| 114 | | |
| 115 | | open(JAVA, "<", $ENV{"XWG_SKRIPTOVANI_JAVA"}) or die $!; |
| 116 | | |
| 117 | | while (<JAVA>) { |
| 118 | | #i.put("bash", "/bin/bash"); |
| 119 | | if (/"(.*)=".*\/\/\s+env:(.*)/) { |
| 120 | | print "<tr><td><code>$1</code></td><td>$2</td></tr>\n"; |
| 121 | | } |
| 122 | | } |
| 123 | | ]]></m:skript> |
| | 121 | <!-- Pokud načítáme skript ze souboru, je atribut jazyk nepovinný. --> |
| | 122 | <m:skript jazyk="perl" výstup="xml" src="skriptování-proměnné.pl"/> |
| 124 | 123 | </tbody> |
| 125 | 124 | </table> |
-
|
r101
|
r103
|
|
| 56 | 56 | * než jen vložení do souboru a přidání správného záhlaví. |
| 57 | 57 | * |
| 58 | | * @param skript program k vykonání |
| | 58 | * @param skriptText skript k vykonání |
| | 59 | * @param skriptSoubor cesta k souboru se skriptem/programem |
| 59 | 60 | * @param jazyk programovací jazyk |
| 60 | 61 | * @param výstupníFormát text (výchozí) | xml (v tom případě kontrolujeme validitu) |
| … |
… |
|
| 64 | 65 | * @return výstup příkazu |
| 65 | 66 | */ |
| 66 | | public static String interpretuj(String skript, String jazyk, String výstupníFormát, String uriStránky, String nadpisStránky, String perexStránky) { |
| | 67 | public static String interpretuj(String skriptText, String skriptSoubor, String jazyk, String výstupníFormát, String uriStránky, String nadpisStránky, String perexStránky) { |
| 67 | 68 | try { |
| 68 | | System.err.println("\tInterpretuji skript v jazyce: " + jazyk); |
| 69 | | String interpret = interpreti.get(jazyk); |
| 70 | | if (interpret == null) { |
| 71 | | System.err.println("Neznámý skriptovací jazyk: " + jazyk); |
| 72 | | return null; |
| | 69 | if (isNeprázdný(skriptSoubor)) { |
| | 70 | System.err.println("\tInterpretuji skript ze souboru: " + skriptSoubor); |
| 73 | 71 | } else { |
| 74 | | File f = File.createTempFile("xml-web-generátor-", ".skript"); |
| | 72 | System.err.println("\tInterpretuji skript v jazyce: " + jazyk); |
| | 73 | } |
| | 74 | |
| | 75 | File souborStránky = new File(new URI(uriStránky)); |
| | 76 | File f; |
| | 77 | |
| | 78 | if (isNeprázdný(skriptText)) { |
| | 79 | /** Skript je zadán uvnitř elementu přímo ve stránce */ |
| | 80 | String interpret = interpreti.get(jazyk); |
| | 81 | if (interpret == null) { |
| | 82 | throw new Exception("Neznámý skriptovací jazyk: " + jazyk); |
| | 83 | } |
| | 84 | |
| | 85 | f = File.createTempFile("xml-web-generátor-", ".skript"); |
| 75 | 86 | f.deleteOnExit(); |
| | 87 | f.setExecutable(true); |
| 76 | 88 | |
| 77 | 89 | PrintStream ps = new PrintStream(f); |
| … |
… |
|
| 79 | 91 | ps.println(interpret); |
| 80 | 92 | ps.println(); |
| 81 | | ps.print(skript); |
| | 93 | ps.print(skriptText); |
| 82 | 94 | ps.close(); |
| | 95 | } else if (isNeprázdný(skriptSoubor)) { |
| | 96 | /** Skript/program je uložen v externím souboru */ |
| | 97 | if (skriptSoubor.startsWith(File.separator)) { |
| | 98 | /** absolutní cesta */ |
| | 99 | f = new File(skriptSoubor); |
| | 100 | } else { |
| | 101 | /** relativní cesta */ |
| | 102 | f = new File(souborStránky.getParent(), File.separatorChar + skriptSoubor); |
| | 103 | } |
| | 104 | |
| | 105 | if (!f.canExecute()) { |
| | 106 | throw new Exception("Soubor se skriptem není spustitelný → nastavte: chmod +x " + f); |
| | 107 | } |
| | 108 | } else { |
| | 109 | throw new Exception("Musí být vyplněn text skriptu, nebo cesta k souboru."); |
| | 110 | } |
| 83 | 111 | |
| 84 | 112 | |
| 85 | | String[] prostředí = new String[]{ |
| 86 | | "LANG=" + System.getenv("LANG"), |
| 87 | | "USER=" + System.getenv("USER"), |
| 88 | | "XWG_SKRIPTOVANI_JAVA=" + "šablona" + File.separator + "funkce" + File.separator + "src" + File.separator + Skriptování.class.getName().replaceAll("\\.", File.separator) + ".java", |
| 89 | | "XWG_STRANKA_URI=" + uriStránky, // env:URI aktuálně zpracovávané stránky |
| 90 | | "XWG_STRANKA_SOUBOR=" + (new File(new URI(uriStránky)).getAbsolutePath()), // env:absolutní cesta k souboru |
| 91 | | "XWG_STRANKA_NADPIS=" + nadpisStránky, // env:nadpis stránky |
| 92 | | "XWG_STRANKA_PEREX=" + perexStránky // env:perex stránky |
| 93 | | }; |
| | 113 | String[] prostředí = new String[]{ |
| | 114 | "LANG=" + System.getenv("LANG"), |
| | 115 | "USER=" + System.getenv("USER"), |
| | 116 | "XWG_SKRIPTOVANI_JAVA=" + "šablona" + File.separator + "funkce" + File.separator + "src" + File.separator + Skriptování.class.getName().replaceAll("\\.", File.separator) + ".java", |
| | 117 | "XWG_STRANKA_URI=" + uriStránky, // env:URI aktuálně zpracovávané stránky |
| | 118 | "XWG_STRANKA_SOUBOR=" + souborStránky.getAbsolutePath(), // env:absolutní cesta k souboru |
| | 119 | "XWG_STRANKA_NADPIS=" + nadpisStránky, // env:nadpis stránky |
| | 120 | "XWG_STRANKA_PEREX=" + perexStránky // env:perex stránky |
| | 121 | }; |
| 94 | 122 | |
| 95 | | f.setExecutable(true); |
| 96 | | Runtime r = Runtime.getRuntime(); |
| 97 | | Process p = r.exec(new String[]{f.getAbsolutePath()}, prostředí); |
| | 123 | Runtime r = Runtime.getRuntime(); |
| | 124 | Process p = r.exec(new String[]{f.getAbsolutePath()}, prostředí); |
| 98 | 125 | |
| 99 | | String výsledek = načtiProud(p.getInputStream()); |
| 100 | | String chyby = načtiProud(p.getErrorStream()); |
| | 126 | String výsledek = načtiProud(p.getInputStream()); |
| | 127 | String chyby = načtiProud(p.getErrorStream()); |
| 101 | 128 | |
| 102 | | p.waitFor(); |
| | 129 | p.waitFor(); |
| 103 | 130 | |
| 104 | | if (p.exitValue() == 0) { |
| 105 | | if (chyby.length() > 0) { |
| 106 | | System.err.println("--- Chybový výstup skriptu -----"); |
| 107 | | System.err.println(chyby); |
| 108 | | System.err.println("--------------------------------"); |
| 109 | | System.err.println("Nicméně skript skončil úspěšně, takže pokračujeme dál."); |
| 110 | | } |
| | 131 | if (p.exitValue() == 0) { |
| | 132 | if (chyby.length() > 0) { |
| | 133 | System.err.println("--- Chybový výstup skriptu -----"); |
| | 134 | System.err.println(chyby); |
| | 135 | System.err.println("--------------------------------"); |
| | 136 | System.err.println("Nicméně skript skončil úspěšně, takže pokračujeme dál."); |
| | 137 | } |
| 111 | 138 | |
| 112 | | return připravVýstup(výsledek, výstupníFormát); |
| 113 | | } else { |
| 114 | | System.err.println("--- Standardní výstup skriptu: -----"); |
| 115 | | System.err.println(výsledek); |
| 116 | | System.err.println("--- Cyhbový výstup skriptu: ---------"); |
| 117 | | System.err.println(chyby); |
| 118 | | System.err.println("--------------------------------------"); |
| 119 | | throw new RuntimeException("Návratová hodnota: " + p.exitValue()); |
| 120 | | } |
| | 139 | return připravVýstup(výsledek, výstupníFormát); |
| | 140 | } else { |
| | 141 | System.err.println("--- Standardní výstup skriptu: -----"); |
| | 142 | System.err.println(výsledek); |
| | 143 | System.err.println("--- Cyhbový výstup skriptu: ---------"); |
| | 144 | System.err.println(chyby); |
| | 145 | System.err.println("--------------------------------------"); |
| | 146 | throw new Exception("Návratová hodnota: " + p.exitValue()); |
| 121 | 147 | } |
| 122 | 148 | } catch (Exception e) { |
| 123 | 149 | System.err.println("Došlo k chybě při vykonávání skriptu v jazyce: " + jazyk); |
| 124 | 150 | System.err.println("--------"); |
| 125 | | System.err.println(skript); |
| | 151 | System.err.println(skriptText); |
| 126 | 152 | System.err.println("--------"); |
| 127 | 153 | e.printStackTrace(System.err); |
| … |
… |
|
| 144 | 170 | } |
| 145 | 171 | |
| | 172 | private static boolean isNeprázdný(String s) { |
| | 173 | return !(s == null || s.trim().isEmpty()); |
| | 174 | } |
| | 175 | |
| 146 | 176 | /** |
| 147 | 177 | * @param xml fragment XML vygenerovaný skriptem |
-
|
r96
|
r103
|
|
| 29 | 29 | Skriptování |
| 30 | 30 | *********** |
| 31 | | Provedeme skript zadaný v těle elementu a jeho výstup vložíme do stránky. |
| | 31 | Provedeme skript zadaný v těle elementu nebo v souboru a jeho výstup vložíme do stránky. |
| 32 | 32 | * |
| 33 | | @jazyk programovací jazyk, např. bash, perl, php |
| | 33 | @jazyk programovací jazyk, např. bash, perl, php (nepovinné, pokud je vyplněn atribut src) |
| 34 | 34 | @výstup formát výstupu skriptu: text (výchozí) | xml (musí být validním fragmentem XML) |
| | 35 | @src soubor se skriptem/programem (volitelný parametr – buď zadáme skript do těla elementu, nebo nastavíme tento atribut) |
| 35 | 36 | --> |
| 36 | 37 | <xsl:template match="m:skript"> |
| … |
… |
|
| 42 | 43 | <xsl:variable name="výstupSkriptu" select="j:interpretuj( |
| 43 | 44 | text(), |
| | 45 | @src, |
| 44 | 46 | @jazyk, |
| 45 | 47 | @výstup, |