XMLHttpRequest java javascript - java

I try to communicate between javascript and java. My script javascript send a message to java and java send a response.
javascript part:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4)
{
alert(xmlhttp.responseText);
}
}
var s = "LIGNE \n 2 \n il fait beau \nEND\n";
xmlhttp.open("POST","http://localhost:6020",true);
xmlhttp.send(s);
java part:
try {
serverSocket = new ServerSocket(6020);
} catch (IOException e) {
System.err.println("Could not listen on port: 6020.");
System.exit(-1);
}
serverSocket.accept()
BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
String ligne = "";
while(!(ligne = plec.readLine()).equals("END")){
System.out.println(ligne);
}
bw.write("Il fait beau\n");
bw.flush();
bw.close();
plec.close();
socket.close();
output java :
POST / HTTP/1.1
Host: localhost:6020
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost:8080/test.html
Content-Length: 30
Content-Type: text/plain; charset=UTF-8
Origin: http://localhost:8080
Pragma: no-cache
Cache-Control: no-cache
LIGNE
2
il fait beau
So, I receive correctly the message send by javascript but the alert his always empty. How to response at this message?
I try a lot of possiblity but they don't work. And I don't want to use the servlet, it's to heavy to do that.
Thanks.
Edit:
I did this :
bw.write("HTTP/1.1 200 OK\r\n"+
"Content-Type: text/html; charset=utf-8\r\n"+
"Content-Length: 13\r\n\r\n" +
"il fait beau\n");
and this:
String data = "il fait beau \n";
StringBuilder builder = new StringBuilder();
builder.append("HTTP/1.1 200 OK\r\n");
builder.append("Content-Type: text/html; charset=utf-8\r\n");
builder.append("Content-Length:" + data.length() + "\r\n\r\n");
builder.append(data);
bw.write(builder.toString());
But the alert remain empty. Maybe it's a problem in the javascript.

The javascript needs to see a full HTTP response. Merely sending back characters to it, makes it discard the reply as it is an invalid HTTP response.
In your java code, send back something like this
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: <length of data>
---data here---
Reference
Something like:
StringBuilder builder = new StringBuilder();
builder.append("HTTP/1.1 200 OK\r\n");
builder.append("Content-Type: text/plain; charset=utf-8\r\n");
builder.append("Content-Length:" + data.length() + "\r\n\r\n);
builder.append(data);
bw.write(builder.toString());

Try:
bw.write("HTTP/1.1 200 OK\r\n"+
"Content-Type: text/html; charset=utf-8\r\n"+
"Content-Length: 13\r\n\r\n" +
"il fait beau\n");
HTTP-Headers are separated by \r\n (CRLF). Headers and body is spearated by \r\n\r\n.
Note that you set the length to 13 because you also have to count the \n at the end of your string.
EDIT: It does not work because of the cross-domain-policy. http://localhost:6020 is not the same port as the website which executes your JavaScript and so the xmlhttprequest might not be delivered.

Related

BAD Request 400 consume multipart/form-data jersey clientresponse java

I need consume a service, the file is a excel.
But when I execute the consume the response is this "returned a response status of 400 Bad Request"
String authString = name + ":" + password;
Client restClient = Client.create();
String authStringEnc = Base64.getEncoder().encodeToString(authString.getBytes());
// the file to upload, represented as FileDataBodyPart
FileDataBodyPart fileDataBodyPart = new FileDataBodyPart("file", new File(file),
MediaType.APPLICATION_OCTET_STREAM_TYPE);
// fileDataBodyPart.setContentDisposition(FormDataContentDisposition.name("file").fileName(file).build());
FormDataMultiPart multiPart = new FormDataMultiPart();
multiPart.field("spId", idServicio, MediaType.MULTIPART_FORM_DATA_TYPE).bodyPart(fileDataBodyPart);
multiPart.setMediaType(MediaType.MULTIPART_FORM_DATA_TYPE);
WebResource webResource = restClient.resource(url);
ClientResponse resp = webResource.header("Authorization", "Basic " + authStringEnc)
.header("Content-Type", "multipart/form-data").post(ClientResponse.class, multiPart);
String output = resp.getEntity(String.class);
System.out.print(output);
return resp;
I put a proxy and I use the Rest client "insomnia" and it works for me by insomnia.
This is the request that sent it:
INSOMNIA
POST /conf/configuration/distribution-files/service HTTP/1.1
Authorization: Basic aW1wbGluZWE6SU1QTElORUE=
User-Agent: insomnia/7.0.6
Content-Type: multipart/form-data; boundary=X-INSOMNIA-BOUNDARY
Accept: */*
Content-Length: 5872
Connection: close
--X-INSOMNIA-BOUNDARY
Content-Disposition: form-data; name="file"; filename="myspprueba.xls"
Content-Type: application/vnd.ms-excel
--X-INSOMNIA-BOUNDARY
Content-Disposition: form-data; name="spId"
5823
This is the request that at the moment i am failing
POST /conf/configuration/distribution-files/service HTTP/1.1
Authorization: Basic aW1wbGluZWE6SU1QTElORUE=
Accept: */*
Content-Type: multipart/form-data; boundary=Boundary_1_2104028992_1577117786190
MIME-Version: 1.0
User-Agent: Java/1.8.0_211
Connection: close
Content-Length: 5994
--Boundary_1_2104028992_1577117786190
Content-Type: text/plain
Content-Disposition: form-data; filename="myspprueba.xls"; modification-date="Thu, 19 Dec 2019 15:52:46 GMT"; size=5632; name="file"

400 Bad Request on Multipart File Upload

I'm trying to upload an image to the PushBullet API with retrofit.
After the upload-request I fire the multipart upload.
With retrofit I get this error:
{"error":{"code":"invalid_request","type":"invalid_request","message":"Invalid multipart body.","cat":"o(^・x・^)o"},"error_code":"invalid_request"}
The problem only occurs in my java code and not with the PAW HTTP-Client.
# PAW generated Request
POST /upload-legacy/bcSWXnBjNIwpkej7CxfIHFz0ugXO6yhf HTTP/1.1
Content-Type: multipart/form-data; charset=utf-8; boundary=__X_PAW_BOUNDARY__
Host: upload.pushbullet.com
Connection: close
User-Agent: Paw/3.0.12 (Macintosh; OS X/10.11.6) GCDHTTPRequest
Content-Length: 34508
--__X_PAW_BOUNDARY__
Content-Disposition: form-data; name="file"; filename="cat.jpg"
Content-Type: image/jpeg
...
# Retrofit generated Request
POST https://upload.pushbullet.com/upload-legacy/ZZ4fLcqt2WFQmlbKTDlgcYXtB3KiCs3M http/1.1
Content-Type: multipart/form-data; charset=utf-8
Content-Length: 2012
Content-Disposition: form-data; name="file"; filename="1475501429665_motion_detected.jpg"
Content-Type: image/jpeg; charset=utf-8
Content-Length: 1772
...
The important difference I think is the Content-Length in the Part.
I found this issue, but that would mean the PushBullet API is non-compliant with the HTTP specification?
Any help would be appreciated.
I was experiencing this same issue in Google Apps Script, which is JavaScript based, but I'm hoping my solution could help anyone else experiencing this issue. I used TANAIKE's method of building the multipart request here: https://gist.github.com/tanaikech/d595d30a592979bbf0c692d1193d260c
My successful end result looked like this for successfully uploading a JPEG:
// https://docs.pushbullet.com/v8/#upload-request
// Assuming var picResponseJSON is your JSON results from successful upload-request
var uploadJSON = {
awsaccesskeyid: picResponseJSON.data.awsaccesskeyid,
acl: picResponseJSON.data.acl,
key: picResponseJSON.data.key,
signature: picResponseJSON.data.signature,
policy: picResponseJSON.data.policy,
"content-type": picResponseJSON.data["content-type"],
};
// https://gist.github.com/tanaikech/d595d30a592979bbf0c692d1193d260c
var boundary = "xxxxxxxxxx";
var data = "";
for (var i in uploadJSON) {
data += "--" + boundary + "\r\n";
data +=
'Content-Disposition: form-data; name="' +
i +
'"; \r\n\r\n' +
uploadJSON[i] +
"\r\n";
}
data += "--" + boundary + "\r\n";
data +=
'Content-Disposition: form-data; name="file"; filename="' +
fileTitle +
'"\r\n';
data += "Content-Type:" + mimeType + "\r\n\r\n";
var payload = Utilities.newBlob(data)
.getBytes()
.concat(DriveApp.getFileById(fileID).getBlob().getBytes())
.concat(Utilities.newBlob("\r\n--" + boundary + "--").getBytes());
var options3 = {
method: "post",
contentType: "multipart/form-data; boundary=" + boundary,
payload: payload,
muteHttpExceptions: true,
};
// Send request
var uploadResponse = UrlFetchApp.fetch(picResponseJSON.upload_url, options3);
// Confirm it's successful
if (uploadResponse.getResponseCode() == 204) {
console.log("Success! File: " + picResponseJSON.file_url);
}
Please note the Blob functions in the payload are part of Google Apps Script so modify accordingly for your language.

Extracting the body from HTTP post requestH

I have a weird problem when trying to extract the body of a given
HTTP post request.
If I try to extract only the header, it works fine. When I try to extract the body, the method blocks (even thought the stream still has data in it).
Here is my code:
private void extractHeader() throws Exception {
StringBuffer buffer = new StringBuffer();
InputStreamReader reader = new InputStreamReader(socket.getInputStream());
BufferedReader bufferedReader = new BufferedReader(reader);
boolean extractBody = false;
int bodyLength = 0;
String line;
while (!(line = bufferedReader.readLine()).equals("")) {
buffer.append(line + "");
if (line.startsWith("POST")) {
extractBody = true;
}
if (line.startsWith("Content-Length:")) {
bodyLength = Integer.valueOf(line.substring(line.indexOf(' ') + 1, line.length()));
}
}
requestHeader = buffer.toString();
if (extractBody) {
char[] body = new char[bodyLength];
reader.read(body, 0, bodyLength);
requestBody = new String(body);
}
}
And this is the request request:
POST /params_info.html HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/index.html
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 31
firstname=Mickey&lastname=Mouse
From what I understand, the loop will go until seeing the empty string
and then stoping. At this stage, the reader can read 'Content-Length' number of bytes. So it should have no problem reading the body and finish. Instead, it blocks on the line 'reader.read(body, 0, bodyLength);'
(The reason I don't use readLine() is because body does not end with \n).
I've tried debugging it in al kinds of ways but I get nothing. Can anyone please help with this?
You're reading the header using the bufferedReader:
while (!(line = bufferedReader.readLine()).equals("")) {
but read the body using reader, which has no data available, as this has been read and buffered by the bufferedReader:
reader.read(body, 0, bodyLength);
Change that line to
bufferedReader.read(body, 0, bodyLength);

Java HTTP Server response incomplete

I am trying to build my own embedded HTTP Server for Java with very specific usage for an internal closed system. Using embedded solution that already exists meant that I need to strip them down to refit them for my internal system's specific use cases.
I have managed to get my Java HTTPD receive HTTP Requests from web browsers but the Requests that the HTTPD receives are incomplete.
Below is the server thread codes (pretending the ServerSocket works perfectly fine):
public class HttpThread implements Runnable {
private Socket socket;
private DataInputStream in;
private PrintStream out;
private BufferedReader br;
private String EOF = "\n";
private String STATUS_200 = "HTTP/1.1 200 OK" + EOF;
public HttpThread(Socket socket) throws IOException {
this.socket = socket;
this.in = new DataInputStream(this.socket.getInputStream());
this.out = new PrintStream(new BufferedOutputStream(this.socket.getOutputStream()));
}
#Override
public void run() {
System.out.println("New thread...");
try {
processInput();
//socket.close();
} catch (IOException ex) {
Logger.getLogger(HttpThread.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//System.out.println("Thread END...");
}
private String processInput() throws IOException {
String line;
StringBuilder buff = new StringBuilder();
br = new BufferedReader(new InputStreamReader(in));
while ((line = br.readLine()) != null) {
buff.append(line);
System.out.println(">>> " + line);
if (line.trim().isEmpty()) {
break;
}
}
out.print(STATUS_200);
out.print("Server: Test Server\n" +
"Content-Type: text/html; charset=UTF-8\n" +
"Connection: close");
out.print(EOF);
out.print("<html><body>yello</body></html>");
out.print(EOF);
out.flush();
System.out.println(STATUS_200);
return buff.toString();
}
}
I am using this HTML Script to test the server thread to simulate a POST request:
<html>
<body onLoad="document.test.submit();">
<form action="http://localhost:9999/" method="POST" name="test">
<input type=hidden name="userid" value="1443"/>
<input type=hidden name="password" value="1443"/>
</form>
</body>
</html>
When I use the browser to call the HTML codes the Java HTTPD receives an incomplete response:
New thread...
>>> POST / HTTP/1.1
>>> Host: localhost:9999
>>> Connection: keep-alive
>>> Content-Length: 25
>>> Cache-Control: max-age=0
>>> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
>>> Origin: null
>>> User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36
>>> Content-Type: application/x-www-form-urlencoded
>>> Accept-Encoding: gzip,deflate,sdch
>>> Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
>>>
HTTP/1.1 200 OK
New thread...
>>> GET /favicon.ico HTTP/1.1
>>> Host: localhost:9999
>>> Connection: keep-alive
>>> Accept: */*
>>> User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36
>>> Accept-Encoding: gzip,deflate,sdch
>>> Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
>>>
HTTP/1.1 200 OK
It seems that the HTTPD only received the HTTP headers and stopped receiving the POST body.
May I know of some solutions to solve the above problem ?
Thanks.
The HTTP headers and body are separated by an empty line (also see the HTTP RFC, especially the chapter "5 Request"). Your server reads the socket Inputstream but breaks on an empty line :
if (line.trim().isEmpty()) {
break;
}
Therefore obviously you will not receive the body. You should fully consume the Inputstream instead.
Besides that, I would advise you to use already existing solutions. There is an abundance of HTTP server implementations, that are well tested and proven in real world usage. Save yourself alot of headache and use an existing lightweight server like e.g. Jetty, Netty or similar ones.
I switched out the while loop that does the readline() with the following code:
int i;
byte[] buffer = new byte[2048];
i = in.read(buffer);
for (int j = 0; j < i; j++) {
buff.append((char) buffer[j]);
}
System.out.println(buff.toString());
and the problem is solved.
Pyranja, thanks for the help.
Thanks to http://kcd.sytes.net/articles/simple_web_server.php IF you follow concisely. Somehow the br.readline() is not fully reading the lines properly after the empty line.
The code fragment should now look like:
private String processInput() throws IOException {
String line;
StringBuilder buff = new StringBuilder();
int i;
byte[] buffer = new byte[2048];
i = in.read(buffer);
for (int j = 0; j < i; j++) {
buff.append((char) buffer[j]);
}
System.out.println(buff.toString());
out.print(STATUS_200);
out.print("Server: Test Server\n" +
"Content-Type: text/html; charset=UTF-8\n" +
"Connection: close");
out.print(EOF);
out.print("<html><body>yello</body></html>");
out.print(EOF);
out.flush();
System.out.println(STATUS_200);
return buff.toString();
}
I guess it's a good experience learning how to build a simple HTTP Server :D .

Java - problems with REST client while sending an HTTP request

I am trying to send a GET request to a REST server using Java.
This is the code with some debugging.
URL url = new URL(request);
System.out.println("request url: " + url.toString());
System.out.println("method: " + httpMethod);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod(httpMethod);
connection.setRequestProperty("Content-Type", "text/plain");
connection.setRequestProperty("charset", "utf-8");
OutputStream os = connection.getOutputStream();
os.flush();
String response = os.toString();
System.out.println("response: " + response);
if (response.length() == 0)
{
throw new MyException("the response is empty");
}
This is the output:
request url: http://www.example.com/api.php/getToken/?api_ver=1&token=&api_key=bf8de053d9b6c540fb12195b4ac1602b0a71788c&sig=e00a59747afc7232207d40087e3765a5
method: GET
response:
com.example.api.client.MyException: the response is empty
As you can see, the response is empty.
But if I try and copy and paste the URL in Firefox I get this output
{"error":220}
and this header:
HTTP/1.1 200 OK
Date: Mon, 15 Nov 2010 11:55:29 GMT
Server: Apache
Cache-Control: max-age=0
Expires: Mon, 15 Nov 2010 11:55:29 GMT
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Length: 33
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
Can you see what it is wrong? How could I debug this code further?
Any help would be very much appreciated.
I think you do not use HttpURLConnection properly (there is no connect()).
Maybe study this example.

Categories

Resources