http.kt (2391B)
1 /* 2 * This file is part of LibEuFin. 3 * Copyright (C) 2024-2025 Taler Systems S.A. 4 5 * LibEuFin is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Affero General Public License as 7 * published by the Free Software Foundation; either version 3, or 8 * (at your option) any later version. 9 10 * LibEuFin is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General 13 * Public License for more details. 14 15 * You should have received a copy of the GNU Affero General Public 16 * License along with LibEuFin; see the file COPYING. If not, see 17 * <http://www.gnu.org/licenses/> 18 */ 19 20 package tech.libeufin.ebics 21 22 import io.ktor.http.* 23 import io.ktor.http.content.* 24 import io.ktor.client.* 25 import io.ktor.client.request.* 26 import io.ktor.client.plugins.* 27 import io.ktor.client.engine.mock.* 28 import java.time.Instant 29 import java.time.ZoneId 30 import java.time.format.DateTimeFormatter 31 32 /** Use for unit testing */ 33 var MOCK_ENGINE: MockEngine? = null 34 35 /** Create an HTTP client for EBICS requests */ 36 fun httpClient(): HttpClient = MOCK_ENGINE?.let { 37 HttpClient(it) 38 } ?: HttpClient { 39 install(HttpTimeout) { 40 // It can take a lot of time for the bank to generate documents 41 socketTimeoutMillis = 5 * 60 * 1000 42 } 43 } 44 45 /** Gets an HTTP client whose requests are going to be served by 'handler' */ 46 fun getMockedClient( 47 handler: MockRequestHandleScope.(HttpRequestData) -> HttpResponseData 48 ): HttpClient = HttpClient(MockEngine) { 49 followRedirects = false 50 engine { 51 addHandler { 52 request -> handler(request) 53 } 54 } 55 } 56 57 private lateinit var steps: Iterator<(String) -> ByteArray> 58 59 object BadRequest: Exception() 60 61 fun setMock(sequences: Sequence<(String) -> ByteArray>) { 62 steps = sequences.iterator() 63 if (MOCK_ENGINE == null) { 64 val cfg: MockEngineConfig = MockEngineConfig() 65 cfg.addHandler { req -> 66 val body = String((req.body as OutgoingContent.ByteArrayContent).bytes()) 67 val handler = steps.next() 68 try { 69 val res = handler(body) 70 respond(res) 71 } catch (e: BadRequest) { 72 respondBadRequest() 73 } 74 } 75 MOCK_ENGINE = MockEngine(cfg) 76 } 77 }