1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs2.provider;
18
19 import org.apache.commons.vfs2.FileName;
20 import org.apache.commons.vfs2.FileSystemException;
21 import org.apache.commons.vfs2.FileSystemManager;
22 import org.apache.commons.vfs2.FileType;
23 import org.apache.commons.vfs2.VFS;
24 import org.apache.commons.vfs2.util.Cryptor;
25 import org.apache.commons.vfs2.util.CryptorFactory;
26
27
28
29
30
31
32
33
34
35 public class HostFileNameParser extends AbstractFileNameParser {
36
37
38
39 protected static class Authority {
40 private String hostName;
41 private String password;
42 private int port;
43 private String scheme;
44 private String userName;
45
46
47
48
49
50
51
52 public String getHostName() {
53 return hostName;
54 }
55
56
57
58
59
60
61
62 public String getPassword() {
63 return password;
64 }
65
66
67
68
69
70
71
72 public int getPort() {
73 return port;
74 }
75
76
77
78
79
80
81
82 public String getScheme() {
83 return scheme;
84 }
85
86
87
88
89
90
91
92 public String getUserName() {
93 return userName;
94 }
95
96
97
98
99
100
101
102 public void setHostName(final String hostName) {
103 this.hostName = hostName;
104 }
105
106
107
108
109
110
111
112 public void setPassword(final String password) {
113 this.password = password;
114 }
115
116
117
118
119
120
121
122 public void setPort(final int port) {
123 this.port = port;
124 }
125
126
127
128
129
130
131
132 public void setScheme(final String scheme) {
133 this.scheme = scheme;
134 }
135
136
137
138
139
140
141
142 public void setUserName(final String userName) {
143 this.userName = userName;
144 }
145 }
146
147 private final int defaultPort;
148
149 public HostFileNameParser(final int defaultPort) {
150 this.defaultPort = defaultPort;
151 }
152
153
154
155
156
157
158
159 protected String extractHostName(final StringBuilder name) {
160 final int maxlen = name.length();
161 int pos = 0;
162 for (; pos < maxlen; pos++) {
163 final char ch = name.charAt(pos);
164 if (ch == '/' || ch == ';' || ch == '?' || ch == ':' || ch == '@' || ch == '&' || ch == '=' || ch == '+'
165 || ch == '$' || ch == ',') {
166 break;
167 }
168 }
169 if (pos == 0) {
170 return null;
171 }
172
173 final String hostname = name.substring(0, pos);
174 name.delete(0, pos);
175 return hostname;
176 }
177
178
179
180
181
182
183
184
185
186
187
188 protected int extractPort(final StringBuilder name, final String uri) throws FileSystemException {
189 if (name.length() < 1 || name.charAt(0) != ':') {
190 return -1;
191 }
192
193 final int maxlen = name.length();
194 int pos = 1;
195 for (; pos < maxlen; pos++) {
196 final char ch = name.charAt(pos);
197 if (ch < '0' || ch > '9') {
198 break;
199 }
200 }
201
202 final String port = name.substring(1, pos);
203 name.delete(0, pos);
204 if (port.isEmpty()) {
205 throw new FileSystemException("vfs.provider/missing-port.error", uri);
206 }
207
208 return Integer.parseInt(port);
209 }
210
211
212
213
214
215
216
217
218
219
220 @Deprecated
221 protected Authority extractToPath(final String uri, final StringBuilder name) throws FileSystemException {
222 return extractToPath(null, uri, name);
223 }
224
225
226
227
228
229
230
231
232
233
234 protected Authority extractToPath(final VfsComponentContext context, final String uri, final StringBuilder name) throws FileSystemException {
235 final Authority auth = new Authority();
236
237 final FileSystemManager fsm;
238 if (context != null) {
239 fsm = context.getFileSystemManager();
240 } else {
241 fsm = VFS.getManager();
242 }
243
244
245 auth.scheme = UriParser.extractScheme(fsm.getSchemes(), uri, name);
246
247
248 if (name.length() < 2 || name.charAt(0) != '/' || name.charAt(1) != '/') {
249 throw new FileSystemException("vfs.provider/missing-double-slashes.error", uri);
250 }
251 name.delete(0, 2);
252
253
254 final String userInfo = extractUserInfo(name);
255 final String userName;
256 final String password;
257 if (userInfo != null) {
258 final int idx = userInfo.indexOf(':');
259 if (idx == -1) {
260 userName = userInfo;
261 password = null;
262 } else {
263 userName = userInfo.substring(0, idx);
264 password = userInfo.substring(idx + 1);
265 }
266 } else {
267 userName = null;
268 password = null;
269 }
270 auth.userName = UriParser.decode(userName);
271 auth.password = UriParser.decode(password);
272
273 if (auth.password != null && auth.password.startsWith("{") && auth.password.endsWith("}")) {
274 try {
275 final Cryptor cryptor = CryptorFactory.getCryptor();
276 auth.password = cryptor.decrypt(auth.password.substring(1, auth.password.length() - 1));
277 } catch (final Exception ex) {
278 throw new FileSystemException("Unable to decrypt password", ex);
279 }
280 }
281
282
283 final String hostName = extractHostName(name);
284 if (hostName == null) {
285 throw new FileSystemException("vfs.provider/missing-hostname.error", uri);
286 }
287 auth.hostName = hostName.toLowerCase();
288
289
290 auth.port = extractPort(name, uri);
291
292
293 if (name.length() > 0 && name.charAt(0) != '/') {
294 throw new FileSystemException("vfs.provider/missing-hostname-path-sep.error", uri);
295 }
296
297 return auth;
298 }
299
300
301
302
303
304
305
306 protected String extractUserInfo(final StringBuilder name) {
307 final int maxlen = name.length();
308 for (int pos = 0; pos < maxlen; pos++) {
309 final char ch = name.charAt(pos);
310 if (ch == '@') {
311
312 final String userInfo = name.substring(0, pos);
313 name.delete(0, pos + 1);
314 return userInfo;
315 }
316 if (ch == '/' || ch == '?') {
317
318 break;
319 }
320 }
321
322
323 return null;
324 }
325
326 public int getDefaultPort() {
327 return defaultPort;
328 }
329
330 @Override
331 public FileName parseUri(FileNameal VfsComponentContext context, final FileName base, final String fileName)
332 throws FileSystemException {
333
334 final StringBuilder name = new StringBuilder();
335
336
337 final Authority auth = extractToPath(context, fileName, name);
338
339
340 UriParser.canonicalizePath(name, 0, name.length(), this);
341 UriParser.fixSeparators(name);
342 final FileType fileType = UriParser.normalisePath(name);
343 final String path = name.toString();
344
345 return new GenericFileName(auth.scheme, auth.hostName, auth.port, defaultPort, auth.userName, auth.password,
346 path, fileType);
347 }
348 }