Commit | Line | Data |
---|---|---|
efa9722b FT |
1 | package dolda.jsvc.util; |
2 | ||
3 | import dolda.jsvc.*; | |
4 | import java.util.*; | |
5 | import java.io.*; | |
6 | import java.net.*; | |
7 | import java.nio.charset.CharacterCodingException; | |
8 | ||
9 | public class Params { | |
141e5e3c | 10 | public static class EncodingException extends ClientError { |
efa9722b | 11 | public EncodingException(String msg) { |
141e5e3c | 12 | super("Invalid parameter encoding", msg); |
efa9722b FT |
13 | } |
14 | } | |
15 | ||
d7bc1a7a | 16 | public static MultiMap<String, String> urlparams(Reader in) throws IOException { |
efa9722b FT |
17 | try { |
18 | MultiMap<String, String> ret = new WrappedMultiMap<String, String>(new TreeMap<String, Collection<String>>()); | |
19 | String st = "key"; | |
20 | String key = null; /* Java is stupid. */ | |
21 | MixedBuffer buf = new MixedBuffer(); | |
efa9722b | 22 | while(true) { |
d7bc1a7a | 23 | int c = in.read(); |
efa9722b FT |
24 | if(st == "key") { |
25 | if(c == '%') { | |
efa9722b | 26 | try { |
d7bc1a7a FT |
27 | int d1 = in.read(); |
28 | int d2 = in.read(); | |
29 | buf.append((byte)((Misc.hex2int((char)d1) << 4) | Misc.hex2int((char)d2))); | |
efa9722b FT |
30 | } catch(NumberFormatException e) { |
31 | throw(new EncodingException("Invalid character escape")); | |
32 | } | |
efa9722b FT |
33 | } else if(c == '=') { |
34 | key = buf.convert(); | |
35 | buf = new MixedBuffer(); | |
36 | st = "val"; | |
37 | } else if(c == '&') { | |
38 | ret.add(buf.convert(), ""); | |
39 | buf = new MixedBuffer(); | |
40 | } else if(c == -1) { | |
41 | if(buf.size() == 0) { | |
42 | break; | |
43 | } else { | |
44 | ret.add(buf.convert(), ""); | |
45 | buf = new MixedBuffer(); | |
46 | } | |
47 | } else { | |
48 | buf.append((char)c); | |
49 | } | |
50 | } else if(st == "val") { | |
51 | if(c == '%') { | |
efa9722b | 52 | try { |
d7bc1a7a FT |
53 | int d1 = in.read(); |
54 | int d2 = in.read(); | |
55 | buf.append((byte)((Misc.hex2int((char)d1) << 4) | Misc.hex2int((char)d2))); | |
efa9722b FT |
56 | } catch(NumberFormatException e) { |
57 | throw(new EncodingException("Invalid character escape")); | |
58 | } | |
efa9722b FT |
59 | } else if((c == '&') || (c == -1)) { |
60 | ret.add(key, buf.convert()); | |
61 | buf = new MixedBuffer(); | |
62 | st = "key"; | |
63 | } else if(c == '+') { | |
64 | buf.append(' '); | |
65 | } else { | |
66 | buf.append((char)c); | |
67 | } | |
68 | } | |
69 | } | |
70 | return(ret); | |
71 | } catch(CharacterCodingException e) { | |
72 | throw(new EncodingException("Escaped parameter text is not proper UTF-8")); | |
73 | } | |
74 | } | |
75 | ||
d7bc1a7a FT |
76 | public static MultiMap<String, String> urlparams(String q) { |
77 | try { | |
78 | return(urlparams(new StringReader(q))); | |
79 | } catch(IOException e) { | |
80 | /* This will, of course, never ever once happen, but do | |
81 | * you think Javac cares? */ | |
82 | throw(new Error(e)); | |
83 | } | |
84 | } | |
85 | ||
efa9722b | 86 | public static MultiMap<String, String> urlparams(URL url) { |
ca045757 FT |
87 | String q = url.getQuery(); |
88 | if(q == null) | |
89 | q = ""; | |
90 | return(urlparams(q)); | |
efa9722b FT |
91 | } |
92 | ||
93 | public static MultiMap<String, String> urlparams(Request req) { | |
94 | return(urlparams(req.url())); | |
95 | } | |
96 | ||
97 | public static String encquery(Map<String, String> pars) { | |
98 | StringBuilder buf = new StringBuilder(); | |
99 | boolean f = true; | |
100 | for(Map.Entry<String, String> par : pars.entrySet()) { | |
101 | if(!f) | |
102 | buf.append('&'); | |
103 | buf.append(Misc.urlq(par.getKey())); | |
104 | buf.append('='); | |
105 | buf.append(Misc.urlq(par.getValue())); | |
106 | f = false; | |
107 | } | |
108 | return(buf.toString()); | |
109 | } | |
ca045757 FT |
110 | |
111 | public static MultiMap<String, String> postparams(Request req) { | |
112 | if(req.method() != "POST") | |
113 | return(null); | |
ca045757 FT |
114 | String ctype = req.inheaders().get("Content-Type"); |
115 | if(ctype == null) | |
116 | return(null); | |
117 | ctype = ctype.toLowerCase(); | |
118 | if(ctype.equals("application/x-www-form-urlencoded")) { | |
ca045757 FT |
119 | byte[] data; |
120 | try { | |
d7bc1a7a | 121 | return(urlparams(new InputStreamReader(req.input(), "UTF-8"))); |
ca045757 FT |
122 | } catch(IOException e) { |
123 | return(null); | |
124 | } | |
ca045757 FT |
125 | } |
126 | return(null); | |
127 | } | |
80e2f848 FT |
128 | |
129 | public static MultiMap<String, String> stdparams(Request req) { | |
130 | MultiMap<String, String> params = Params.urlparams(req); | |
131 | if(req.method() == "POST") { | |
132 | MultiMap<String, String> pp = Params.postparams(req); | |
133 | if(pp != null) | |
134 | params.putAll(pp); | |
135 | } | |
136 | return(params); | |
137 | } | |
efa9722b | 138 | } |