httpx - CLI to test HTTP/gRPC/RSocket/Kafka... services by HTTP DSL

Related tags

Spring Boot httpx
Overview

httpx: CLI for run http file

httpx is a CLI to execute requests from JetBrains Http File.

Request types supported by httpx

  • HTTP REST
  • PUB/SUB - Apache Kafka/Redpanda, Apache Pulsar, RabbitMQ, NATS, Redis, MQTT, AMQP, Stomp, ZeroMQ
  • gRPC
  • RSocket
  • Apache Dubbo
  • Sofa RPC
  • Email sending by SMTP
  • GraphQL over HTTP/WebSocket/RSocket
  • Memcache: set/get/delete
  • Redis: set/hmset/eval
  • msgpack-rpc: with Neovim support
  • json-rpc: HTTP and TCP transports support
  • Cloud Open API: AWS and Aliyun

How to install?

How to use?

Create index.http file with following code, then chmod u+x index.http

#!/usr/bin/env httpx --httpfile

### get my internet ip
# @name myip
GET https://httpbin.org/ip

### inspection http post
# @name post
POST https://httpbin.org/post
Content-Type: application/json

[ 1 ]

### RSocket Request
// @name request
RSOCKET com.example.UserService.findById
Host: 127.0.0.1:42252
Content-Type: application/json

1

### grpc call SayHello
//@name SayHello
GRPC localhost:50052/org.mvnsearch.service.Greeter/SayHello

{
  "name": "Jackie"
}

### graphql query
//@name query
GRAPHQL http://localhost:8080/graphql
Content-Type: application/graphql

query { hello }

### send an email by Gmail
//@name mail
MAIL mailto:[email protected]
Host: tls://smtp.gmail.com:587
Authorization: Basic [email protected]:google_app_password
From: [email protected]
Subject: e-nice to meet you
Content-Type: text/plain

Hi Master:
  this is testing email.

Best regards
Yours sincerely Zombie

Then input httpx myip or ./index.http myip to invoke request.

Protocols Support

  • HTTP Request
  • RSocket Request
  • GRPC Request: you should install grpcurl
  • GraphQL support: Query, Mutation and Subscribe on HTTP and WebSocket(graphql-ws)
  • EMAIL: send email by SMTP
  • PUB/SUB: pub/sub support for Kafka, RabbitMQ/ActiveMQ, Nats, Redis, MQTT, Stomp and Aliyun MNS/EventBridge.

Email sending

Email URL format: mailto:[email protected][email protected]

oh-my-zsh integration for shell completion

Please create ~/.oh-my-zsh/custom/plugins/httpx with following code, then add httpx to plugins in .zshrc file.

#compdef httpx
#autload

local subcmds=()

while read -r line ; do
   if [[ ! $line == Available* ]] ;
   then
      subcmds+=(${line/[[:space:]]*\#/:})
   fi
done < <(httpx --summary)

_describe 'command' subcmds

JavaScript Code test

JetBrains HTTP Client uses JavaScript ECMAScript 5.1 as response handler for test. httpx uses Node.js as JS engine, and you should install Node.js first.

### hello ip
GET https://httpbin.org/ip

> {%
    client.test("Request executed successfully", function() {
        client.log(response.status);
        client.log(response.contentType);
        client.log(response.body);
    });
%}

Attentions:

  • You should know the difference between ECMAScript 5.1 and Node.js
  • JavaScript code test is available for HTTP, gRPC, RSocket, Dubbo and other protocols with httpx

How to build from source?

httpx uses Toolchains Maven Plugin to build project, and you don't need to install GraalVM first, and GraalVM will be installed in ~/.m2/jdks.

./mvnw -Pnative -DskipTests clean package

Development setup

  • docker-compose.yml: MQTT/1883, Stomp/61613, RabbitMQ/5672, SMTP/1025, Redpanda/9092

References

Comments
  • unknown host exception

    unknown host exception

    Hi!

    i try to run auth.http from the command line: httpx --httpfile auth.http

    An exception is thrown (see below).

    There is nothing wrong with the request. When i use Postman to POST https://lvapitest.localhost.wip/api/oauth/v2/token, i get a valid response with status code 200.

    I think the problem is our proxy. We have set the proxy configuration at the system level (MacOs Big Sur) to:

    automatic proxy configuration
    proxy configuration file: http://127.0.0.1:7080/proxy.pac
    

    Is it possible to add the proxy configuration to the command line arguments?

    Regards, Stijn


    auth.http

    #!/usr/bin/env
    
    ### get tokens
    POST https://{{env}}.{{domain}}/api/oauth/v2/token
    Content-Type: application/json
    
    {
        "grant_type": "password",
        "client_id": "{{client_id}}",
        "client_secret": "{{client_secret}}",
        "username": "{{username}}",
        "password": "{{password}}"
    }
    
    > {%
    client.test('Post token', function() {
       client.assert(response.status === 200, 'Response status is not 200');
       client.assert(response.body.hasOwnProperty('access_token'), 'Response  bevat geen access_token');
       client.assert(response.body.hasOwnProperty('refresh_token'), 'Response  bevat geen refresh_token');
    });
    
    if (response.body.hasOwnProperty('access_token') && response.body.hasOwnProperty('refresh_token')) {
        client.global.set("accessToken", response.body['access_token']);
        client.global.set("refreshToken", response.body['refresh_token']);
    }
    %}
    

    Exception

    POST https://lvapitest.localhost.wip/api/oauth/v2/token
    
    2022-04-05 10:51:04.366 ERROR 52922 --- [           main] org.mvnsearch.http.HttpxCommand          : HTX-002-500 - Failed to parse http code!
    
    reactor.core.Exceptions$ReactiveException: io.netty.resolver.dns.DnsResolveContext$SearchDomainUnknownHostException: Failed to resolve 'lvapitest.localhost.wip' and search domain query for configured domains failed as well: [home]
    	at reactor.core.Exceptions.propagate(Exceptions.java:392) ~[na:na]
    	at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:97) ~[na:na]
    	at reactor.core.publisher.Mono.block(Mono.java:1707) ~[na:na]
    	at org.mvnsearch.http.protocol.HttpBaseExecutor.request(HttpBaseExecutor.java:94) ~[na:na]
    	at org.mvnsearch.http.protocol.HttpExecutor.execute(HttpExecutor.java:40) ~[na:na]
    	at org.mvnsearch.http.HttpxCommand.execute(HttpxCommand.java:278) ~[httpx:0.23.0]
    	at org.mvnsearch.http.HttpxCommand.call(HttpxCommand.java:201) ~[httpx:0.23.0]
    	at org.mvnsearch.http.HttpxCommand.call(HttpxCommand.java:33) ~[httpx:0.23.0]
    	at picocli.CommandLine.executeUserObject(CommandLine.java:1953) ~[na:na]
    	at picocli.CommandLine.access$1300(CommandLine.java:145) ~[na:na]
    	at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358) ~[na:na]
    	at picocli.CommandLine$RunLast.handle(CommandLine.java:2352) ~[na:na]
    	at picocli.CommandLine$RunLast.handle(CommandLine.java:2314) ~[na:na]
    	at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179) ~[na:na]
    	at picocli.CommandLine$RunLast.execute(CommandLine.java:2316) ~[na:na]
    	at picocli.CommandLine.execute(CommandLine.java:2078) ~[na:na]
    	at org.mvnsearch.http.HttpFileRunner.run(HttpFileRunner.java:24) ~[httpx:0.23.0]
    	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:777) ~[httpx:0.23.0]
    	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:761) ~[httpx:0.23.0]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[httpx:0.23.0]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[httpx:0.23.0]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[httpx:0.23.0]
    	at org.mvnsearch.http.HttpxApplication.main(HttpxApplication.java:23) ~[httpx:0.23.0]
    	Suppressed: java.lang.Exception: #block terminated with an error
    		at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:99) ~[na:na]
    		... 21 common frames omitted
    Caused by: io.netty.resolver.dns.DnsResolveContext$SearchDomainUnknownHostException: Failed to resolve 'lvapitest.localhost.wip' and search domain query for configured domains failed as well: [home]
    	at io.netty.resolver.dns.DnsResolveContext.finishResolve(DnsResolveContext.java:1047) ~[na:na]
    	at io.netty.resolver.dns.DnsResolveContext.tryToFinishResolve(DnsResolveContext.java:1000) ~[na:na]
    	at io.netty.resolver.dns.DnsResolveContext.query(DnsResolveContext.java:418) ~[na:na]
    	at io.netty.resolver.dns.DnsResolveContext.onResponse(DnsResolveContext.java:629) ~[na:na]
    	at io.netty.resolver.dns.DnsResolveContext.access$400(DnsResolveContext.java:66) ~[na:na]
    	at io.netty.resolver.dns.DnsResolveContext$2.operationComplete(DnsResolveContext.java:462) ~[na:na]
    	at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:578) ~[na:na]
    	at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:571) ~[na:na]
    	at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:550) ~[na:na]
    	at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:491) ~[na:na]
    	at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:616) ~[na:na]
    	at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:605) ~[na:na]
    	at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104) ~[na:na]
    	at io.netty.resolver.dns.DnsQueryContext.trySuccess(DnsQueryContext.java:216) ~[na:na]
    	at io.netty.resolver.dns.DnsQueryContext.finish(DnsQueryContext.java:208) ~[na:na]
    	at io.netty.resolver.dns.DnsNameResolver$DnsResponseHandler.channelRead(DnsNameResolver.java:1314) ~[na:na]
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[na:na]
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[na:na]
    	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[na:na]
    	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[na:na]
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[na:na]
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[na:na]
    	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[na:na]
    	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[na:na]
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[na:na]
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[na:na]
    	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[na:na]
    	at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:97) ~[na:na]
    	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722) ~[na:na]
    	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658) ~[na:na]
    	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584) ~[na:na]
    	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496) ~[na:na]
    	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986) ~[na:na]
    	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[na:na]
    	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[na:na]
    	at java.lang.Thread.run(Thread.java:833) ~[na:na]
    	at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:597) ~[na:na]
    	at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:194) ~[na:na]
    
    opened by stijn-at-work 9
  • Crashes on DELETE call

    Crashes on DELETE call

    DELETE http://localhost:8080/api/v1/path/RetentionRules
    
    ^[[1m^[[31mStatus: 204  ^[[39m^[[21m^[[0m
    ^[[32mX-Frame-Options ^[[39m^[[0m: SAMEORIGIN
    ^[[32mReferrer-Policy ^[[39m^[[0m: strict-origin-when-cross-origin
    ^[[32mX-UA-Compatible ^[[39m^[[0m: IE=10; IE=11
    ^[[32mCache-Control ^[[39m^[[0m: no-cache
    ^[[32mX-Content-Type-Options ^[[39m^[[0m: nosniff
    ^[[32mContent-Security-Policy ^[[39m^[[0m: img-src data: blob: *; default-src blob: *; script-src 'unsafe-inline' 'unsafe-eval' data: *; style-src 'unsafe-inline' *; font-src data: *
    ^[[32mX-XSS-Protection ^[[39m^[[0m: 1; mode=block
    ^[[32mContent-Type ^[[39m^[[0m: application/json
    ^[[32mDate ^[[39m^[[0m: Thu, 25 Aug 2022 16:27:00 GMT
    
    ^[[2m2022-08-25 16:27:00.394^[[0;39m ^[[31mERROR^[[0;39m ^[[35m2272^[[0;39m ^[[2m---^[[0;39m ^[[2m[           main]^[[0;39m ^[[36morg.mvnsearch.http.HttpxCommand         ^[[0;39m ^[[2m:^[[0;39m HTX-002-500 - Failed to parse http code!
    
    java.lang.NullPointerException: null
            at java.util.Objects.requireNonNull(Objects.java:208) ~[na:na]
            at java.util.ImmutableCollections$List12.<init>(ImmutableCollections.java:556) ~[na:na]
            at java.util.List.of(List.java:812) ~[httpx:na]
            at org.mvnsearch.http.protocol.HttpBaseExecutor.request(HttpBaseExecutor.java:110) ~[httpx:0.35.1]
            at org.mvnsearch.http.protocol.HttpExecutor.execute(HttpExecutor.java:43) ~[httpx:0.35.1]
            at org.mvnsearch.http.HttpxCommand.execute(HttpxCommand.java:345) ~[httpx:0.35.1]
            at org.mvnsearch.http.HttpxCommand.call(HttpxCommand.java:215) ~[httpx:0.35.1]
    

    Response body is empty that why I guess. But should not fail. It is a legit case. Thank you one more time for excellent tool.

    opened by ssokolov1 7
  • JS tests do not run for every target

    JS tests do not run for every target

    Running httpx with -a with 4 targets, each having a JS test, it only indicates it is running for one or two of the middle 2.

    test file:

    ### ERROR 401: Exchange for Device token with bad secret
    POST {{baseUri}}/device/auth/test-ABC-123-XYZ-001
    Accept: application/json
    Content-Type: application/json
    
    {
      "registrationSecret": "secret-is-wrong"
    }
    
    > {%
        client.test("Bad attempt at token exchange", function() {
            client.log("test 1 log");
            client.assert(response.status === 401, "Response status is not 401");
        });
    %}
    
    ### ERROR 401: Exchange for Device token with bad device
    POST {{baseUri}}/device/auth/no-such-device
    Accept: application/json
    Content-Type: application/json
    
    {
      "registrationSecret": "secret-is-wrong"
    }
    
    > {%
        client.test("Bad attempt at token exchange", function() {
            client.log("test 2 log");
            client.assert(response.status === 401, "Response status is not 401");
        });
    %}
    
    ### Exchange secret for Device registration token
    POST {{baseUri}}/device/auth/test-ABC-123-XYZ-001
    Accept: application/json
    Content-Type: application/json
    
    {
      "registrationSecret": "secret-ABC-123-XYZ-001"
    }
    
    > {%
        client.test("Successful token exchange", function() {
            client.log("test 3 log");
            client.assert(response.status === 200, "Response status is not 200");
            client.assert(response.body.apiToken.length > 0, "Should have token");
            client.global.set("_deviceRegistrationToken", response.body.apiToken);
        });
    %}
    
    ### Error 403: Device check token should not succeed with a registration token, as it is the wrong type!
    GET {{baseUri}}/device/registered/test-ABC-123-XYZ-001
    Accept: application/json
    Authorization: Bearer {{_deviceRegistrationToken}}
    
    > {%
        client.test("Device should not validate a registration token token", function() {
            client.log("test 4 log");
            client.assert(response.status === 403, "Response status is not 403");
        });
    %}
    
    

    and output from httpx

    ❯ httpx -f src/test/http/devices-auth.http -a 
    =============1==================
    POST http://localhost:9090/device/auth/test-ABC-123-XYZ-001
    
    Status: 401 Unauthorized 
    Content-Type : application/json
    www-authenticate : Bearer
    content-length : 0
    
    
    =============2==================
    POST http://localhost:9090/device/auth/no-such-device
    
    Status: 401 Unauthorized 
    Content-Type : application/json
    www-authenticate : Bearer
    content-length : 0
    
    
    =============3==================
    POST http://localhost:9090/device/auth/test-ABC-123-XYZ-001
    
    Status: 200 OK 
    Content-Type : application/json;charset=UTF-8
    content-length : 789
    
    {
      "deviceId" : "test-ABC-123-XYZ-001",
      "apiToken" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2Rldi50YXRlYW0udGhlb3JlbW9uZS5jby9pc3N1ZXIiLCJ1cG4iOiJ0ZXN0LUFCQy0xMjMtWFlaLTAwMSIsInN1YiI6InRlc3QtQUJDLTEyMy1YWVotMDAxIiwiZXhwIjoxNjY1NDE5MTU2LCJncm91cHMiOlsiREVWSUNFX1JFRyIsIkFQSSJdLCJsZW1tYS50cyI6MTY2NTQxOTA5Njc0NywianRpIjoiYmZmOTc3YjctNzBjNi00ZTI2LWI1MzktNzM3YjViYTJkMGI3IiwiaWF0IjoxNjY1NDE5MDk2fQ.eBKI_mH7T7ULQ9Cgn6xuAck7HTI3eMd7SUC1xV08g8iznoOkosWSMNtX7qX4rFRFp3ixBhbwABrRgOLCSLJpDWHwLdwuL8vvdUcL4_mRAgNQiRV9fz2nh3f9Syzc877wJkawMllQFgOBWPp_hh4tTOB4kpTVeyCI2NXw6G7Gusq5lmhqr2Hao5OxPwF6BgIfecOZTpFz2iblu5UYcPrle1S_V6pEhqymmqAknD5C0GdKnWnlhwajF1LW3gWNjpoquuBkSdHwKoCbSOpzw6X8CYytoeZ21Li8D9R4cV4l5Zb9X6_zwn6RUhC-6vthiifEfYPw2IZBGUk7vCOGQl9dMw",
      "expiresAt" : 1665419156,
      "expiresIn" : 60
    }
    ============Execute JS Test============
    test 3 log
    
    
    =============4==================
    GET http://localhost:9090/device/registered/test-ABC-123-XYZ-001
    
    Status: 403 Forbidden 
    Content-Type : application/json
    content-length : 0
    
    opened by apatrida 4
  • Cannot simple test the response with client test

    Cannot simple test the response with client test

    ### hello ip
    GET https://httpbin.org/ip
    
    > {%
        client.test("Request executed successfully", function() {
            client.log(response.status);
            client.log(response.contentType);
            client.log(response.body);
        });
    %}
    
    httpx --version  
    0.23.0
    
    httpx
    GET https://httpbin.org/ip
    
    Status: 200 OK 
    Date : Fri, 08 Apr 2022 05:09:13 GMT
    Content-Type : application/json
    Connection : keep-alive
    Server : gunicorn/19.9.0
    Access-Control-Allow-Origin : *
    Access-Control-Allow-Credentials : true
    content-length : 31
    
    {
      "origin" : "00.177.64.37"
    }
    ============Execute JS Test============
    [stdin]:92
            let bodyText = decodeURIComponent(atob(base64Text))
                           ^
    
    ReferenceError: atob is not defined
        at HttpResponse.setBase64Body ([stdin]:92:24)
        at [stdin]:140:10
        at Script.runInThisContext (vm.js:134:12)
        at Object.runInThisContext (vm.js:311:38)
        at internal/process/execution.js:77:19
        at [stdin]-wrapper:6:22
        at evalScript (internal/process/execution.js:76:60)
        at internal/main/eval_stdin.js:29:5
        at Socket.<anonymous> (internal/process/execution.js:205:5)
        at Socket.emit (events.js:387:35)
    
    =========JavaScript Code===========
    class ContentType {
        mimeType = ""
        charset = "utf-8";
    
        constructor(mimeType) {
            this.mimeType = mimeType;
        }
    }
    
    class Variables {
        store = new Map();
    
        set(varName, varValue) {
            this.store.set(varName, varValue);
        }
    
    
        get(varName) {
            return this.store.get(varName)
        }
    
        isEmpty() {
            return this.store.size === 0
        }
    
    
        clear(varName) {
            this.store.delete(varName)
        }
    
        clearAll() {
            this.store.clear()
        }
    }
    
    class ResponseHeaders {
        store = new Map();
    
        valueOf(headerName) {
            return this.store.get(headerName)
        }
    
        valuesOf(headerName) {
            let value = this.store.get(headerName);
            if (value == null) {
                return []
            } else if (value && !Array.isArray(value)) {
                return [value];
            } else {
                return value;
            }
        }
    
        add(name, value) {
            this.store.set(name, value);
        }
    }
    
    class HttpResponse {
        /**
         * response body: object if application/json
         *
         * @type {string | object | LineStreamResponse}
         */
        body;
        headers = new ResponseHeaders();
        status = 200;
        /**
         *  content type
         * @type {ContentType}
         */
        contentType;
    
        constructor(status, contentType) {
            this.status = status;
            if (typeof contentType === "string") {
                let parts = contentType.split(";");
                this.contentType = new ContentType(parts[0]);
                if (parts.length > 1) {
                    this.contentType.charset = parts[1];
                }
            }
        }
    
        setHeaders(headers) {
            for (const [key, value] of Object.entries(variables)) {
                this.headers.add(key, value);
            }
        }
    
        setBase64Body(base64Text) {
            let bodyText = decodeURIComponent(atob(base64Text))
            if (this.contentType.mimeType.indexOf("json") >= 0) {
                this.body = JSON.parse(bodyText);
            } else {
                this.body = bodyText;
            }
        }
    
    }
    
    class HttpClient {
        global = new Variables();
    
        constructor(variables) {
            for (const [key, value] of Object.entries(variables)) {
                this.global.set(key, value)
            }
        }
    
        test(testName, func) {
            func();
        }
    
        log(message) {
            console.log(message);
        }
    
        assert(condition, message) {
            console.assert(condition, message);
        }
    
        exit() {
            process.exit(0)
        }
    }
    
    function encodeBody(plainText) {
        return btoa(encodeURIComponent(plainText));
    }
    
    const statusCode = 200;
    const contentType = 'application/json';
    const headers = {"content-length":"31","Server":"gunicorn/19.9.0","Access-Control-Allow-Origin":"*","Access-Control-Allow-Credentials":"true","Connection":"keep-alive","Date":"Fri, 08 Apr 2022 05:09:13 GMT","Content-Type":"application/json"};
    const variables = {id: 111};
    const client = new HttpClient(variables);
    const response = new HttpResponse(statusCode, contentType);
    response.setHeaders(headers);
    const base64Body = 'JTdCJTBBJTIwJTIwJTIyb3JpZ2luJTIyJTNBJTIwJTIyMTQuMTc3LjY0LjM3JTIyJTBBJTdEJTBB';
    response.setBase64Body(base64Body);
    
    /*
    client.test("Request executed successfully", function () {
        client.log(response.status)
        client.log(response.contentType)
        client.log(response.body)
    });
    */
    
        client.test("Request executed successfully", function() {
            client.log(response.status);
            client.log(response.contentType);
            client.log(response.body);
        });
    
    opened by nhahv 3
  • Support for Intellij Community Edition

    Support for Intellij Community Edition

    Hello @linux-china ,

    Came across this plugin, looks promising and great. However can this plugin be supported for IntelliJ community edition? looks like currently its only available in Ultimate edition.

    opened by anantagarwal 2
  • Please implement urlencode format parsing

    Please implement urlencode format parsing

    Please implement this feature

    https://youtrack.jetbrains.com/issue/IDEA-281753/Support-formatting-for-POST-request-body-for-application-x-www-f

    Will be much helpful

    opened by tixsys 1
  • Redis functions support

    Redis functions support

    https://redis.io/docs/manual/programmability/functions-intro/

    LOAD  localhost:6379
    Content-Type: text/x-lua
    
    #!lua name=mylib
    redis.register_function(
      'knockknock',
      function() return 'Who\'s there?' end
    )
    

    https://youtrack.jetbrains.com/issue/IDEA-293139

    opened by linux-china 1
  • suggest change project name to servicex

    suggest change project name to servicex

    1. There's already a popular tool named 'httpx' : https://github.com/encode/httpx
    2. stackoverflow tagged 'httpx' referrence to the Python one, will confuse some user searching for help.
    3. There's no popular project named 'servicex'
    4. This tool use for testing several kinds of service, not just for http, so...
    opened by jiacheo 1
  • Global variables not working

    Global variables not working

    I have this problem on debian (I tried it on windows but it didn't start); I am using the -a flag, which I expect to work like the "Run all" button in Idea.

    I use this pattern in my tests (this works in Idea): I first login, get a token, set it in client.global and use it for several later calls.

    Authorization: Bearer {{authToken}}

    I debugged the issue and it turns out that global it's not working. Calling this in the script, it prints "undefined":

    `client.global.set("authToken",response.body.access_token);

    client.log(client.global.get("authToken"));`

    Edit: I further investigated the problem and it is definitely in the JS part; it seems that the global_variables.json is written only at startup, using global.set never writes it. I am using debian on WSL2

    opened by riccardocossu 2
  • Problem to save files

    Problem to save files

    @ssokolov1 is running a command in testing directory where file test-api-retention.http is located and there is a subfolder resources

    httpx -f rest-api-retention.http -p docker -a

    ### Download random logo to use as attachment to the file
    GET {{logo}}
    
    >>! resources/logo.png
    

    2022-10-10 11:04:07.103 ERROR 29167 --- [ main] org.mvnsearch.http.HttpxCommand : HTX-002-500 - Failed to parse http code!

    java.nio.file.FileSystemException: rest-api-retention.http/resources/logo.png: Not a directory at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:218) ~[httpx:na]

    Here is the problem. It is trying to append script name to the current path, what is wrong in my opinion as rest-api-retention.http is a file, not a directory. IntelliJ internal runner handles it correctly. I can create a new issue if it helps. And one more time, thank you for your great work.

    opened by linux-china 1
  • Relative directory for file download/upload is using test name

    Relative directory for file download/upload is using test name

    NPE issue is fixed. Thank you very much !!! However, sorry to say, there is a new one. That is about destination of saved files. I am running a command in testing directory where file test-api-retention.http is located and there is a subfolder resources

    httpx -f rest-api-retention.http -p docker -a

    Download random logo to use as attachment to the file

    GET {{logo}}

    ! resources/logo.png 2022-10-10 11:04:07.103 ERROR 29167 --- [ main] org.mvnsearch.http.HttpxCommand : HTX-002-500 - Failed to parse http code!

    java.nio.file.FileSystemException: rest-api-retention.http/resources/logo.png: Not a directory at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:218) ~[httpx:na]

    Here is the problem. It is trying to append script name to the current path, what is wrong in my opinion as rest-api-retention.http is a file, not a directory. IntelliJ internal runner handles it correctly. I can create a new issue if it helps. And one more time, thank you for your great work.

    opened by ssokolov1 0
  • How to run all tests in the file. Test group file ?

    How to run all tests in the file. Test group file ?

    You have a very promising tool that can save a lot of time. Really happy to find it on JetBrains forum. Great work and let me share my feedback.

    I have around 20 HTTP scripts and planning to have xxx more. Each script has some GET/POST/DELETE requests and then some assertions. Is there a way to

    a) Run all actions in the http file sequentially until the end and report output in some type of log file (configurable location) - may be but default input_file_name.success if all good and input_file_name.fail if there are arrors.

    b) Create a group file that contains a list of http files to run. For example quick_test.http[ (inside a list of script files to run ) and full_regression.http(inside a list of tests to run). httpx -f quick_test.http -p=local -logfilepath=somepath

    If you need a help or accept donations for your work please publish a link. I would be happy to add a tip as your tool is a timesaver.

    opened by ssokolov1 2
  • The assertions are not being verified.

    The assertions are not being verified.

    I'm trying to use this tool to run tests outside of my IDE in CICD. So far the called are executed, but the problem I have is that non of my assertions are being tested at all.

    Bellow the simplest test for your HTTP example:

    ### get my ip
    //@name get-my-ip
    GET https://httpbin.org/ip
    
    > {%
        client.test("Request executed successfully", function() {
            client.log(response.status);
            client.log(response.contentType);
            client.log(response.body);
            client.log("Testing");
            client.assert(response.status == 400, "this should fail");
            client.assert(true, "this should not fail");
        });
    %}
    

    Expected result:

    Exactly as in IntelliJ, I would imagine the tool to fail/return non zero error code.

    opened by Marek00Malik 7
Releases(v0.38.0)
Owner
servicex-sh
CLI/Plugin to test difference services
servicex-sh
Kafka-spring-boot-starter: encapsulated based on spring-kafka

Encapsulation based on spring-kafka not only supports native configuration, but also adds multi data source configuration.

liudong 8 Jan 9, 2023
starter project for react native cli setups, typescript included

A starter project with react native 0.68, @storybook/react-native 6.0 beta, storybook/addon-react-native-web getting started To get all the dependenci

Danny 26 Dec 21, 2022
Sample Spring Boot CLI application

sb-cli Sample Spring Boot CLI application. Shows how a Spring Boot application may be configured and packaged to create native executables with GraalV

Andres Almiray 28 Nov 2, 2022
Drifty is an open-source interactive File Downloader system built with java. It is currently available in CLI mode and has the GUI version under active development.

Drifty Drifty is an open-source interactive File Downloader system built using Java. It takes the link to the file, the directory where it needs to be

Saptarshi Sarkar 60 Dec 24, 2022
Spring Boot starter module for gRPC framework.

Spring Boot starter module for gRPC framework.

Michael Zhang 2.8k Jan 4, 2023
Spring Boot starter module for gRPC framework.

Spring Boot starter module for gRPC framework.

Michael Zhang 1.8k Mar 17, 2021
A base repo for creating RPC microservices in Java with gRPC, jOOQ, and Maven.

Wenower Core OSX local installation Install Protocol Buffer $ brew install protobuf Install Postgresql and joopc database and user $ brew install pos

Hamidreza Soleimani 1 Jan 9, 2022
Auto-Unit-Test-Case-Generator automatically generates high-level code-coverage JUnit test suites for Java, widely used within the ANT Group.

中文README传送门 What is Auto-Unit-Test-Case-Generator Auto-Unit-Test-Case-Generator generates JUnit test suites for Java class just as its name. During te

TRaaS 108 Dec 22, 2022
【咕泡学院实战项目】-基于SpringBoot+Dubbo构建的电商平台-微服务架构、商城、电商、微服务、高并发、kafka、Elasticsearch

咕泡商城- 微服务架构实战 咕泡商城是咕泡学院 Java架构课程中,帮助学员对于技术更好落地的一个实战项目,项目基于springboot2.1.6.RELEASE+Dubbo2.7.3 来构建微服务。 业务模块划分,尽量贴合互联网公司的架构体系。所以,除了业务本身的复杂度不是很高之外,整体的架构基本

Mic 4.5k Dec 26, 2022
:herb: 基于springboot的快速学习示例,整合自己遇到的开源框架,如:rabbitmq(延迟队列)、Kafka、jpa、redies、oauth2、swagger、jsp、docker、spring-batch、异常处理、日志输出、多模块开发、多环境打包、缓存cache、爬虫、jwt、GraphQL、dubbo、zookeeper和Async等等:pushpin:

欢迎大家留言和PR~ Tip: 技术更新换代太快,本仓库仅做参考,自己的项目具体使用哪个版本还需谨慎思考~(不推荐使用最新的版本,推荐使用(最新-1|2)的版本,会比较稳定) spring-boot-quick 前言   自己很早就想搞一个总的仓库就是将自己平时遇到的和学习到的东西整合在一起,方便后

wangxc 2.1k Jan 2, 2023
🦄 开源社区系统:基于 SpringBoot + MyBatis + MySQL + Redis + Kafka + Elasticsearch + Spring Security + ... 并提供详细的开发文档和配套教程。包含帖子、评论、私信、系统通知、点赞、关注、搜索、用户设置、数据统计等模块。

Echo — 开源社区系统 项目上线到服务器之后可能会出现各种各样的 BUG,比如 Elasticsearch 服务启动失败导致搜索模块不可用,但是在本地运行是完全没问题的,所以各位小伙伴可以放心下载部署。 ?? 项目简介 Echo 是一套前后端不分离的开源社区系统,基于目前主流 Java Web

小牛肉 434 Jan 7, 2023
A Spring Boot Camel boilerplate that aims to consume events from Apache Kafka, process it and send to a PostgreSQL database.

SPRING-BOOT CAMEL BOILERPLATE This is a Spring-Boot Camel Application model that you can use as a reference to study or even to use in your company. I

Bruno Delgado 45 Apr 4, 2022
Spring Boot, Hibernate, JpaRepository, RESTful services & PostgreSQL.

HRMS-Project Human Resources Management System Back End application with Java, Spring Boot, Hibernate, JpaRepository, RESTful services & PostgreSQL. S

Hikmet Tutuncu 9 Aug 23, 2022
Simple and lightweight application which is checking status of your web services and send a notification if it is down.

rose-uptimer Simple and lightweight application which is checking status of your web services and send a notification if it is down. Example configura

RoseSapphire 3 Sep 25, 2022
log4j-scanner is a project derived from other members of the open-source community by CISA's Rapid Action Force team to help organizations identify potentially vulnerable web services affected by the log4j vulnerabilities.

Log4j Scanner This repository provides a scanning solution for the log4j Remote Code Execution vulnerabilities (CVE-2021-44228 & CVE-2021-45046). The

Cybersecurity and Infrastructure Security Agency 1.3k Dec 22, 2022
MediaBoutique - TP d'E-Services - ING 3 info

MediaBoutique - TP d'E-Services - ING 3 info Développement IDE: Intellij JDK: 11 1. Récupérer le projet Faire un clone de ce projet : git clone https:

Alexandre 2 Jan 13, 2022
A suite of software tools and services created to support activity planning and sequencing needs of missions with modeling, simulation, scheduling and validation capabilities

Aerie A suite of software tools and services created to support activity planning and sequencing needs of missions with modeling, simulation, scheduli

NASA Advanced Multi-Mission Operations System 31 Jan 3, 2023
Programming Services and Processes - 04 Secure Programming Techniques

Programación de Servicios y Procesos - 04 Técnicas de Programación Segura Tema 04. Técnicas de Programación segura. Curso 2021/2022. Contenidos Introd

José Luis González Sánchez 5 Dec 27, 2022
消息推送平台 - 所使用的技术栈包括:SpringBoot、SpringDataJPA、MySQL、Docker、docker-compose、Kafka、Redis、Apollo、prometheus、Grafana、GrayLog等等

项目介绍 austin项目核心功能:发送消息 项目出现意义:只要公司内有发送消息的需求,都应该要有类似austin的项目,对各类消息进行统一发送处理。这有利于对功能的收拢,以及提高业务需求开发的效率 系统项目架构 austin项目核心流程:austin-api接收到发送消息请求,直接将请求进MQ。a

Java3y 2.9k Dec 31, 2022