class TrafficCaptureService : VpnService(), Handler.Callback, Runnable {

    private var mHandler: Handler? = null
    private var mThread: Thread? = null
    private var mInterface: ParcelFileDescriptor? = null

    private lateinit var proxyClient: ProxyClient

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // Initialize the handler if it's not already created.
        Log.d(TAG, "TrafficCaptureService started")

        proxyClient = ProxyClient("192.168.49.1")

        if (mHandler == null) {
            mHandler = Handler(this)
        }

        // Stop the previous session if any.
        mThread?.interrupt()

        // Start a new session by creating a new thread.
        mThread = Thread(this, "TrafficCaptureThread")
        mThread?.start()

        return START_STICKY
    }

    override fun onDestroy() {
        // Interrupt the thread when the service is destroyed.
        Log.d(TAG, "TrafficCaptureService destroyed")

        mThread?.interrupt()
    }

    override fun handleMessage(message: Message): Boolean {
        Toast.makeText(this, message.what, Toast.LENGTH_SHORT).show()
        Log.d(TAG, "handleMessage(): message received: ${message.what}")
        return true
    }

    override fun run() {
        Log.i(TAG, "Running VPN Service")
        try {
            runVpnConnection()
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            try {
                mInterface?.close()
            } catch (e: Exception) {
                Log.i(TAG, "Running VPN Service failed: ${e.message}")
            }
            mInterface = null
            Log.i(TAG, "Running VPN Service failed: mInterface = null")

            mHandler?.sendEmptyMessage(R.string.disconnected)
            Log.i(TAG, "Exiting VPN service")
        }
    }

    @Throws(Exception::class)
    private fun runVpnConnection() {
        Log.i(TAG, "Running VPN connection")
        configure()

        val inputStream = FileInputStream(mInterface?.fileDescriptor)
        val packet = ByteBuffer.allocate(32767)

        while (true) {
            var idle = true

            // Read outgoing packet from the input stream.
            val length = inputStream.read(packet.array())
            if (length > 0) {
                Log.i(TAG, "New packet received")
                packet.limit(length)

                // Parse packet to check if it's an HTTP request
                val httpUrl = parsePacketToHttpUrl(packet)
                Log.d(TAG, "startPacketCaptureLoop(): captured httpUrl = $httpUrl")

                // If a URL was parsed, forward it to the ProxyServer

                // After processing the packet, clear the buffer.
                packet.clear()

                idle = false
            }

            // Sleep to avoid tight looping.
            Thread.sleep(50)
        }
    }
    private fun parsePacketToHttpUrl(packet: ByteBuffer): String? {
        packet.position(0)  // Start at the beginning of the packet

        // Check that we have at least the minimum IP header length
        if (packet.remaining() < 20) {
            Log.d(TAG, "Packet too short for IP header")
            return null
        }

        // IP header length (in 32-bit words)
        val ipHeaderLength = (packet.get(0).toInt() and 0x0F) * 4
        if (ipHeaderLength < 20 || packet.remaining() < ipHeaderLength) {
            Log.d(TAG, "Invalid or incomplete IP header")
            return null
        }

        // Move to the TCP header
        packet.position(ipHeaderLength)

        // Check if we have enough data for the TCP header length field
        if (packet.remaining() < 20) {
            Log.d(TAG, "Packet too short for TCP header")
            return null
        }

        // TCP header length (in 32-bit words) from the 12th byte of the TCP header
        val tcpHeaderLength = (packet.get(packet.position() + 12).toInt() shr 4) * 4
        if (tcpHeaderLength < 20 || packet.remaining() < tcpHeaderLength) {
            Log.d(TAG, "Invalid TCP header length: $tcpHeaderLength")
            return null
        }

        // Move to the HTTP data start
        packet.position(ipHeaderLength + tcpHeaderLength)

        // Extract HTTP data as a string
        val httpData = String(packet.array(), packet.position(), packet.remaining())
        Log.i(TAG, "HTTP data extracted: $httpData")

        // Look for an HTTP GET or POST request pattern to find the URL
        val regex = Regex("GET (https?://[^ ]+)|POST (https?://[^ ]+)", RegexOption.IGNORE_CASE)
        val matchResult = regex.find(httpData)

        return matchResult?.groups?.get(1)?.value ?: matchResult?.groups?.get(2)?.value
    }

    // Helper function to parse destination IP address from the packet
    private fun parseDestinationIp(packet: ByteBuffer): String {
        return (1..4).joinToString(".") { (packet.get(16 + it - 1).toInt() and 0xFF).toString() }
    }

    private fun getLocalIpAddress(): String? {
        try {
            val networkInterfaces = NetworkInterface.getNetworkInterfaces()
            while (networkInterfaces.hasMoreElements()) {
                val networkInterface = networkInterfaces.nextElement()
                val inetAddresses = networkInterface.inetAddresses
                while (inetAddresses.hasMoreElements()) {
                    val inetAddress = inetAddresses.nextElement()
                    Log.i(TAG, "INET ADDRESS: ${inetAddress.hostAddress}")
                    if (!inetAddress.isLoopbackAddress) {
                        return inetAddress.hostAddress
                    }
                }
            }
        } catch (e: SocketException) {
            Log.e(TAG, e.toString())
        }
        return null
    }

    @Throws(Exception::class)
    private fun configure() {
        // Use the existing interface if it's still valid.
        if (mInterface != null) {
            Log.i(TAG, "Using the previous interface")
            return
        }

        // Configure VPN interface.
        val builder = Builder()
        builder.setMtu(1500)
            .addAddress("10.0.0.2", 24) // Example internal IP address
            .addRoute("0.0.0.0", 0) // Route all traffic through VPN

        try {
            mInterface?.close()
        } catch (e: Exception) {
            Log.i(TAG, "configure(): Failed to close old interface (mInterface = null)")
        }

        mInterface = builder.establish()
        Log.i(TAG, "configure(): mInterface = $mInterface")
    }

    companion object {
        private const val TAG = "#TrafficCaptureService"
    }
}
I am trying to convert the byte packets into an Http request but this service fails to do so , I was thinking about using Ktor how should I achieve my result ?