Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Illegal character(s) in message header value: Basic

I get the following error when trying to query an api in Java using HttpUrlConnection:

    "Exception in thread "main" java.lang.IllegalArgumentException: Illegal   character(s) in message header value: Basic MTk2YTVjODdhNWI2YjFmNWE3ZmQ5ODEtYjFjYTEzZmUtM2FkNC0xMWU1LWEyZjAtMDBkMGZlYTgy
NjI0OmY3NDQ2ZWQ0YjhjNzI2MzkyMzY1YzczLWIxY2ExNjQ4LTNhZDQtMTFlNS1hMmYwLTAwZDBm
ZWE4MjYyNA=="

Here is my code:

public class LocalyticsTest {

        public static void main(String[] args) throws UnsupportedEncodingException {

            String apiKey = "MyKey";
            String apiSecret = "MySecretKey";
            String apiUrl = "https://api.localytics.com/v1/query";
            String credentials = apiKey + ":" + apiSecret;
            //String encoding = Base64.encode(apiKey.getBytes("UTF-8"));
            //String encoding2 = Base64.encode(apiSecret.getBytes("UTF-8"));
            String encoding3 = new sun.misc.BASE64Encoder().encode (credentials.getBytes("UTF-8"));

            String appId = "myAppId";
            String metric = "sessions";
            String dimensions = "day";
            String condition = "'{\"day\":[\"between\",\"'.$newDate.'\",\"'.$newDate.'\"]}'";
            Map data = new HashMap();
            data.put("app_id", appId);
            data.put("metric", metric);
            data.put("dimensions", dimensions);
            data.put("condition", condition);

            QueryEncoder q = new QueryEncoder();
            String newData = q.toQueryString(data);

            String newUrl = String.format("%s?%s", apiUrl, newData);


            try{
                URL url = new URL(newUrl);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                //conn.setRequestMethod("GET");
                //conn.setRequestProperty("Authorization", "Basic");
                //conn.setRequestProperty(apiKey,apiSecret);
                conn.setRequestProperty("Authorization", "Basic " + encoding3);
                conn.setRequestProperty("Accept", "application/vnd.localytics.v1+hal+json");


                if (conn.getResponseCode() != 200) {
                    throw new RuntimeException("Failed : HTTP error code : "
                            + conn.getResponseCode());
                }

                BufferedReader br = new BufferedReader(new InputStreamReader(
                        (conn.getInputStream())));

                String output;
                System.out.println("Output from Server .... \n");
                while ((output = br.readLine()) != null) {
                    System.out.println(output);
                }

                conn.disconnect();

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (ProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
       }
    }

I am able to get it to work fine in php with Curl with the following:

function call_localytics_api($method, $url, $data)
{
    $curl = curl_init();
    $url = sprintf("%s?%s", $url, http_build_query($data));
    $api_key = "myKey";
    $api_secret = "mySecret";
    // Optional Authentication:
    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($curl, CURLOPT_USERPWD, $api_key . ":" . $api_secret);
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    // Disable the SSL verificaiton process
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array("Accept: application/vnd.localytics.v1+hal+json"));

    // Confirm cURL gave a result, if not, write the error

    $response = curl_exec($curl);

    if ($response === FALSE) {
        die("Curl Failed: " . curl_error($curl));
    } else {
        return $response;
    }
}

$api_querystring = "https://api.localytics.com/v1/query";
$app_id = "myAppId";

$metric = "sessions";
$dimensions = "day";
//$data = array(app_id => $app_id, metrics => $metric, dimensions => $dimensions, conditions => '{"day":["in","'.$requestDate.'"]}');
$data = array(app_id => $app_id, metrics => $metric, dimensions => $dimensions, conditions => '{"day":["between","'.$newDate.'","'.$newDate.'"]}');
$response = call_localytics_api('GET', $api_querystring, $data);
$json = json_decode($response);
print_r($json);

Just need help getting it to work in Java.

like image 363
teej2542 Avatar asked May 11 '16 18:05

teej2542


1 Answers

It appears the illegal character is a newline. Use a base 64 encoder that doesn't put newlines in the result, or remove the newline yourself.

As of Java 8, you should use:

String encoding3 = Base64.getEncoder().encodeToString(
    credentials.getBytes(StandardCharsets.UTF_8));

In older versions of Java, you can use DatatypeConverter:

String encoding3 = DatatypeConverter.printBase64Binary(
    credentials.getBytes(StandardCharsets.UTF_8));

You could also remove the newline character directly, but you should use one of the above approaches instead. The sun.* classes are not for development use, and they can change or disappear from one Java release to the next. Furthermore, as I understand it, they may not even be usable at all as of Java 9, regardless of whether they exist, due to module restrictions.

like image 61
VGR Avatar answered Oct 04 '22 23:10

VGR