Skip to content

Commit

Permalink
Merge branch 'main' into feature/load-test
Browse files Browse the repository at this point in the history
  • Loading branch information
sunny-chung committed Apr 18, 2024
2 parents cd7b0b1 + 311ee94 commit a8e6344
Show file tree
Hide file tree
Showing 33 changed files with 2,636 additions and 154 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ Watch the images and videos on the [website](https://sunny-chung.github.io/hello
- UUID (type `$((uuid))`)
- Current date-time ISO-8601 string (type `$((now.iso8601))`)
- Current timestamp (type `$((now.epochMills))` or `$((now.epochSeconds))`)
- Copying as verbose cURL commands (only for Linux & macOS)
- Copying as verbose [grpcurl](https://github.com/fullstorydev/grpcurl) commands (only for Linux & macOS)
- Executing custom safe script to mutate a Request before firing it
- Copying as verbose cURL commands
- Copying as verbose [grpcurl](https://github.com/fullstorydev/grpcurl) commands
- Copying as PowerShell Invoke-WebRequest command (for Windows pwsh.exe)

**Response**
- Post flight actions
Expand Down
7 changes: 5 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ val grpcVersion = "1.59.1"

kotlin {
jvm {
jvmToolchain(11)
jvmToolchain(17)
withJava()
}
sourceSets {
Expand Down Expand Up @@ -64,12 +64,15 @@ kotlin {
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2")
implementation("com.jayway.jsonpath:json-path:2.8.0")

implementation("io.github.sunny-chung:kdatetime-multiplatform:0.5.0")
implementation("io.github.sunny-chung:kdatetime-multiplatform:1.0.0")

implementation("net.harawata:appdirs:1.2.2")
implementation("com.darkrockstudios:mpfilepicker:2.1.0")

implementation("org.jetbrains.compose.components:components-splitpane:1.5.2")

implementation("io.github.sunny-chung:kotlite-interpreter:1.1.0-snapshot.2")
implementation("io.github.sunny-chung:kotlite-stdlib:1.1.0-snapshot.1")
}

resources.srcDir("$buildDir/resources")
Expand Down
Binary file added doc/_include/copy-command.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_include/pre-flight-script.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_include/user-files.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions doc/features/command-generation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: Command Generation
---

# Command Generation

![Generate and copy commands](../copy-command.gif)

Some types of requests allow copying as shell commands. Click the dropdown menu near the "Send" or "Connect" button, and the copy buttons are there.

Supported operations are as follows:

| Request | Copying as verbose cURL commands | Copying as verbose [grpcurl](https://github.com/fullstorydev/grpcurl) commands | Copying as PowerShell Invoke-WebRequest command (for Windows pwsh.exe) |
|------------------------------|----------------------------------|--------------------------------------------------------------------------------|------------------------------------------------------------------------|
| HTTP / REST | ✔︎ || ✔︎ |
| WebSocket ||||
| GraphQL Query | ✔︎ || ✔︎ |
| GraphQL Mutation | ✔︎ || ✔︎ |
| GraphQL Subscription ||||
| gRPC Unary || ✔︎ ||
| gRPC Client Streaming || ✔︎ ||
| gRPC Server Streaming || ✔︎ ||
| gRPC Bidirectional Streaming || ✔︎ ||
4 changes: 2 additions & 2 deletions doc/features/data-import-export.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: Data Import & Export

## Data Import

Welcome to bring in data from other applications to try Hello HTTP! Enjoy data freedom! Currently suppported data
Welcome to bring in data from other applications to try Hello HTTP! Enjoy data freedom! Currently supported data
formats are:

- Insomnia v4 JSON
Expand All @@ -15,7 +15,7 @@ formats are:
- Hello HTTP data dump

## Data Export
Create a manual backup, or leave anytime you want! Currently suppported data formats are:
Create a manual backup, or leave anytime you want! Currently supported data formats are:
- Insomnia v4 JSON
- Hello HTTP data dump
- Postman v2 Data Dump (One File per Project or Environment)
Expand Down
1 change: 1 addition & 0 deletions doc/features/environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Each environment may contain the followings:
- Zero or more variables
- HTTP protocol version preference
- SSL verification preference
- Zero or more user files (for scripts)

## Creating an Environment

Expand Down
234 changes: 234 additions & 0 deletions doc/features/user-script.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
---
title: User Script
---

# User Script

Hello HTTP allows the use of custom script to perform a limited set of operations that are not possible or difficult to do via the UI. The supported programming language is [Kotlite](https://sunny-chung.github.io/kotlite/#_the_kotlite_language), a subset of the **Common** variant of the [Kotlin](https://kotlinlang.org/docs/basic-syntax.html) 1.9 **script** language. Script means it does not require a `main` function and the statements at the outermost scope will be executed sequentially.

It is not quite possible to do anything harmful by user scripts, because both the language and the APIs available to be used are limited. For example, it is not possible to make another HTTP request directly from the script, nor modify the URL of the current script, nor execute system commands. There is also a short time limit on execution.

An example use case of user scripts is to generate some hash or signature with some encryption keys and embed into a request before sending it.

## Providing custom files for user script use

Files can be imported into an [Environment](environments) to be consumed by user script. Only small files can be imported.

![User Files](../user-files.png)

Names can be changed after importing.

## Pre-flight Script

Custom pre-flight script can be provided to a [request example](request-examples-and-payload-examples). It would be executed before firing the request.

It is only available for:
- Plain/RESTful HTTP requests
- GraphQL requests

Similar to other request example properties, the script in the "Base" example can be overridden by other request examples.

![Pre-flight Script](../pre-flight-script.png)

The only supported mutation operations are:
- append headers
- append query parameters

All APIs in the [standard library](https://sunny-chung.github.io/kotlite/#_built_in_and_standard_library_apis) can be used.

In additional, below inputs and APIs are available as follow.

### Global Properties

```kotlin
/**
* Request object.
*
* @param <BODY> One of `Nothing`, `StringBodyClass`, `FormUrlEncodedBodyClass`, `MultipartBodyClass`, `FileBodyClass`, `GraphqlBodyClass`.
*/
val request: MutableRequest<BODY>

/**
* The environment chosen to be active. Null if there is none.
*/
val environment: Environment?
```

### Types

#### `Request`

```kotlin
class Request<BODY>

val Request<*>.url: String
val Request<*>.method: String
val Request<*>.headers: List<Pair<String, String>>
val Request<*>.queryParameters: List<Pair<String, String>>
val <BODY> Request<BODY>.body: BODY?

/**
* Get a properly encoded URI embedded with query parameters.
*/
fun Request<*>.getResolvedUri(): String
```

#### `MutableRequest`

```kotlin
class MutableRequest<BODY> : Request<BODY>

fun MutableRequest<*>.addHeader(key: String, value: String)
fun MutableRequest<*>.addQueryParameter(key: String, value: String)
```

#### `Environment`

```kotlin
class Environment

val Environment.name: String

/**
* Environment variables. Only enabled variables are available.
*/
val Environment.variables: List<UserKeyValuePair>

/**
* User files. Only enabled user files are available.
*/
val Environment.userFiles: List<ImportedFile>
```

#### `UserKeyValuePair`

```kotlin
class UserKeyValuePair

val UserKeyValuePair.key: String
val UserKeyValuePair.value: String

/**
* Either "String" or "File".
*/
val UserKeyValuePair.valueType: String

/**
* If valueType is "String", return the bytes of the String value.
* If valueType is "File", return the bytes of the underlying file, or null if no file is selected. Exception would be thrown if a file is specified and cannot be read.
*/
fun UserKeyValuePair.readValueBytes(): ByteArray?
```

#### `StringBody`

```kotlin
class StringBody

val StringBody.value: String
```

#### `FormUrlEncodedBody`

```kotlin
class FormUrlEncodedBody

val FormUrlEncodedBody.value: List<UserKeyValuePair>
```

#### `MultipartBody`

```kotlin
class MultipartBody

val MultipartBody.value: List<UserKeyValuePair>
```

#### `FileBody`

```kotlin
class FileBody

val FileBody.filePath: String?

/**
* Return the bytes of the underlying file, or null if no file is selected. Exception would be thrown if a file is specified and cannot be read.
*/
val FileBody.readBytes(): ByteArray?
```

#### `GraphqlBody`

```kotlin
class GraphqlBody

val GraphqlBody.document: String
val GraphqlBody.variables: String
val GraphqlBody.operationName: String?
```

#### `ImportedFile`

```kotlin
class ImportedFile

val ImportedFile.name: String
val ImportedFile.originalFilename: String
val ImportedFile.createdWhen: KInstant
val ImportedFile.content: ByteArray
```

#### `PublicKey`

```kotlin
class PublicKey
```

#### `PrivateKey`

```kotlin
class PrivateKey
```

#### `SecretKey`

```kotlin
class SecretKey
```

### Extensions

#### Encoding

````kotlin
fun ByteArray.encodeToBase64String(): String
fun ByteArray.encodeToBase64UrlString(): String
fun ByteArray.encodeToHexString(): String

fun String.decodeBase64StringToByteArray(): ByteArray
fun String.decodeBase64UrlStringToByteArray(): ByteArray
fun String.decodeHexStringToByteArray(): ByteArray

fun String.decodeJsonStringToMap(): Map<Any?, Any?>
````

#### Crypto

````kotlin
fun ByteArray.toSha1Hash(): ByteArray
fun ByteArray.toSha256Hash(): ByteArray
fun ByteArray.toSha512Hash(): ByteArray
fun ByteArray.toMd5Hash(): ByteArray
fun ByteArray.toSha1WithRsaSignature(rsaPrivateKey: PrivateKey): ByteArray
fun ByteArray.toSha256WithRsaSignature(rsaPrivateKey: PrivateKey): ByteArray

fun ByteArray.toPkcs8RsaPublicKey(): PublicKey
fun ByteArray.toPkcs8RsaPrivateKey(): PrivateKey
fun ByteArray.toAesSecretKey(): SecretKey

/**
* Example value of parameter `algorithm`: "AES/CBC/PKCS5Padding"
*/
fun ByteArray.asEncrypted(algorithm: String, key: SecretKey, iv: ByteArray? = null): ByteArray
fun ByteArray.asDecrypted(algorithm: String, key: SecretKey, iv: ByteArray? = null): ByteArray
````
2 changes: 0 additions & 2 deletions doc/transports/grpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,4 @@ A [grpcurl](https://github.com/fullstorydev/grpcurl) command can be copied to se
shell. All service method types are supported. If only response bodies are needed, the verbose option `-v` can be
removed.

Note: It is only available for Linux & macOS.

![grpcurl](../grpcurl.png)
2 changes: 2 additions & 0 deletions doctave.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ navigation:
- path: doc/features/project-and-request-management.md
- path: doc/features/request-examples-and-payload-examples.md
- path: doc/features/custom-http-methods.md
- path: doc/features/command-generation.md
- path: doc/features/environments.md
- path: doc/features/ssl-configuration.md
- path: doc/features/functions.md
- path: doc/features/user-script.md
- path: doc/features/post-flight-actions.md
- path: doc/features/viewing-responses.md
- path: doc/features/transport-timeline.md
Expand Down
Loading

0 comments on commit a8e6344

Please sign in to comment.