Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Post to GoogleCloudMessaging returns 400 InvalidTokenFormat

I'm trying to post to Googles Cloud Messaging Api (GCM), but my request fails with response HTTP/1.1 400 InvalidTokenFormat.

However, if I change my program so that it connects to localhost instead, and I simply pipe the request it makes through to something else that transmits the request to GCM, the request succeeds. Below is the code that fails:

import java.net.URL;
import java.net.HttpURLConnection;
import java.io.OutputStream;

public class GcmPostMe {
    public static void main (String[] args) {

        String data = "{\"to\":\" *** censored recipient token *** \"}";
        String type = "application/json";
        try {
            URL u = new URL("https://android.googleapis.com/gcm/send/");
            HttpURLConnection conn = (HttpURLConnection) u.openConnection();
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty( "Authorization", "key=" + " *** censored api key *** " );
            conn.setRequestProperty( "Content-Type", type );
            conn.setRequestProperty( "Content-Length", String.valueOf(data.length()));
            OutputStream os = conn.getOutputStream();
            os.write(data.getBytes());
            System.out.println(conn.getResponseCode() + " " + conn.getResponseMessage() );
            conn.disconnect();
        } catch (Exception e) {
            System.err.println("Something went wrong");
        }
    }
}

It works when I change the URL in the code above to "http://localhost:10000/gcm/send" and do

nc -l 10000 | sed -e "s/localhost:10000/android.googleapis.com/" | openssl s_client -connect android.googleapis.com:443

before I run the program.

like image 994
velfundert Avatar asked Feb 06 '26 16:02

velfundert


1 Answers

Ok, I've found my mistake: the path was wrong, the trailing / in the path somehow makes it not work.

Doing HTTP POST to https://android.googleapis.com/gcm/send/ gives you HTTP/1.1 400 InvalidTokenFormat

Doing the same POST to http://android.googleapis.com/gcm/send (without the trailing /) succeeds with HTTP/1.1 200 OK

The following works:

import java.net.URL;
import java.net.HttpURLConnection;
import java.io.OutputStream;

public class GcmPostMe {
    public static void main (String[] args) {

        String data = "{\"to\":\" *** censored recipient token *** \"}";
        String type = "application/json";
        try {
            URL u = new URL("https://android.googleapis.com/gcm/send");
            HttpURLConnection conn = (HttpURLConnection) u.openConnection();
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty( "Authorization", "key=" + " *** censored api key *** " );
            conn.setRequestProperty( "Content-Type", type );
            conn.setRequestProperty( "Content-Length", String.valueOf(data.length()));
            OutputStream os = conn.getOutputStream();
            os.write(data.getBytes());
            System.out.println(conn.getResponseCode() + " " + conn.getResponseMessage() );
            conn.disconnect();
        } catch (Exception e) {
            System.err.println("Something went wrong");
        }
    }
}
like image 86
velfundert Avatar answered Feb 09 '26 08:02

velfundert