Skip to content

Commit bd37505

Browse files
committed
allowing x-www-encoded file transfer; bug in GET
missing the & between items n GET
1 parent cd55f14 commit bd37505

File tree

2 files changed

+79
-43
lines changed

2 files changed

+79
-43
lines changed

sources/net.sf.j2s.java.core/src/javajs/http/JavaHttpPoster.java

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,57 @@
1919
*
2020
* adapted from https://github.com/atulsm/https-multipart-purejava
2121
*
22+
* 2023.12.21 BH fixed to allow x-www-encoding
23+
*
2224
* @author Bob Hanson
2325
*
2426
*/
2527
public class JavaHttpPoster {
2628

27-
public static void post(HttpURLConnection conn, List<FormData> formData) throws IOException {
28-
String boundary = "---" + System.nanoTime() + "---";
29-
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
30-
OutputStream os = conn.getOutputStream();
31-
for (int i = 0; i < formData.size(); i++) {
32-
FormData data = formData.get(i);
33-
String name = data.getName();
34-
Object value = data.getData();
35-
String contentType = data.getContentType();
36-
String fileName = data.getFileName();
37-
append(os, "--" + boundary + "\r\n");
38-
append(os, "Content-Disposition: form-data; name=\"" + name
39-
+ (fileName == null ? "" : "\"; filename=\"" + fileName) + "\"");
40-
append(os, "\r\nContent-Type: ");
41-
append(os, contentType == null ? "application/octet-stream" : contentType);
42-
append(os, "\r\n\r\n");
43-
append(os, value);
44-
append(os, "\r\n");
45-
}
46-
append(os, "\r\n--" + boundary + "--\r\n");
47-
os.flush();
29+
public static void post(HttpURLConnection conn, List<FormData> formData, boolean isWWWEncoded) throws IOException {
30+
31+
conn.setRequestMethod("POST");
32+
33+
// isWWWEncoded is from setting
34+
// request.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
35+
36+
if (isWWWEncoded) {
37+
OutputStream os = conn.getOutputStream();
38+
append(os, SimpleHttpClient.wwwEncode(formData));
39+
os.flush();
40+
} else {
41+
String boundary = "---" + System.nanoTime() + "---";
42+
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
43+
OutputStream os = conn.getOutputStream();
44+
for (int i = 0; i < formData.size(); i++) {
45+
FormData data = formData.get(i);
46+
String name = data.getName();
47+
Object value = data.getData();
48+
String contentType = data.getContentType();
49+
50+
String fileName = data.getFileName();
51+
append(os, "--" + boundary + "\r\n");
52+
append(os, "Content-Disposition: form-data; name=\"" + name
53+
+ (fileName == null ? "" : "\"; filename=\"" + fileName) + "\"");
54+
if (contentType != null) {
55+
// default is text
56+
append(os, "\r\nContent-Type: ");
57+
append(os, contentType == null ? "application/octet-stream" : contentType);
58+
}
59+
append(os, "\r\n\r\n");
60+
append(os, value);
61+
append(os, "\r\n");
62+
}
63+
append(os, "\r\n--" + boundary + "--\r\n");
64+
os.flush();
65+
}
66+
4867

4968
}
5069

5170
private static void append(OutputStream outputStream, Object val) throws IOException {
71+
72+
//System.out.println("JHP.append " + val);
5273
if (val instanceof byte[]) {
5374
outputStream.write((byte[]) val);
5475
} else {

sources/net.sf.j2s.java.core/src/javajs/http/SimpleHttpClient.java

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,41 @@
4040
* The SimpleHttpClient is very light -- just a constructor and five methods,
4141
* providing limited access to HttpRequest and HttpResponse implementations.
4242
*
43+
* 2023.12.21 BH fixed GET and x-www-encoded POST missing "&" between name=value sets
4344
*
4445
* @author Bob Hanson
4546
* @author Mateusz Warowny
4647
*
4748
*/
4849
public class SimpleHttpClient implements HttpClient {
4950

51+
52+
public static String wwwEncode(List<Request.FormData> queryData) {
53+
Map<String, String> htGetParams = new LinkedHashMap<>();
54+
for (int i = 0; i < queryData.size(); i++) {
55+
Request.FormData fd = queryData.get(i);
56+
htGetParams.put(fd.getName(), fd.getData().toString());
57+
}
58+
String data = "";
59+
for (Entry<String, String> e : htGetParams.entrySet()) {
60+
data += "&" + e.getKey() + "=" + encodeURI(e.getValue());
61+
}
62+
return data.substring(1);
63+
}
64+
65+
public static String encodeURI(String value) {
66+
try {
67+
// convert " " to "%20", not "+"
68+
// based on https://stackoverflow.com/questions/2678551/when-to-encode-space-to-plus-or-20
69+
// Answer # 46. and "URI Generic Syntax " https://tools.ietf.org/html/rfc3986
70+
// This will be consistent, then, with JavaScript encodeURIComponent().
71+
return URLEncoder.encode(value.replace(' ', '\0'), "UTF-8").replaceAll("%00", "%20");
72+
} catch (UnsupportedEncodingException e) {
73+
// impossible
74+
return null;
75+
}
76+
}
77+
5078
SimpleHttpClient() {
5179
// for reflection
5280
}
@@ -186,6 +214,8 @@ String getFileName() {
186214
*/
187215
boolean hasFormBody = false;
188216

217+
private boolean isWWWencoded;
218+
189219
Request(URI uri, String method) {
190220
this.uri = uri;
191221
this.method = method.toUpperCase();
@@ -217,6 +247,9 @@ public URI getUri() {
217247
@Override
218248
public HttpRequest addHeader(String name, String value) {
219249
htHeaders.put(name, value);
250+
if (name.equals("Content-Type") && value.startsWith("application/x-www-form-urlencoded")) {
251+
isWWWencoded = true;
252+
}
220253
return this;
221254
}
222255

@@ -353,31 +386,11 @@ Response fulfillGet(Response r) throws IOException {
353386
private URL createURL() throws MalformedURLException {
354387
String data = "";
355388
if (queryData != null) {
356-
Map<String, String> htGetParams = new LinkedHashMap<>();
357-
for (int i = 0; i < queryData.size(); i++) {
358-
FormData fd = queryData.get(i);
359-
htGetParams.put(fd.getName(), fd.getData().toString());
360-
}
361-
for (Entry<String, String> e : htGetParams.entrySet()) {
362-
data += e.getKey() + "=" + encodeURI(e.getValue());
363-
}
389+
data = wwwEncode(queryData);
364390
}
365391
return (data.length() > 0 ? new URL(uri.toString() + "?" + data) : uri.toURL());
366392
}
367393

368-
private String encodeURI(String value) {
369-
try {
370-
// convert " " to "%20", not "+"
371-
// based on https://stackoverflow.com/questions/2678551/when-to-encode-space-to-plus-or-20
372-
// Answer # 46. and "URI Generic Syntax " https://tools.ietf.org/html/rfc3986
373-
// This will be consistent, then, with JavaScript encodeURIComponent().
374-
return URLEncoder.encode(value.replace(' ', '\0'), "UTF-8").replaceAll("%00", "%20");
375-
} catch (UnsupportedEncodingException e) {
376-
// impossible
377-
return null;
378-
}
379-
}
380-
381394
Response fulfillPost(Response r) throws IOException {
382395
HttpURLConnection conn = getConnection(createURL());
383396
sendFormData(conn, formData);
@@ -392,10 +405,11 @@ private void sendFormData(HttpURLConnection conn, List<FormData> formData) throw
392405
* @j2sIgnore
393406
*/
394407
{
395-
JavaHttpPoster.post(conn, formData);
408+
JavaHttpPoster.post(conn, formData, isWWWencoded);
396409
if (true)
397410
return;
398411
}
412+
// JavaSCript only
399413
for (int i = 0, n = formData.size(); i < n; i++) {
400414
FormData data = formData.get(i);
401415
((AjaxURLConnection) conn).addFormData(data.name, data.data, data.contentType, data.fileName);
@@ -692,4 +706,5 @@ public static HttpRequest createRequest(HttpClient client, String method, String
692706
}
693707
}
694708

709+
695710
}

0 commit comments

Comments
 (0)