/* Mangadex@Home Copyright (c) 2020, MangaDex Network This file is part of MangaDex@Home. MangaDex@Home is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. MangaDex@Home is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this MangaDex@Home. If not, see . */ package mdnet import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.module.kotlin.KotlinModule import mdnet.ServerHandlerJackson.auto import mdnet.logging.info import mdnet.settings.* import okhttp3.Dns import okhttp3.OkHttpClient import org.http4k.client.OkHttp import org.http4k.core.* import org.http4k.format.ConfigurableJackson import org.http4k.format.asConfigurable import org.http4k.format.withStandardMappings import org.http4k.lens.LensFailure import org.slf4j.LoggerFactory import java.net.Inet4Address import java.net.InetAddress object ServerHandlerJackson : ConfigurableJackson( KotlinModule() .asConfigurable() .withStandardMappings() .done() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) ) class BackendApi(private val settings: ClientSettings) { private val client = OkHttp( client = OkHttpClient.Builder() .dns(object : Dns { override fun lookup(hostname: String): List { return Dns.SYSTEM.lookup(hostname).filterIsInstance() } }) .build() ) private val serverAddress = settings.devSettings.devUrl ?: SERVER_ADDRESS fun logoutFromControl(): Boolean { val serverSettings = settings.serverSettings LOGGER.info { "Disconnecting from the control server" } val request = LOGOUT_REQUEST_LENS( LogoutRequest(serverSettings.secret), Request(Method.POST, serverAddress + "stop") ) val response = client(request) return response.status.successful } private fun getPingParams(tlsCreatedAt: String? = null): SettingsRequest { val serverSettings = settings.serverSettings return SettingsRequest( secret = serverSettings.secret, port = if (serverSettings.externalPort != 0) { serverSettings.externalPort } else { serverSettings.port }, buildVersion = Constants.CLIENT_BUILD, diskSpace = settings.maxCacheSizeInMebibytes * 1024 * 1024, networkSpeed = serverSettings.externalMaxKilobitsPerSecond * 1000 / 8, ipAddress = serverSettings.externalIp, tlsCreatedAt = tlsCreatedAt, ) } fun loginToControl(): PingResult { LOGGER.info { "Connecting to the control server" } val request = SETTINGS_REQUEST_LENS( getPingParams(null), Request( Method.POST, serverAddress + "ping" ) ) return client.makeRequest(request) } fun pingControl(old: RemoteSettings): PingResult { LOGGER.info { "Pinging the control server" } val request = SETTINGS_REQUEST_LENS( getPingParams(old.tls!!.createdAt), Request( Method.POST, serverAddress + "ping" ) ) return client.makeRequest(request) } private fun HttpHandler.makeRequest(request: Request): PingResult { val response = this(request) return when { response.status.successful -> { SERVER_SETTINGS_LENS(response) } else -> { try { PING_FAILURE_LENS(response) } catch (e: LensFailure) { PingFailure(response.status.code, response.bodyString()) } } } } companion object { private val LOGGER = LoggerFactory.getLogger(BackendApi::class.java) private val SETTINGS_REQUEST_LENS = Body.auto().toLens() private val PING_FAILURE_LENS = Body.auto().toLens() private val LOGOUT_REQUEST_LENS = Body.auto().toLens() private val SERVER_SETTINGS_LENS = Body.auto().toLens() private const val SERVER_ADDRESS = "https://api.mangadex.network/" } }