0

I have an application running on a server. Once a user is trying to connect to the server he sends a GET request. Based on the username and password passed in the request the server authenticates the user.

I am able to connect to the server using a client code that is written in java. The code i use to generate the GET request is:

private String GETrequest(String nMountpoint, String nUsername, String nPassword){
        String requestmsg = "";
        requestmsg += "GET /" + nMountpoint + " HTTP/1.0\r\n";
        requestmsg += "Host: " + nServer +"\r\n";
        requestmsg += "User-Agent: NTRIP Client v1\r\n";
        requestmsg += "Ntrip-Version: Ntrip/2.0\r\n";
        requestmsg += "Accept: */* \r\n";
        requestmsg += "Connection: close\r\n";
        if (nUsername.length() > 0) {
            requestmsg += "Authorization: Basic " + Base64.getEncoder().encodeToString((nUsername + ":" + nPassword).getBytes(StandardCharsets.UTF_8)) + "\r\n\r\n";
        }

        return requestmsg;
    }

When the request arrives to the server and it processes it I receive the next output:

GET /mP HTTP/1.0
Host: host.address.net
User-Agent: NTRIP Client v1
Ntrip-Version: Ntrip/2.0
Accept: */*
Connection: close
Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=


checking credentials
dGVzdHVzZXI6dGVzdHBhc3M=
lavrovson:exotech
User: testuser,    Pass: testpass

The server decoded the message as planed and the process keeps running. However, when i try to connect to the server using an android app the process on the server side stuck. The code i use to generate the GET request on android is:

private String GETrequest(String nMountpoint, String nUsername, String nPassword){
        String requestmsg = "";
        requestmsg += "GET /" + nMountpoint + " HTTP/1.0\r\n";
        requestmsg += "Host: " + nServer +"\r\n";
        requestmsg += "User-Agent: NTRIP Client v1\r\n";
        requestmsg += "Ntrip-Version: Ntrip/2.0\r\n";
        requestmsg += "Accept: */* \r\n";
        requestmsg += "Connection: close\r\n";
        if (nUsername.length() > 0) {
            String usps = nUsername + ":" + nPassword;
            byte[] bt = null;
            try {
                bt = usps.getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {e.printStackTrace();}
            String base64 = Base64.encodeToString(bt, Base64.DEFAULT);
            requestmsg += "Authorization: Basic " + base64 + "\r\n\r\n";
        }

        return requestmsg;
    }

When the request arrives to the server and it tries to decode it i receive the next output:

GET /mP HTTP/1.0
Host: host.address.net
User-Agent: NTRIP Client v1
Ntrip-Version: Ntrip/2.0
Accept: */*
Connection: close
Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=



checking credentials
dGVzdHVzZXI6dGVzdHBhc3M=

The process gets stuck on the decoding of the Base64 encoded string. When trying to decode the encoded string on the server i use the next code:

byte[] valueDecoded = Base64.getDecoder().decode(decodedString); 
String UserPass = new String(valueDecoded, StandardCharsets.UTF_8);
String[] UP = UserPass.split(":");

EDIT: Some additional server code:

 private void messageParsing(byte[] bt){
        String MSG = new String(bt);
        if (bt.length > 4){
            System.out.println(MSG);
        }

        String tokens[] = MSG.split(" ");
        // GET request parsing
        if (tokens[0].matches("GET") && tokens[1].length()>1){
            if (secure){
                if(conn_logger.isTraceEnabled()){
                    conn_logger.trace("Client at adress " + secureSocket.getRemoteSocketAddress());
                }
            } else {
                if(conn_logger.isTraceEnabled()){
                    conn_logger.trace("Client at adress " + socket.getRemoteSocketAddress());
                }
            }
            System.out.println("checking credentials");
            chekCredentials(tokens);
        }
     }

The checkCredentials method :

private void chekCredentials(String[] tokens){
        String[] encoded = tokens[tokens.length-1].split("\r\n");
        System.out.println(encoded[0]);
        byte[] valueDecoded = Base64.getDecoder().decode(encoded[0]);
        System.out.println(new String(valueDecoded));
        String UserPass = new String(valueDecoded, StandardCharsets.UTF_8);
        String[] UP = UserPass.split(":");
        System.out.println("User: " + UP[0] + ",    Pass: " + UP[1]);

        // Some stuff to do with user/password
          .
          .
          .

}

So the question is why does the server code isn't able to decode the base64 encoded string that is coming from the android app? Am i doing something wrong with the encoding process on the android side? Any help would be appreciated. Thank you.

Dan
  • 195
  • 2
  • 14
  • If the output from both requests is accurate, then it seems that the android client is sending an additional line break. Maybe this is causing problems with the processing of the message on the server side? Can you post more of the server code to see what it's actually doing? – Guenther Sep 27 '17 at 09:01
  • I have added more code. – Dan Sep 27 '17 at 09:19
  • @Maddy I have checked the possible duplication. There is nothing in there that i have not already tried. All my imports are the way they should be and i am doing the same thing as suggested in the various answers. – Dan Sep 27 '17 at 09:24

2 Answers2

0

Instead of using "UTF-8" as a string argument directly, use StandardCharsets.UTF_8 while performing getBytes from string in android or if you are pointing lower api level then use as i stated below.

Instead of

bt = usps.getBytes("UTF-8");

use this

bt = usps.getBytes(Charset.forName("UTF-8"))
  • Changed my code to use `bt = usps.getBytes(Charset.forName("UTF-8"))`, the result is the same server stuck on decoding. – Dan Sep 27 '17 at 09:32
0

Problem solved. Apparently in the line : requestmsg += "Authorization: Basic " + base64 + "\r\n\r\n" Android was adding additional \n before the `\r\n\r\n".

Dan
  • 195
  • 2
  • 14