No HTTP response from Chrome extension to my Java Server - javascript

This is my very first question I am posting on StackOverflow. I usually tend to find answers to any question I have for whatever project, but I am really stuck on this one. I'm writing a Chrome extension that attempts to send JSON-objects over a HTTP post request with certain data in it to a basic Java server that will -in a later stage- process some of the data and return a HTTP response with relevant (processed) information for the client. This is the relevant JavaScript snippet on client-side:
function postRequest(jsonObject) {
var param = JSON.stringify(jsonObject);
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4) {
console.log(request.response);
}
};
request.open("POST", "http://"+link);
request.setRequestHeader("Content-type","text/plain");
request.send(param);
// request.abort();
}
The input JSON-object is legit and the link-item is the predefined host IP of the server. The server-side code is Java-based and is the following:
public class Server {
public static void main(String args[]) throws Exception {
while (true) {
try {
ServerSocket ss = new ServerSocket(1024);
Socket s = ss.accept();
System.out.println("Request: ");
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter pw = new PrintWriter(s.getOutputStream());
String line;
while ((line = br.readLine()) != null) {
if (line.length() == 0) {
break;
}
System.out.print(line + "\r\n");
}
System.out.println("");
System.out.println("Response:");
String response = "HTTP/1.1 200 OK \r\n" + "Access-Control-Allow-Origin: * \r\n"
+ "Connection: close \r\n" + "\r\n";
System.out.println(response);
pw.write(response);
while ((line = br.readLine()) != null) {
if (line.length() == 0) {
break;
}
System.out.print(line + "\r\n");
}
br.close();
pw.close();
System.out.println("");
System.out.println("Socket Closed");
System.out.println("");
s.close();
ss.close();
} catch (Exception ex) {
// Do whatever
}
}
}}
The server does receive the request and the JSON-object, but no response is received on client side (readyState is usually 4, but status code is 0 and responseText is empty). Additionally the connection is not closed when I don't use request.abort() or close the extension's window. It for sure has nothing to do with the permissions in the manifest file, so I didn't include it in this post. Can somebody see what my mistake is or anybody have had a similar experience?
EDIT:
The HTTP request is received on server side and looks like:
POST / HTTP/1.1
Host: [IP address of the server; I deleted the exact address for privacy]
Connection: keep-alive
Content-Length: 173
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
Origin: chrome-extension://nhpingbdjkkljheamibjobneeehiednk
Content-type: text/plain
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4,fr;q=0.2
Since the request is received on server side, I figured that the actual sending of the response is currently unsuccessful. Might it have something to do with the origin domain of the client? When I copy-paste that domain in my browser, I get a ERR_FILE_NOT_FOUND.

Related

Problems to get POST response JavaScript front / node js back

im trying to connect to my local node server route (http://localhost:3000/user-ragnarok-controller/saveragnarokuser/) from my javascript application and im getting no response from it. The server is receiving the request and is processing the same, but i cant get the response at client side.
my javascript app are running at localhost:80 (Apache XAMPP) and my node server at localhost:3000.
this is my javascript code to connect to node server end-point:
function handler() {
alert('handler');
if(invocation.readyState === XMLHttpRequest.DONE && invocation.status === 200) {
alert('entrei aqui');
console.log(invocation.responseText);
} else
alert('nao foi hj ' + invocation.status.toString());
}
function saveUser() {
alert('dourado ');
var eml = document.getElementById('emailInputRegister');
var user = document.getElementById('userInputText');
var sx = document.getElementById("sexInputSelected");
var selectedSex = sx.options[sx.selectedIndex].value;
var pwd = document.getElementById("passwordInputRegister");
var uri = 'http://localhost:3000/user-ragnarok-controller/saveragnarokuser/';
var body = {
'userid': user.value,
'userpass': pwd.value,
'email': eml.value,
'sex': selectedSex
};
invocation.open('POST', uri);
invocation.withCredentials = true;
invocation.setRequestHeader('Content-Type', 'application/json');
invocation.onreadystatechange = this.handler;
invocation.send(JSON.stringify(body));
}
this is my request at google chrome console
Now let's talk about the server side. Here i have a middleware for CORS treatment.
// Add headers
app.use(function (req, res, next) {
console.log('reqHeaders: ' + JSON.stringify(req.headers));
res.header('Access-Control-Allow-Origin', 'http://localhost');
res.header('Access-Control-Allow-Headers', 'content-type');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.header('Access-Control-Allow-Credentials', true);
if(req.method === 'OPTIONS')
return res.status(200).send({});
next();
});
After CORS, the server starts my route POST:
router.post('/saveragnarokuser',function(req,res,next){
console.log('######################### Iniciando saveragnarokuser.');
UserRagnarokController.addUser(req.body,function(err,count){
if(err){
console.log('entrei aqui error: ' + err);
res.json(err);
}
else{
console.log('entrei aqui ok');
var userObj = {
response: "OK"
};
res.status(200).json(userObj);
}
});
});
looking to the server log its possible to see the request coming, processing, but for some reason the POST response is -- ms --. With no Status and execution time.
reqHeaders: {"host":"localhost:3000","connection":"keep-alive","content-length":"88","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","content-type":"application/json","accept":"*/*","origin":"http://localhost","sec-fetch-site":"same-site","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost/co-cadastro/register.html?","accept-encoding":"gzip, deflate, br","accept-language":"pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7"}
######################### Iniciando saveragnarokuser.
myReqbody: {"userid":"fernandocabeca","userpass":"1234","email":"acosta.aluiz#gmail.com","sex":"F"}
POST /user-ragnarok-controller/saveragnarokuser/ - - ms - -
entrei aqui ok
My function UserRagnarokController.addUser performed perfectly, the requisition data was successfully filled in the database, i just need to get this response at client side (google chrome app), i got no error and no success.
NOTE: when I execute the request at POSTMAN it works normally, the answer is 200 OK.
There is probably a warning in the browser's console about breaking of CORS policy.
Headers about CORS should come from your server (Response Headers) and I don't see that tab here in your screenshot.
Postman ignores CORS, and server process all request by default.

Websocket handshake doesnt work

i have a cpp server using WinSock2 and im trying to connect to this server with my javascript client, and it doesnt work, the chrome console says "Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value".
i compared my sha1 and base64 functions with online sha1 and base64 so the problem isnt here.
Chrome Response Header:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-Websocket-Accept: NzdkYjg1Y2I4MDRlNTk0OGNmNzI1NzdjZDgwOTEwZWZiYWI1NzQ3Yw==
Chrome Request Header:
GET ws://localhost:8820/ HTTP/1.1
Host: localhost:8820
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: file://
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: he-IL,he;q=0.8,en-US;q=0.6,en;q=0.4
Sec-WebSocket-Key: Y7a2ZKEz/VCM92Wya49iPA==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Server Code:
//key is already defined.
key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
key = sha1(key);
key = base64_encode(reinterpret_cast<const unsigned char*>(key.c_str()), key.length());
toClient = "HTTP/1.1 101 Switching Protocols\r\n";
toClient += "Upgrade: websocket\r\n";
toClient += "connection: Upgrade\r\n";
toClient += "Sec-Websocket-Accept: ";
toClient += key;
toClient += "\r\n\r\n";
sendData(sc, toClient);
Client Code:
<!DOCTYPE HTML>
<script type="text/javascript">
function WebSocketTest()
{
if ("WebSocket" in window)
{
//alert("WebSocket is supported by your Browser!");
// Let us open a web socket
var ws = new WebSocket("ws://localhost:8820");
console.log("test");
ws.onopen = function()
{
alert("Connection.")
// Web Socket is connected, send data using send()
ws.send("20304user04user04user");
//alert("Message is sent...");
};
ws.onmessage = function (evt)
{
var received_msg = evt.data;
alert("Hey");
};
ws.onclose = function()
{
// websocket is closed.
alert("Connection is closed...");
};
}
else
{
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
}
}
</script>
<div id="sse">
Run WebSocket
</div>
I tried manually to build the response:
Raw sha1 digest bytes of the concatenation are 77db85cb804e5948cf72577cd80910efbab5747c
Bytes to base 64: d9uFy4BOWUjPcld82AkQ77q1dHw=
This is different than what you have. You are transforming the hexadecimal string representation of those bytes to base 64 instead of raw bytes to base 64.

Handshake between JS WebSocket and Java

I tried to implement the WebSocket Protocol and connecting a JavaScript WebSocket with a Java WebSocket Server.
The JavaScript part is pretty straight forward and works as expected.
I wrote the Java server myself and read the rfc 6455 page 7 for the correct handshake response. So the server generates the correct response and sends it. I wrote a Java client dummy to make sure it gets send.
But the problem is that the JavaScript / Browser seems not to receive the handshake response and kills the request after some seconds (but does not close the tcp socket).
Here is the handshake:
Client
GET / HTTP/1.1
Host: 127.0.0.1:4455
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: http://localhost
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Server
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
HTML JavaScript
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Socket testing - Client</title>
</head>
<body>
<div id="container"></div>
<script type="text/javascript">
var socket = new WebSocket('ws://127.0.0.1:4455');
socket.addEventListener("error",function(e){
console.log("an error ocurred: ",e)
})
socket.addEventListener("close",function(e){
console.log("the connection was closed: ",e)
})
socket.addEventListener("open",function(e){
console.log("the connection was opened: ",e)
})
socket.addEventListener("message",function(e){
console.log("recieved a message: ",e)
})
</script>
</body>
</html>
Java (excerpt)
public class SocketHandlerWebSocketLevel extends SocketHandler {
private HashMap<String, String> connectionHeaders;
private InputStreamReader stringReader;
private OutputStreamWriter stringWriter;
public SocketHandlerWebSocketLevel(Socket socket) {
super(socket);
connectionHeaders = new HashMap<String, String>();
try {
stringReader = new InputStreamReader(s.getInputStream());
} catch (IOException e) {
e.printStackTrace();
close();
print("could not get the input stream");
return;
}
try {
stringWriter = new OutputStreamWriter(s.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
close();
print("could not get the output stream");
return;
}
}
#Override
public void run() {
print("Started handler");
char b;
String buffer = "";
try {
mainLoop: while (true) {
while (stringReader.ready() || buffer.length() == 0) {
if ((b = (char) stringReader.read()) != -1) {
buffer += b;
} else {
break mainLoop;
}
}
gotMessage(buffer);
buffer = "";
}
} catch (IOException e) {
close();
print("connection was killed remotly, could not read the next byte");
return;
}
close();
print("connection was closed remotely, stopped Handler, closed socked");
}
private void gotMessage(String message) {
if (connectionHeaders.size() == 0) {
connectionHeaders = parseHttpHeader(message);
handshakeResponse();
} else {
print(message);
}
}
private void handshakeResponse() {
/*
taken from: https://www.rfc-editor.org/rfc/rfc6455#page-7
For this header field, the server has to take the value (as present
in the header field, e.g., the base64-encoded [RFC4648] version minus
any leading and trailing whitespace) and concatenate this with the
Globally Unique Identifier (GUID, [RFC4122]) "258EAFA5-E914-47DA-
95CA-C5AB0DC85B11" in string form, which is unlikely to be used by
network endpoints that do not understand the WebSocket Protocol. A
SHA-1 hash (160 bits) [FIPS.180-3], base64-encoded (see Section 4 of
[RFC4648]), of this concatenation is then returned in the server's
handshake.
Concretely, if as in the example above, the |Sec-WebSocket-Key|
header field had the value "dGhlIHNhbXBsZSBub25jZQ==", the server
would concatenate the string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
to form the string "dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-
C5AB0DC85B11". The server would then take the SHA-1 hash of this,
giving the value 0xb3 0x7a 0x4f 0x2c 0xc0 0x62 0x4f 0x16 0x90 0xf6
0x46 0x06 0xcf 0x38 0x59 0x45 0xb2 0xbe 0xc4 0xea. This value is
then base64-encoded (see Section 4 of [RFC4648]), to give the value
"s3pPLMBiTxaQ9kYGzzhZRbK+xOo=". This value would then be echoed in
the |Sec-WebSocket-Accept| header field.
*/
String secWebSocketKey, secWebSocketAccept, GUID, template, merged, toSend;
secWebSocketKey = connectionHeaders.get("Sec-WebSocket-Key");
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
template = "HTTP/1.1 101 Switching Protocols\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Accept: %s\nSec-WebSocket-Protocol: chat\n";
// combine secWebSocketKey and the GUID
merged = secWebSocketKey + GUID;
print("merged: " + merged);
// convert to byte[]
byte[] asBytes = merged.getBytes();
print("asBytes: " + Arrays.toString(asBytes));
// SHA-1 hash
byte[] sha1 = SHA1Hash(asBytes);
print("sha1: " + Arrays.toString(sha1));
// base64 encode
byte[] base64 = base64Encode(sha1);
print("base64: " + Arrays.toString(base64));
// reconvert to string to put it into the template
secWebSocketAccept = new String(base64);
toSend = String.format(template, secWebSocketAccept);
print(toSend);
try {
stringWriter.write(toSend, 0, toSend.length());
stringWriter.flush();
} catch (IOException e) {
print("hanshake sending failed!");
}
}
private HashMap<String, String> parseHttpHeader(String h) {
HashMap<String, String> fields = new HashMap<String, String>();
String[] rows = h.split("\n");
if (rows.length > 1) {
fields.put("Prototcol", rows[0]);
Pattern pattern = Pattern.compile("^([^:]+): (.+)$");
for (int i = 1; i < rows.length; i++) {
Matcher matcher = pattern.matcher(rows[i]);
while (matcher.find()) {
if (matcher.groupCount() == 2) {
fields.put(matcher.group(1), matcher.group(2));
}
}
}
}
return fields;
}
private byte[] SHA1Hash(byte[] bytes) {
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
return null;
}
md.update(bytes);
return md.digest();
}
private byte[] base64Encode(byte[] bytes) {
byte[] encodedBytes = Base64.getEncoder().encode(bytes);
return encodedBytes;
}
Where might be my error? What could be missing, maybe a "message end" symbol?
Note that I don't want to use a framework.
The solution was simple. I just used Wireshark to debug this whole thing: I just forgot the carriage return.
The correct string in the Java class would be:
template = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: %s\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
Until this modification the browser is not able to interpret it as HTTP data in the TCP package.

How to receive Angular $http post multipart form data in Grails

How to receive angular $http post multipart form data from Grails. Here I have sent multipart form data from Angular controller to the Grails. I am new to Grails.
Anyone can give me guidance to retrieve-boundary data. I don't Know exactly it's correct form to receive image file data with some input data also.
Request headers in browser's network console:
Provisional headers are shown
Accept:application/json, text/plain, */*
Content-Type:multipart/form-data; boundary=----
WebKitFormBoundary0p6R8BecvYqzcbMK
Origin:file://
User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us)
AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53
Request Payload
------WebKitFormBoundary0p6R8BecvYqzcbMK
Content-Disposition: form-data; name="rackImage"; filename="PhoneGap.png"
Content-Type: image/png
------WebKitFormBoundary0p6R8BecvYqzcbMK
Content-Disposition: form-data; name="storeNo"
HD1304
------WebKitFormBoundary0p6R8BecvYqzcbMK
Content-Disposition: form-data; name="rackQty"
12
------WebKitFormBoundary0p6R8BecvYqzcbMK--
Here you go. Just write the following in your controller:
class MyController {
def upload() {
def multipartFile = params.rackImage
InputStream is
FileOutputStream fos
byte[] fileRead = new byte[1024]
File tempFile
try {
is = multipartFile.getInputStream()
String fileName = multipartFile.getOriginalFilename()
String path = "./"
fileName = fileName.replaceAll("[^a-zA-Z0-9//._-]+", "").toLowerCase()
tempFile = new File(path + "" + fileName)
fos = new FileOutputStream(tempFile);
int i = is.read(fileRead)
while (i != -1) {
fos.write(fileRead, 0, i);
i = is.read(fileRead);
}
} catch (FileNotFoundException e) {
log.error "Exception uploading", e
} catch (IOException e) {
log.error "Exception uploading", e
} finally {
fos?.close()
is?.close()
}
// Now access the File: "tempFile"
}
}

JSON Javascript doesn't work?

I started developing a webinterface with bootstrap and so I used javascript to receive some JSON-Data.
My JSON-String is build with JSONObjects in JAVA and I used Jersey RestFUL-Service.
Java Code:
#GET
#Path("test")
#Produces(MediaType.TEXT_HTML)
public String createTestJson(){
JSONObject jsobject= new JSONObject();
try {
jsobject.append("test1", "test");
jsobject.append("test2", "test");
jsobject.append("test3", "test");
jsobject.append("test4", "test");
jsobject.append("test5", "test");
jsobject.append("test6", "test");
jsobject.append("test7", "test");
}catch(Exception e){
e.printStackTrace();
}
return jsobject.toString();
}
When I call the URL with the browser it works:
{"test1":["test"],"test2":["test"],"test3":["test"],"test4":["test"],"test5":["test"],"test6":["test"],"test7":["test"]}
I created a JavaScript function, which should retrieve the JSON String and fill the certain values in my HTML-page.
function loadJSON()
{
var data_file = "http://127.0.0.1:8085/Rest/test/test";
var http_request = new XMLHttpRequest();
try{
// Opera 8.0+, Firefox, Chrome, Safari
http_request = new XMLHttpRequest();
}catch (e){
// Internet Explorer Browsers
try{
http_request = new ActiveXObject("Msxml2.XMLHTTP");
}catch (e) {
try{
http_request = new ActiveXObject("Microsoft.XMLHTTP");
}catch (e){
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
http_request.onreadystatechange = function(){
if (http_request.readyState == 4 )
{
alert(http_request.responseText.length);
var jsonObj = JSON.parse(http_request.responseText);
document.getElementById("test1").innerHTML = jsonObj.test1;
document.getElementById("test2").innerHTML = jsonObj.test2;
}
}
http_request.open("GET", data_file, true);
http_request.send();
}
When I analyse the document with firebug, I can see that the GET- inquiry is completed and it's state is "200 OK". The answer of the inquiry is the JSON String.
I also analysed the script and it seems to stop working at:
var jsonObj = JSON.parse(http_request.responseText);
Additionally I wrote out the length of the responseText and the result is "0".
So I really don't get the problem. According firebug the script gets the data, but it breaks down at parsing the JSON String. It could relate to the responseText, which has a length of 0.
-------Edit-----
More Firebug information:
The XMLHTTPRequest-Object Data after receiving the data:
DONE 4
HEADERS_RECEIVED 2
LOADING 3
OPENED 1
UNSENT 0
mozAnon false
mozBackgroundRequest false
mozSystem false
onloadend null
ontimeout null
readyState 1
response ""
responseText ""
responseType ""
responseXML null
status 0
statusText ""
timeout 0
The inquiry-header
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Connection keep-alive
Host 127.0.0.1:8085
Origin null
User-Agent Mozilla/5.0 (Windows NT 6.3; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0
The response-header
Content-Type application/xhtml+xml
Date Mon, 24 Aug 2015 22:56:18 GMT
Server Apache-Coyote/1.1
Transfer-Encoding chunked
Response:
{"test1":["test"],"test2":["test"],"test3":["test"],"test4":["test"],"test5":["test"],"test6":["test"],"test7":["test"]}
Maybe you can help me!
Thank you!
Marko
I would be interested if your JSON is recieved as type="application/json or perhaps as XML/HTML. Could it be that the response is XML and so the "object" is stored inside http_request.XML?
---------- EDIT ----------
I think you are having issues with the Same-Origin-Policy of JS. You cannot load your field because of that. Try to implement your JS inside a view of your Java-App (so that you can access it via http:// and in the same domain as your app) and try it again.

Categories