Mercurial Hosting > luan
comparison src/luan/modules/url/MultipartClient.java @ 1274:383f924dfe9d
support multipart files in http request
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 04 Dec 2018 06:08:20 -0700 |
parents | 668f29bc52ea |
children | 643cf1c37723 |
comparison
equal
deleted
inserted
replaced
1273:ed6e8bd78c11 | 1274:383f924dfe9d |
---|---|
7 import java.util.ArrayList; | 7 import java.util.ArrayList; |
8 import java.util.Map; | 8 import java.util.Map; |
9 import java.util.HashMap; | 9 import java.util.HashMap; |
10 import luan.LuanTable; | 10 import luan.LuanTable; |
11 import luan.LuanException; | 11 import luan.LuanException; |
12 import luan.webserver.Request; | |
12 | 13 |
13 | 14 |
14 public final class MultipartClient { | 15 public final class MultipartClient { |
15 private static final byte[] __CRLF = {'\r','\n'}; | 16 private static final byte[] __CRLF = {'\r','\n'}; |
16 private static final byte[] __DASHDASH = {'-','-'}; | 17 private static final byte[] __DASHDASH = {'-','-'}; |
17 private static final String __ISO_8859_1 = "ISO-8859-1"; | 18 private static final String __ISO_8859_1 = "ISO-8859-1"; |
18 | 19 |
19 private final Map params = new HashMap(); | 20 private final Map params = new HashMap(); |
20 | 21 |
22 private static Object get(Map<Object,Object> params,String key) throws LuanException { | |
23 Object val = params.remove(key); | |
24 if( val==null) | |
25 throw new LuanException( "parameter '"+key+"' is required in multipart file" ); | |
26 return val; | |
27 } | |
28 | |
29 private static String getString(Map<Object,Object> params,String key) throws LuanException { | |
30 Object val = get(params,key); | |
31 if( !(val instanceof String) ) | |
32 throw new LuanException( "parameter '"+key+"' must be a string" ); | |
33 return (String)val; | |
34 } | |
35 | |
21 MultipartClient(Map params) throws LuanException { | 36 MultipartClient(Map params) throws LuanException { |
22 for( Object hack : params.entrySet() ) { | 37 for( Object hack : params.entrySet() ) { |
23 Map.Entry entry = (Map.Entry)hack; | 38 Map.Entry entry = (Map.Entry)hack; |
24 String key = (String)entry.getKey(); | 39 String key = (String)entry.getKey(); |
25 Object val = entry.getValue(); | 40 Object val = entry.getValue(); |
26 List list = new ArrayList(); | 41 List list = new ArrayList(); |
27 if( val instanceof String ) { | 42 if( val instanceof String ) { |
28 list.add(val); | 43 list.add(val); |
44 } else if(val instanceof LuanTable) { | |
45 LuanTable t = (LuanTable)val; | |
46 if( t.isList() ) { | |
47 for( Object obj : t.asList() ) { | |
48 if( obj instanceof String ) { | |
49 list.add(obj); | |
50 } else | |
51 throw new LuanException( "parameter '"+key+"' values must be strings or tables" ); | |
52 } | |
53 } else { | |
54 Map<Object,Object> map = t.asMap(); | |
55 String filename = getString(map,"filename"); | |
56 String contentType = getString(map,"content_type"); | |
57 Object content = get(map,"content"); | |
58 if( !(content instanceof String || content instanceof byte[]) ) | |
59 throw new LuanException( "content must be a string or binary" ); | |
60 list.add( new Request.MultipartFile(filename,contentType,content) ); | |
61 } | |
29 } else { | 62 } else { |
30 if( !(val instanceof LuanTable) ) | 63 throw new LuanException( "parameter '"+key+"' must be string or table" ); |
31 throw new LuanException( "parameter '"+key+"' must be string or table" ); | |
32 LuanTable t = (LuanTable)val; | |
33 if( !t.isList() ) | |
34 throw new LuanException( "parameter '"+key+"' table must be list" ); | |
35 for( Object obj : t.asList() ) { | |
36 if( !(obj instanceof String) ) | |
37 throw new LuanException( "parameter '"+key+"' values must be strings" ); | |
38 list.add(obj); | |
39 } | |
40 } | 64 } |
41 this.params.put(key,list); | 65 this.params.put(key,list); |
42 } | 66 } |
43 } | 67 } |
44 | 68 |
51 for( Object hack : params.entrySet() ) { | 75 for( Object hack : params.entrySet() ) { |
52 Map.Entry entry = (Map.Entry)hack; | 76 Map.Entry entry = (Map.Entry)hack; |
53 String name = (String)entry.getKey(); | 77 String name = (String)entry.getKey(); |
54 List list = (List)entry.getValue(); | 78 List list = (List)entry.getValue(); |
55 for( Object obj : list ) { | 79 for( Object obj : list ) { |
56 String val = (String)obj; | |
57 out.write(__DASHDASH); | 80 out.write(__DASHDASH); |
58 out.write(boundaryBytes); | 81 out.write(boundaryBytes); |
59 out.write(__CRLF); | 82 out.write(__CRLF); |
60 out.write(("Content-Disposition: form-data; name=\""+name+"\"").getBytes(__ISO_8859_1)); | 83 out.write(("Content-Disposition: form-data; name=\""+name+"\"").getBytes(__ISO_8859_1)); |
61 out.write(__CRLF); | 84 if( obj instanceof String ) { |
62 out.write(__CRLF); | 85 String val = (String)obj; |
63 out.write(val.getBytes()); | 86 out.write(__CRLF); |
87 out.write(__CRLF); | |
88 out.write(val.getBytes()); | |
89 } else { | |
90 Request.MultipartFile mpf = (Request.MultipartFile)obj; | |
91 out.write(("; filename=\""+mpf.filename+"\"").getBytes(__ISO_8859_1)); | |
92 out.write(__CRLF); | |
93 out.write(("Content-Type: "+mpf.contentType).getBytes(__ISO_8859_1)); | |
94 out.write(__CRLF); | |
95 out.write(__CRLF); | |
96 byte[] content = mpf.content instanceof String ? ((String)mpf.content).getBytes() : (byte[])mpf.content; | |
97 out.write(content); | |
98 } | |
64 out.write(__CRLF); | 99 out.write(__CRLF); |
65 } | 100 } |
66 } | 101 } |
67 out.write(__DASHDASH); | 102 out.write(__DASHDASH); |
68 out.write(boundaryBytes); | 103 out.write(boundaryBytes); |