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);