diff --git a/docs/docs/en/changelog.md b/docs/docs/en/changelog.md index cfdc37b..195c527 100644 --- a/docs/docs/en/changelog.md +++ b/docs/docs/en/changelog.md @@ -6,6 +6,9 @@ - Fix passing command-line arguments to scripts - Fix `this` in non-static class methods +### Modules +- [okhttp] Added `okhttp.newClient()` and `HttpClientBuilderValue` + ## 2.0.0 diff --git a/docs/docs/ru/changelog.md b/docs/docs/ru/changelog.md index 7e914a2..c8c7799 100644 --- a/docs/docs/ru/changelog.md +++ b/docs/docs/ru/changelog.md @@ -6,6 +6,9 @@ - Исправлена передача аргументов командной строки скриптам - Исправлен `this` в нестатических методах классов +### Modules +- [okhttp] Добавлен `okhttp.newClient()` и `HttpClientBuilderValue` + ## 2.0.0 diff --git a/docs/src/modules/okhttp.yml b/docs/src/modules/okhttp.yml index d53eaaa..09c74f8 100644 --- a/docs/src/modules/okhttp.yml +++ b/docs/src/modules/okhttp.yml @@ -170,6 +170,10 @@ types: args: '' desc: returns RequestBuilderValue desc_ru: возвращает RequestBuilderValue + - name: newClient + args: '' + desc: returns HttpClientBuilderValue + desc_ru: возвращает HttpClientBuilderValue - name: HttpClientValue functions: - name: connectTimeoutMillis @@ -208,3 +212,30 @@ types: args: '' desc: '' desc_ru: '' + - name: HttpClientBuilderValue + functions: + - name: callTimeout + args: 'duration, timeUnit' + desc: 'Sets call timeout for `duration` and `timeUnit` one of "millis"/"milliseconds", "seconds", "minutes", "hours", "days"' + desc_ru: 'Устанавливает таймаут вызова в `duration` и `timeUnit` один из "millis"/"milliseconds", "seconds", "minutes", "hours", "days"' + - name: connectTimeout + args: 'duration, timeUnit' + desc: 'Sets connect timeout for `duration` and `timeUnit` one of "millis"/"milliseconds", "seconds", "minutes", "hours", "days"' + desc_ru: 'Устанавливает таймаут соединения в `duration` и `timeUnit` один из "millis"/"milliseconds", "seconds", "minutes", "hours", "days"' + - name: readTimeout + args: 'duration, timeUnit' + desc: 'Sets read timeout for `duration` and `timeUnit` one of "millis"/"milliseconds", "seconds", "minutes", "hours", "days"' + desc_ru: 'Устанавливает таймаут чтения в `duration` и `timeUnit` один из "millis"/"milliseconds", "seconds", "minutes", "hours", "days"' + - name: writeTimeout + args: 'duration, timeUnit' + desc: 'Sets write timeout for `duration` and `timeUnit` one of "millis"/"milliseconds", "seconds", "minutes", "hours", "days"' + desc_ru: 'Устанавливает таймаут записи в `duration` и `timeUnit` один из "millis"/"milliseconds", "seconds", "minutes", "hours", "days"' + - name: retryOnConnectionFailure + args: 'flag' + desc: 'Enables or disables retry on connection failure' + desc_ru: 'Включает или выключает повтор при ошибках соединения' + - name: build + args: '' + desc: 'Returns new HttpClientValue' + desc_ru: 'Возвращает новый HttpClientValue' + diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/HttpClientBuilderValue.java b/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/HttpClientBuilderValue.java new file mode 100644 index 0000000..43ef48b --- /dev/null +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/HttpClientBuilderValue.java @@ -0,0 +1,52 @@ +package com.annimon.ownlang.modules.okhttp; + +import com.annimon.ownlang.exceptions.OwnLangRuntimeException; +import com.annimon.ownlang.lib.*; +import okhttp3.*; +import java.util.concurrent.TimeUnit; + +public class HttpClientBuilderValue extends MapValue { + + private final OkHttpClient.Builder builder; + + public HttpClientBuilderValue(OkHttpClient.Builder builder) { + super(6); + this.builder = builder; + init(); + } + + private void init() { + set("callTimeout", timeout(builder::callTimeout)); + set("connectTimeout", timeout(builder::connectTimeout)); + set("readTimeout", timeout(builder::readTimeout)); + set("writeTimeout", timeout(builder::writeTimeout)); + set("retryOnConnectionFailure", args -> { + builder.retryOnConnectionFailure(args[0].asInt() != 0); + return this; + }); + set("build", args -> new HttpClientValue(builder.build())); + } + + private FunctionValue timeout(Timeout timeout) { + return new FunctionValue(args -> { + Arguments.check(2, args.length); + long duration = args[0].type() == Types.NUMBER + ? ((NumberValue) args[0]).asLong() + : args[0].asInt(); + TimeUnit unit = switch (args[1].asString().toLowerCase()) { + case "millis", "milliseconds" -> TimeUnit.MILLISECONDS; + case "seconds" -> TimeUnit.SECONDS; + case "minutes" -> TimeUnit.MINUTES; + case "hours" -> TimeUnit.HOURS; + case "days" -> TimeUnit.DAYS; + default -> throw new OwnLangRuntimeException("Unknown unit type"); + }; + timeout.timeout(duration, unit); + return this; + }); + } + + interface Timeout { + void timeout(long duration, TimeUnit unit); + } +} diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/HttpClientValue.java b/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/HttpClientValue.java index baea7c9..f004c3f 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/HttpClientValue.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/HttpClientValue.java @@ -8,6 +8,7 @@ import okhttp3.Response; import okhttp3.WebSocket; import okhttp3.WebSocketListener; import okio.ByteString; +import java.util.Objects; public class HttpClientValue extends MapValue { @@ -117,6 +118,7 @@ public class HttpClientValue extends MapValue { } } }); + Objects.requireNonNull(ws); return new CallValue(client.newCall(request)); } } diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/okhttp.java b/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/okhttp.java index c593d6d..c2179a2 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/okhttp.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/okhttp.java @@ -17,6 +17,24 @@ public final class okhttp implements Module { @Override public Map constants() { + MapValue okhttp = new MapValue(3); + okhttp.set("client", defaultClient); + okhttp.set("request", args -> new RequestBuilderValue()); + okhttp.set("newClient", args -> newClientBuilder()); + + return Map.of( + "RequestBody", requestBody(), + "MultipartBody", multipartBody(), + "okhttp", okhttp + ); + } + + @Override + public Map functions() { + return Collections.emptyMap(); + } + + private static MapValue requestBody() { MapValue requestBody = new MapValue(5); requestBody.set("bytes", args -> { Arguments.checkOrOr(2, 4, args.length); @@ -52,8 +70,10 @@ public final class okhttp implements Module { args[1].asString() )); }); + return requestBody; + } - + private static MapValue multipartBody() { MapValue multipartBody = new MapValue(6); multipartBody.set("ALTERNATIVE", new StringValue(MultipartBody.ALTERNATIVE.toString())); multipartBody.set("DIGEST", new StringValue(MultipartBody.DIGEST.toString())); @@ -61,21 +81,10 @@ public final class okhttp implements Module { multipartBody.set("MIXED", new StringValue(MultipartBody.MIXED.toString())); multipartBody.set("PARALLEL", new StringValue(MultipartBody.PARALLEL.toString())); multipartBody.set("builder", args -> new MultipartBodyBuilderValue()); - - - MapValue okhttp = new MapValue(3); - okhttp.set("client", defaultClient); - okhttp.set("request", args -> new RequestBuilderValue()); - - return Map.of( - "RequestBody", requestBody, - "MultipartBody", multipartBody, - "okhttp", okhttp - ); + return multipartBody; } - @Override - public Map functions() { - return Collections.emptyMap(); + private static HttpClientBuilderValue newClientBuilder() { + return new HttpClientBuilderValue(new OkHttpClient.Builder()); } }