сервер возвращает 401

написал на kotlin такой код.

fun encode ( key : String, data : String ) : String {
    val sha = Mac.getInstance("HmacSHA256")
    val secret = SecretKeySpec(key.toByteArray(Charset.forName("UTF-8")), "HmacSHA256")
    sha.init(secret)
    return Hex.encodeHexString(sha.doFinal(data.toByteArray(Charset.forName("UTF-8"))))
}
fun main (args: Array<String> ) {
    val url = URL("https://www.bitmex.com/api/v1/user/wallet")
    val con = url.openConnection() as HttpsURLConnection
    var timestamp = Timestamp(System.currentTimeMillis())
    var exp_time = timestamp.time / 1000 + 10
    val signature = encode(secret_key, "GET/api/v1/user/wallet$exp_time")
    con.requestMethod = "GET"
    con.doOutput = true
    con.setRequestProperty("api-key", api_key)
    con.setRequestProperty("api-signature", signature)
    con.setRequestProperty("api-expires",exp_time.toString())
    val out_stream = DataOutputStream(con.outputStream)
    //out_stream.writeBytes("")
    out_stream.flush()
    out_stream.close()
    val in_stream = BufferedReader(InputStreamReader(con.inputStream))
    var data : String = ""
    data = in_stream.readText()
    println(data)
}

хочу получить данные из кошелька. вот что в ответ выводиться.

Exception in thread "main" java.io.IOException: Server returned HTTP response code: 401 for URL: https://www.bitmex.com/api/v1/user/wallet
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1927)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1523)
    at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:224)
    at MainKt.main(main.kt:39)

Process finished with exit code 1

хотя на языке C и curl всё нормально обрабатывается. И ещё. очень странно. я поставил логирование и почему то пишет что это POST запрос, хотя я указал requestMethod.

FINE: sun.net.www.MessageHeader@4ba2ca3610 pairs: {POST /api/v1/user/wallet HTTP/1.1: null}{accept: */*}

Ответы (1 шт):

Автор решения: Eugene Krivenja

Если взять чтение данных (четыре последние строки) в try-catch и после добавить

println(con.requestMethod)

то увидите там POST

Все потому, что при получении con.outputStream исполняется вот такой код JDK

if (method.equals("GET")) {
    method = "POST"; // Backward compatibility
}

GET запросы не подразумевают тело, хотя по стандарту HTTP это не запрещено.
В вашем случае тело хоть и пустое, но оно заявлено.

Просто удалите строчки с out_stream. Получение con.responseCode перед чтением данных является правильной практикой, но не обязательной для получения результата.

→ Ссылка