POST from Java or JS to GCM - http

I know there are many different situations that resemble mine across stackoverflow, but I just couldn't make the connection.
What I am trying to do, is to send a simple push notification to the GCM. I found two links for which I try to POST too. Note both these links work in this PHP script i found.
https://gcm-http.googleapis.com/gcm/send
https://android.googleapis.com/gcm/send
I tried to send push notifications from JS to the GCM, but many people have stated that this can not because of security issues. As of now, when I execute my code in Angular JS, I am getting a 405 error from https://gcm-http.googleapis.com/gcm/send. Status 405 means method not accepted (link for reference http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html).
Here is the code for JS. I have two method that I tried.
Method 1:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//ite
}
};
var jsonCall = {
registration_id: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx-AEQtUUWnCVH566xcwib4HinI16W3_g"
};
xmlhttp.open("POST", "https://gcm-http.googleapis.com/gcm/send", true);
xmlhttp.setRequestHeader("Content-type", "application/json");
xmlhttp.setRequestHeader("Authorization", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
xmlhttp.send(jsonCall);
Method 2
var jsonCall = {
registration_id: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx-AEQtUUWnCVH566xcwib4HinI16W3_g"
};
$http({
method:'POST',
url: 'https://gcm-http.googleapis.com/gcm/send',
data: jsonCall,
headers: {
'Authorization': 'A1nxxxxxxxxxxxxxxxxxx',
'Content-type': 'application/json' }
})
This is what I have tried in Java. Note that my project was not created as an Android project, but just as a normal Java project. I get a 411 error here, so I think the string I use as JSON is incorrect. Note that I get a 200 if I use GET.
Method 3:
HttpURLConnection connection = null;
try {
//Create connection
String json ="{\"registration_ids\":[\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxx\"]}";
URL url = new URL("https://gcm-http.googleapis.com/gcm/send");
connection = (HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("Content-Length", "0");
connection.setRequestProperty("Authorization", "key="+"xxxxxxxxxxxxxxxxxxxxxxxxxx");
System.out.println(connection.getResponseCode());
InputStream stream = (InputStream) connection.getInputStream();
InputStreamReader isReader = new InputStreamReader(stream);
//put output stream into a string
BufferedReader br = new BufferedReader(isReader);
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
OutputStream os = connection.getOutputStream();
os.write(json.getBytes("UTF-8"));
os.flush();
os.close();
} catch(Exception e){
System.out.println(e);
}
If someone can take a look at this, and set me in the correct direction, I would really appreciate it.
UPDATE:
I have gotten rid of that 411 error. I think it was because I never connected in the first place. Now I am getting the correct 200 code, but the push notification does not send. Is my JSON the correct format?
HttpURLConnection connection = null;
try {
//Create connection
String json ="{\"registration_ids\":[\"APA91bGxHWapgmxgyvPceu85ArDMLaFekbTt5RGzy3gv1xtSO09tJbvnaeVLefBqNl_iBrctoZQ2AltSMfrXykq8-AEQtUUWnCVH566xcwib4HinI16W3_g\"]}";
URL url = new URL("https://gcm-http.googleapis.com/gcm/send");
connection = (HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "key=xxxxxxxxxxxxxxxxxxxxxxx");
connection.connect();
OutputStream os = connection.getOutputStream();
os.write(json.getBytes("UTF-8"));
System.out.println(connection.getResponseCode());
InputStream stream = (InputStream) connection.getInputStream();
InputStreamReader isReader = new InputStreamReader(stream);
//put output stream into a string
BufferedReader br = new BufferedReader(isReader);
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
os.flush();
os.close();
} catch(Exception e){
System.out.println(e);
}

This has been solved using the Java method. JS keeps on returning those status codes of 400, 401, 411 etc. It turns out the reason Java returned a 200 but my phone did not receive anything was because my JSON was incorrect. Here is the correct JSON value:
String postData = "{ \"registration_ids\": [ \"" + CLIENT_REG_ID + "\" ], " +
"\"delay_while_idle\": true, " +
"\"data\": {\"tickerText\":\"My Ticket\", " +
"\"contentTitle\":\"My Title\", " +
"\"message\": \"Test GCM message from GCMServer-Android\"}}";
This was obtained from another question I posted, where a fellow SO member provided this solution.

Related

Tomcat VueJS axios: How to read a string passed through "data" in an axios POST method?

I am making an axios POST call to a tomcat servlet. I see the string being sent as Request payload when I check Developer tools but I am not able to retrieve the string in Tomcat servlet.
When I test it with PHP, I am able to retrieve the json string.
$json_str = file_get_contents('php://input');
echo $json_str; //This works and displays the JSON string
This is what I have tried in the servlet, please let me know what might be wrong with my code.
VueJs axios
axios({
method: 'post',
url: urltocall,
data: this.strjson,
params: {
'username': 'test1'
},
config: {
headers: {
'Access-Control-Allow-Origin': 'http://localhost:1337',
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}
})
.then(function (response) { }
Tomcat Servlet
StringBuilder sb = new StringBuilder();
BufferedReader br = request.getReader();
String str;
while( (str = br.readLine()) != null ){ //Not entering this while loop, so "sb" is empty
sb.append(str);
}
"content-length' when checked in the servlet, shows the correct length of the string passed through "data", so that confirms that the string is available in the request object. But for some strange reason, the getReader() is not fetching the string.
Appreciate your help.
I found the issue. I was reading a parameter from request object before using the getReader() to extract the data. That was causing the data to be wiped out. When I shifted the getReader() to top, to give it the 1st access of info in request object, it worked just fine. Trivial fix but cost some time. Hope this helps someone.
Wrong
String test = request.getParameter("test");
StringBuilder sb = new StringBuilder();
BufferedReader br = request.getReader();
String str;
while( (str = br.readLine()) != null ){
sb.append(str);
}
Right
StringBuilder sb = new StringBuilder();
BufferedReader br = request.getReader();
String str;
while( (str = br.readLine()) != null ){
sb.append(str);
}
String test = request.getParameter("test");

Google-HttpClient: Post request successful but no data added to database

I'm using Google Http Client to code a Post request. Our underlying call is an AJAX post request and the request is successful which return 200 but there is no data added to database. I don't know what wrong with the HTTP Call as the code is design as one HTTP URL call with many function(Add contact, Add organization). How to debug this? Please help me. Thanks.
public void addContact() {
try {
String requestBody = "{'Source': 'Contact', 'MethodName': 'AddContact', 'UserID': '1', 'SalutationID': '1', 'FirstName': 'Peter', "
+ "'LastName': 'Wong', 'JobTitle': 'Software QA', 'PrimaryEmail': 'peterapiit#gmail.com', "
+ "'BusinessPhone': '60163963326', 'CountryID': '104', 'OrganizationID': '1', 'AOIIDs': '2'}";
GenericUrl url = new GenericUrl("https://extranet-uat.who.int/epqs/Main/ServiceProxy");
HttpRequestFactory rf = new NetHttpTransport().createRequestFactory();
HttpRequest request = rf.buildPostRequest(url, ByteArrayContent.fromString("application/json",
requestBody));
request.getHeaders().setContentType("application/json");
HttpResponse response = request.execute();
SoftAssert sAssert = new SoftAssert();
sAssert.assertEquals(response.getStatusCode(), 200);
System.out.println("HTTP Status Code : " + response.getStatusCode());
} catch (IOException ex) {
LogManager.logger.log(Level.INFO, "Exception: " + ex.getMessage());
}
}
The underlying javascript code is available to download from here.

Service Worker file offline events

Google Chrome latest(v55.0.2883.87)
There are various event in that (sw.js)file. Everytime a file got requested fetch event occur. How and when other events occur(sync, push)(web notification api). I want to debug it. Is there any doc available?
Update:
server-key-from-firebase-console
subscription-key-after-subscribing-web-notification
Found how push notification fired--
String url = "https://fcm.googleapis.com/fcm/send";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
//add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("Authorization", "key=<server-key-from-firebase-console>");
con.setRequestProperty("Content-Type", "application/json");
String urlParameters = "{\"to\":\"<subscription-key-after-subscribing-web-notification>\"}";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
Update 2:
Ok now i found how to fire a sync event in service worker file either from google chrome debugger tool or from javascript. Below is the code, what i have found on google's blog post.
// Register your service worker:
navigator.serviceWorker.register('/sw.js');
// Then later, request a one-off sync:
navigator.serviceWorker.ready.then(function(swRegistration) {
return swRegistration.sync.register('myFirstSync');
});
Then listen for the event in /sw.js:
self.addEventListener('sync', function(event) {
if (event.tag == 'myFirstSync') {
event.waitUntil(doSomeStuff());
}
});
A good resource for knowing more about ServiceWorker is MDN (Mozilla Developer Network).
Here is the entry point to the documentation related to ServiceWorker:
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
There you have links and explanations for the install, fetch, sync and push events. And the new ones that will appear like background sync will be documented there too.
Happy reading.

HttpPost method response with WebClient is null.

I know there are similar posts regarding calling an HttpPost method but nothing I've read/implemented has worked for me. I'm simply trying to do a POST call but the response is always null for some reason. I'm new to web development and ASP.
Here's my WebClient code:
using (WebClient webClient = new WebClient())
{
webClient.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
var dataToSend = "=testingu";
var response = webClient.UploadString("http://localhost:5000/core/test", "POST", dataToSend);
Console.WriteLine("Response is: " + response);
}
and here's my HttpPost code:
[HttpPost("/core/test")]
public string PostObj([FromBody]dynamic input)
{
string result = "";
if (input == null)
System.Console.WriteLine("Input is null.");
else
System.Console.WriteLine("Input is not null: " + input);
return result;
}
Whenever PostObj is called, the "Input is null" line is always executed when I'm expecting to see "Input is not null: testingu" printed. It seems like my WebClient code is sound, but I'm pretty new to this so any help is appreciated.

HttpUrlConnection response code always returns -1

I have created my server in amazon ec2 instance. Through my android app i am connecting to the server with HttpUrlConnection. But i get response code as -1. Does anyone has any idea ?? Here is my code.
private String getHttpResponse(final String srcUrl) {
HttpURLConnection urlConnection = null;
FileOutputStream fos = null;
try {
URL url = new URL(srcUrl);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setRequestProperty("Content-Type", "application/json");
mETag = readETagFromPrefForCategory();
urlConnection.setRequestProperty("If-None-Match", mETag);
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("xyz", "abc".toCharArray());
}
});
urlConnection.connect();
mETag = urlConnection.getHeaderField("ETag");
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
Log.v("http","not modifed");
return readLocalJson();
}
if (urlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
Log.w(TAG, "Bad response [" + urlConnection.getResponseCode() + "] from (" + srcUrl + ")");
return null;
}}//end of try block
An answer in this post seemed to solve it for a few people:
Android Https Status code -1
Hope that helps.
The problem might be that your headers HTTP version is not properly formatted. Check this SO link where I have answered a similar question which worked for me.
Java Http~URLConnection response code -1
Why are you setting "Content-Type" on a GET request?

Resources