Changeset 103:aa91d1c6d4c1
- Timestamp:
- 07/01/12 14:43:21 (12 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, |