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 { | |
10 | public static class EncodingException extends RequestRestart { | |
11 | public EncodingException(String msg) { | |
12 | super(msg); | |
13 | } | |
14 | ||
15 | public void respond(Request req) { | |
16 | throw(Restarts.stdresponse(400, "Invalid parameter encoding", getMessage())); | |
17 | } | |
18 | } | |
19 | ||
20 | public static MultiMap<String, String> urlparams(String q) { | |
21 | try { | |
22 | MultiMap<String, String> ret = new WrappedMultiMap<String, String>(new TreeMap<String, Collection<String>>()); | |
23 | String st = "key"; | |
24 | String key = null; /* Java is stupid. */ | |
25 | MixedBuffer buf = new MixedBuffer(); | |
26 | int i = 0; | |
27 | while(true) { | |
28 | int c = (i >= q.length())?-1:(q.charAt(i++)); | |
29 | if(st == "key") { | |
30 | if(c == '%') { | |
31 | if(q.length() - i < 2) | |
32 | throw(new EncodingException("Invalid character escape")); | |
33 | try { | |
34 | buf.append((byte)((Misc.hex2int(q.charAt(i)) << 4) | Misc.hex2int(q.charAt(i + 1)))); | |
35 | } catch(NumberFormatException e) { | |
36 | throw(new EncodingException("Invalid character escape")); | |
37 | } | |
38 | i += 2; | |
39 | } else if(c == '=') { | |
40 | key = buf.convert(); | |
41 | buf = new MixedBuffer(); | |
42 | st = "val"; | |
43 | } else if(c == '&') { | |
44 | ret.add(buf.convert(), ""); | |
45 | buf = new MixedBuffer(); | |
46 | } else if(c == -1) { | |
47 | if(buf.size() == 0) { | |
48 | break; | |
49 | } else { | |
50 | ret.add(buf.convert(), ""); | |
51 | buf = new MixedBuffer(); | |
52 | } | |
53 | } else { | |
54 | buf.append((char)c); | |
55 | } | |
56 | } else if(st == "val") { | |
57 | if(c == '%') { | |
58 | if(q.length() - i < 2) | |
59 | throw(new EncodingException("Invalid character escape")); | |
60 | try { | |
61 | buf.append((byte)((Misc.hex2int(q.charAt(i)) << 4) | Misc.hex2int(q.charAt(i + 1)))); | |
62 | } catch(NumberFormatException e) { | |
63 | throw(new EncodingException("Invalid character escape")); | |
64 | } | |
65 | i += 2; | |
66 | } else if((c == '&') || (c == -1)) { | |
67 | ret.add(key, buf.convert()); | |
68 | buf = new MixedBuffer(); | |
69 | st = "key"; | |
70 | } else if(c == '+') { | |
71 | buf.append(' '); | |
72 | } else { | |
73 | buf.append((char)c); | |
74 | } | |
75 | } | |
76 | } | |
77 | return(ret); | |
78 | } catch(CharacterCodingException e) { | |
79 | throw(new EncodingException("Escaped parameter text is not proper UTF-8")); | |
80 | } | |
81 | } | |
82 | ||
83 | public static MultiMap<String, String> urlparams(URL url) { | |
84 | return(urlparams(url.getQuery())); | |
85 | } | |
86 | ||
87 | public static MultiMap<String, String> urlparams(Request req) { | |
88 | return(urlparams(req.url())); | |
89 | } | |
90 | ||
91 | public static String encquery(Map<String, String> pars) { | |
92 | StringBuilder buf = new StringBuilder(); | |
93 | boolean f = true; | |
94 | for(Map.Entry<String, String> par : pars.entrySet()) { | |
95 | if(!f) | |
96 | buf.append('&'); | |
97 | buf.append(Misc.urlq(par.getKey())); | |
98 | buf.append('='); | |
99 | buf.append(Misc.urlq(par.getValue())); | |
100 | f = false; | |
101 | } | |
102 | return(buf.toString()); | |
103 | } | |
104 | } |