Giter Site home page Giter Site logo

anweber / httpyac Goto Github PK

View Code? Open in Web Editor NEW
267.0 4.0 29.0 5.54 MB

Command Line Interface for *.http and *.rest files. Connect with http, gRPC, WebSocket and MQTT

Home Page: https://httpyac.github.io/

License: MIT License

TypeScript 99.56% JavaScript 0.38% Shell 0.01% Dockerfile 0.05%
postman rest-client intellij http rest graphql grpc mqtt websocket

httpyac's Introduction

Hi there, I'm Andreas

const AnWeber = {
    work: "Software Architect/ Engineer",
    home: "Oberbatzi",
    code: ["Typescript", "Javascript", "Java", "C#", "CSS", "html"],
    askMeAbout: ["kids", "programming topics", "find a solution"],
    technologies: {
        backEnd: ["Spring Boot", "NodeJS", ".Net"],
        frontEnd: ["vue", "preact", "angular", "winforms", "wpf"],
        build: ["esbuild", "webpack", "gradle", "Github Actions", "Argo Workflows", "jenkins", "msbuild"],
        devOps: ["kubernetes", "elk stack", "argo-cd", "helm", "docker", "keycloak"],
        databases: ["oracle", "mssql", "mongo"],
        misc: ["VSCode Extensions", "bpmn"]
    },
    architecture: ["Microservices", "Serverless Architecture"],
    currentFocus: "Uniting software from two decades",
    hobbies: ["Hiking", "Gaming", "Lego"],
    funFact: "There are only 10 kinds of people in the world: the people who understand binary numbers and the people who don't."
};
console.info(AnWeber);

Current projects

Stats

AnWeber's GitHub stats

Top Langs

httpyac's People

Contributors

anweber avatar brammanuel avatar dependabot[bot] avatar fredrikhr avatar janahrens avatar kiranmayi446 avatar mondhs avatar nima-taheri-hs avatar rngtng avatar staff0rd avatar thzink avatar vojtech-pejsa-redbit avatar wooyey avatar yanghua-ola avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

httpyac's Issues

Ending a script block with a comment line errors out

Not a problem in real life scenarios but ending a script block with a comment terminates the script's execution with a fatal error.

Example

### Health check
{{BASE_URL}}/checks/health

{{
  console.log('I will be outputted')
  // I have a feeling this will not end well
}}
prompt$ httpyac --env prod --all ./requests/system/health-check.http 
js:   console.log('I will be outputted')
  // I have a feeling this will not end well
                                                                  

SyntaxError: Unexpected end of input
    at new Script (vm.js:101:7)
    at createScript (vm.js:262:10)
    at Object.runInThisContext (vm.js:310:10)
    at /Users/me/.nvm/versions/node/v14.15.5/lib/node_modules/httpyac/dist/index.js:1:37428
    at Generator.next (<anonymous>)
    at /Users/me/.nvm/versions/node/v14.15.5/lib/node_modules/httpyac/dist/index.js:1:36507
    at new Promise (<anonymous>)
    at s (/Users/me/.nvm/versions/node/v14.15.5/lib/node_modules/httpyac/dist/index.js:1:36252)
    at g (/Users/me/.nvm/versions/node/v14.15.5/lib/node_modules/httpyac/dist/index.js:1:36786)
    at t.JavascriptAction.<anonymous> (/Users/me/.nvm/versions/node/v14.15.5/lib/node_modules/httpyac/dist/index.js:1:38658)

Turn off verification of self-signed certificate

During development on localhost, the dev certificate is self-signed.
Getting this error

ERROR: RequestError - self signed certificate
RequestError: self signed certificate

Is there a way to turn that off in some config or per call?

Version 4.4.1 breaks ability to store GraphQL result

### Login

# @name login
POST {{gqlUrl}}
Content-Type: application/json

query ($input: DoTheLogin) {
  doTheLogin(input: $input)
}

{
  "input": {
    "username": "{{username}}",
    "password": "{{password}}"
  }
}

### Do Something
POST {{gqlUrl}}
Content-Type: application/json
Authorization: Bearer {{login.data.generateAPIKeyFromCredentials.apiKey}}

mutation ($input: DoSomethingInput) {
  doSomething(input: $input)
}

{
  "input": {
    "customerCode": "{{customerCode}}"
  }
}

Invoking DoSomething says login is not defined.

Allow @import to import global variables

There is a small error in importing global variables from other http files. If variables are imported with import and ref, it is working fine. If only import is used nothing gets imported, except a request was already executed from other file.

OAuth2 Implicit flow

It seems that the implicit flow isn't implemented. Do you have any plans to add that as well? That just became a blocker for our pm migration.

Feature: Configure callback

I'd like to attempt to make the hardcoded callback url (http://localhost:3000) for openid implicit to be configurable. Is this a feature you'd be interested in merging were I to open a PR?

At the very least, I'd expect to be able to use something like --callback http://localhost:8653/whatever/path or similar via CLI option and the http server to respect this.

Generating *.http files

This is less a request for this repo and more just asking whether you have pondered generating *.http files.

I have a number of GraphQL apis that I am looking to test out further with httpyac. While the likes of Insomnia/Postman use introspection to hit a GraphQL endpoint, I was thinking I could write a plugin for graphql code generator that during generation also generates httpyac *.http files.

Do you have any thoughts on this or similar?

Import file scoped to current request instead of file

Andreas, thanks for the latest bug fixes / improvements... and for the really nice updated documentation! 🙇‍♂️👍

That being said.. I ran into an issue when doing this:

# @import ./external.http

### Some request
# @ref requestName
# ...

It doesn't know about requestName here.

It works fine when I switch to:

### Some request
# @import ./external.http
# @ref requestName
# ...

The manual says:

To reference Requests from other files, these must first be imported. Imported files are enabled for all requests in one file.

But the example uses only one request with no ### delimiter. It looks like imports are scoped to only one request when ### delimiters are used.

Glob pattern in CLI is not working as expected

I'm running: httpyac --all --output short my-test/**/*.test.http

With the following files, all works as expected:

  • my-test/a.test.http
  • my-test/b.test.http
  • my-test/my-folder/c.skip.http
httpyac --all --output short my-test/**/*.test.http
--------------------- my-test/a.test.http  --

---------------------

=== Login from a.test.http ===

POST http://localhost:60000/graphql
=> 200 (183 ms, 541 B)
--------------------- my-test/b.test.http  --

---------------------

=== Login from b.test.http ===

POST http://localhost:60000/graphql
=> 200 (175 ms, 541 B)

2 requests tested (2 succeeded, 0 failed)

With the following files, only c.test.http runs.

  • my-test/a.test.http
  • my-test/b.test.http
  • my-test/my-folder/c.test.http
httpyac --all --output short my-test/**/*.test.http

---------------------

=== Login from c.test.http ===

POST http://localhost:60000/graphql
=> 200 (287 ms, 541 B)

There's some logic issue somewhere when handling the glob pattern

upload file with multipart/form-data does not work

I followed this example: https://github.com/AnWeber/httpyac/tree/main/examples#multipartform-data to make a file upload request.
request.http:

### upload file
POST http://127.0.0.1:9167/testing/v2/uploadExcel HTTP/1.1
Content-Type: multipart/form-data; boundary=--WebKitFormBoundary

--WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="2.xlsx"
Content-Type: application/xlsx

< ./2.xlsx
--WebKitFormBoundary

but got the following output:

=== upload file ===
POST http://127.0.0.1:9167/base-billing-manager/v2/receipt/uploadExcel
accept: */*
accept-encoding: gzip, deflate, br
content-length: 20458
content-type: multipart/form-data; boundary=--WebKitFormBoundary
user-agent: httpyac

HTTP/1.1 200 OK
access-control-allow-credentials: true
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, Cookie
access-control-allow-methods: GET, POST, PUT, DELETE, OPTIONS
access-control-allow-origin: *
access-control-max-age: 3600
connection: close
content-type: application/json;charset=UTF-8
date: Wed, 21 Jul 2021 07:21:42 GMT
transfer-encoding: chunked
x-application-context: application:9167

{
  "code": 10000001,
  "message": "Required request part 'file' is not present",
  "data": null
}

It seems the body part is missing in this request, could you help me find out if I've missed something in this request?

Code generation fails if there are query parameters

When I choose Generate code for a request containing a query parameter it fails with this error:
HARError: validation failed

It doesn't matter what is the target platform generate it for
Example

GET http://abc.com/a?b=c

ERROR: http://abc.com/a?b=c
{
"url": "http://abc.com/a?b=c",
"method": "GET",
"http2": true,
"headers": {
"User-Agent": "httpyac"
},
"cookieJar": {
"version": "[email protected]",
"storeType": "c",
"rejectPublicSuffixes": true,
"cookies": []
},
"followRedirect": true
}
ERROR: HARError - validation failed
HARError: validation failed

Variable substitution bug

POST https://httpbin.org/anything HTTP/1.1
{
  "template": "My \{\{someVerb\}\} template!!"
}

results in:

ERROR: ReplaceVariableHook: javascript failed
ERROR: BeforeRequestHook: requestVariableReplacer failed
ERROR: https://httpbin.org/anything
{
  "url": "https://httpbin.org/anything",
  "method": "POST",
  "http2": false,
  "headers": {},
  "body": "{\n  \"template\": \"My \\{\\{someVerb\\}\\} template!!\"\n}",
  "cookieJar": {
    "version": "[email protected]",
    "storeType": "D_",
    "rejectPublicSuffixes": true,
    "cookies": []
  }
}
ReferenceError - someVerb is not defined
ReferenceError: someVerb is not defined
	at Object.<anonymous> (/home/dwayne/github/mesh-server/test/http/intel/test.http:7:20)
	at TE (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:91651)
	at Hc (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:92017)
	at Object.Rde [as action] (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:106:43256)
	at yle.trigger (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:76730)
	at async wu (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:100312)
	at async wgt (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:128074)
	at async Object.Mpe [as action] (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:127972)
	at async wE.trigger (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:76713)
	at async Xd (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:88250)
ERROR: ExecuteHook: httpClient failed
ERROR: ReferenceError - someVerb is not defined
ReferenceError: someVerb is not defined
	at Object.<anonymous> (/home/dwayne/github/mesh-server/test/http/intel/test.http:7:20)
	at TE (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:91651)
	at Hc (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:92017)
	at Object.Rde [as action] (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:106:43256)
	at yle.trigger (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:76730)
	at async wu (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:100312)
	at async wgt (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:128074)
	at async Object.Mpe [as action] (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:127972)
	at async wE.trigger (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:76713)
	at async Xd (/home/dwayne/.vscode-server/extensions/anweber.vscode-httpyac-4.5.0/dist/extension.js:105:88250)

Problem with global auth token in IntelliJ context

Hi,

The IntelliJ HTTP Client plugin keeps client.global env parameters between runs. httpyac doesn't it seems?

We have a setup in our structure where we have a login job setup:

### User Login
POST {{auth0_base_url}}/oauth/token
Content-Type: application/json

{
 "client_id": "{{user_auth_client_id}}",
 "client_secret": "{{user_auth_client_secret}}",
 "grant_type": "http://someauth.com/realm",
 "username": "{{user_auth_username}}",
 "password": "{{user_auth_password}}",
 "audience": "an/audience",
 "realm": "Username-Password-Authentication",
 "scope": "openid"
}
> ./login.js

with a script like this:

client.test('Token retrieved successfully', function () {
  client.assert(response.status === 200, 'Response status is not 200')
  var access = response.body.access_token
  if (access) {
    client.global.set('user_access_token', access)
  }
})

This user_access_token is stored globally in the IntelliJ plugin in a way where this env parameter is available to requests that are executed later.

So, If I run:

### List companies
GET {{my_base_url}}/api/companies
Authorization: Bearer {{user_access_token}}

it will work just fine. But If I do this in httpyac, I get the error:

...ReferenceError: user_access_token is not defined at Object.userJS...

So, my questions are:

  • Is this intended behaviour?
  • Do you have a suggestions on how I could solve this scenario for httpyac, without breaking this logic within IntelliJ?

redirect_uri in the authentication flow

The OpenID Authentication Flow requires that the client set the request parameter redirect_uri when sending an authentication request to the authorization end point.

Which variable can be used to set the redirect_uri in the basic flow?


current configuration for an integration environment:
int_authorizationEndpoint=https://oauth-server-int/as/authorization.oauth2
int_tokenEndpoint=https://oauth-server-int/as/token.oauth2
int_clientId=...
int_clientSecret=...
int_scope=openid profile email
int_responseType=code

GET /secure-end-point
Authorization: openid authorization_code int

Multiple @ref

The documentation could be enriched:

You can reference as many requests as you want

# @name keycloak
POST {{host}}/auth

# @name getId
GET {{host}}/getid

###
GET {{host}}/tasks/{{getId.id}}
# @ref keycloak
# @ref getid
Authorization: Bearer {{keycloak.access_token}}

the command donot work, only replied help information.

Thanks for the httpyac, the script funciont is amazing, but the command sounds donot work.
it just replied the help info, no error, I cannot catch any info.
`PS C:\hlp\02src\mygo\huaxrobot> httpyac .\tests\apitest\backapi.http --all
send http requests of .http or .rest

usage: httpyac [options...]
--all execute all http requests in a http file
--editor enter a new request and execute it
-e --env list of environemnts
--filter filter requests output (only-failed)
-h --help help
--insecure allow insecure server connections when using ssl
-i --interactive do not exit the program after request, go back to selection
--json use json output
-l --line line of the http requests
-n --name name of the http requests
--no-color disable color support
-o --output output format of response (short, body, headers, response, exchange, none)
--output-failed output format of failed response (short, body, headers, response, exchange, none)
--raw prevent formatting of response body
-r --repeat repeat count for requests
--repeat-mode repeat mode: sequential, parallel (default)
-s --silent log only request
--timeout maximum time allowed for connections
-v --verbose make the operation more talkative
--version version of httpyac
PS C:\hlp\02src\mygo\huaxrobot> `

Repeat mode with diff variables

Is it possible to run the script in repeat mode with diff parameters every time? I'm thinking to use the script for automated functional testing. I wan to see if there is a way to specify diff params in array of something and array[0] params are the ones to use for 1st iteration, array[1] params are the ones to use for 2nd iteration etc. or anything similar..

Test framework

Are you open to the inclusion of an automated test framework?

I'd like to contribute to the project but find it difficult to do without an automated way to prove bug fixes and test features.

httpyac CLI should return non-zero exit status

When calling a non-existent endpoint, the httpyac-cli client crashed with due to: RequestError: connect ECONNREFUSED 127.0.0.1:60001. The exit code was still 0. If it crashes it should be non-zero exist code since 0 means "success". We are integrating the httpyac cli into a build and it is important that the it return an error code (i.e. anything non-zero).

Enable env variable placeholder replacement when including file in request

It would be great if env variable placeholders would also be replaced in included files.

// My Env File
{
  "dev": {
    "foo": "bar"
  }
}
// My payload "payload.json" as a separate file
{
  "foo": "{{foo}}"
}
POST my.host.com
Content-Type: application/json

< ./payload.json

Currently, when sending the request, it would send the exact payload and not replace the {{foo}} placeholder.

CLI env not detected

I have the following structure:

-- env
  |_ .env
  |_ prod.env               (API_URL=https://some.thing)
-- requests
  |_ something.http         (uses {{API_URL}})
-- package.json             (just script definitions)

When I run:

httpyac --env prod --all ./requests

I get:

ReplaceVariableHook: javascript failed
ExecuteHook: variableReplacer failed
ReferenceError: API_URL is not defined
    at Object.<anonymous> (requests/something.http:6:20)
    at Object.<anonymous> (~/.nvm/versions/node/v16.5.0/lib/node_modules/httpyac/dist/index.js:1:141494)
    at Generator.next (<anonymous>)
    at ~/.nvm/versions/node/v16.5.0/lib/node_modules/httpyac/dist/index.js:1:139999
    at new Promise (<anonymous>)
    at r (~/.nvm/versions/node/v16.5.0/lib/node_modules/httpyac/dist/index.js:1:139744)
    at Object.t.runScript ~/.nvm/versions/node/v16.5.0/lib/node_modules/httpyac/dist/index.js:1:141083)
    at Object.<anonymous> (~/.nvm/versions/node/v16.5.0/lib/node_modules/httpyac/dist/index.js:1:165669)
    at Generator.next (<anonymous>)
    at ~/.nvm/versions/node/v16.5.0/lib/node_modules/httpyac/dist/index.js:1:165188

It used to work before as far as I remember. And the environment is still correctly picked up by the vscode extension (and everything runs fine there). It's just the CLI which no longer works.

I'm using httpyac v3.1.0 (unfortunately I don't remember what version it used to work on but I'm pretty sure I haven't changed my directory structure since it last worked). 🤔

The CLI in version 4.7.1 is broken

Running httpyac CLI (e.g. httpyac --help) always results in:

SyntaxError: Unexpected token '?'
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/home/dwayne/.nvm/versions/node/v12.22.6/lib/node_modules/httpyac/bin/httpyac.js:3:17)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)

This issue is not seen in version 4.7.0.

Support the special character '.' in header names

Background

HTTP header field names can contain the character . according to this RFC and the definition of a token within.
However, httpyac fails to properly parse an .http file with such a header name.

Although commonly used header names have dashes, certain web services can require custom header names.
httpyac should fully support the RFC, especially for proper interoperability with the IntelliJ REST Client plugin.

Example http File

GET https://google.com
header.name: xyz

Executing httpyac with such a file, the following error report can be observed:

ExecuteHook: httpClient failed
RequestError: The `GET` method cannot be used with a body
    at Request._destroy (D:\projects\sandboxes\httpyac-test\node_modules\got\dist\source\core\index.js:1378:21)
    at _destroy (node:internal/streams/destroy:102:25)
    at Request.destroy (node:internal/streams/destroy:64:5)
    at D:\projects\sandboxes\httpyac-test\node_modules\got\dist\source\core\index.js:354:26
    at Request._finalizeBody (D:\projects\sandboxes\httpyac-test\node_modules\got\dist\source\core\index.js:716:23)
    at D:\projects\sandboxes\httpyac-test\node_modules\got\dist\source\core\index.js:333:28
    at new Request (D:\projects\sandboxes\httpyac-test\node_modules\got\dist\source\core\index.js:357:11)
    at makeRequest (D:\projects\sandboxes\httpyac-test\node_modules\got\dist\source\as-promise\index.js:35:29)
    at D:\projects\sandboxes\httpyac-test\node_modules\got\dist\source\as-promise\index.js:147:9
    at D:\projects\sandboxes\httpyac-test\node_modules\p-cancelable\index.js:63:11
    at new Promise (<anonymous>)
    at new PCancelable (D:\projects\sandboxes\httpyac-test\node_modules\p-cancelable\index.js:31:19)
    at Object.asPromise [as default] (D:\projects\sandboxes\httpyac-test\node_modules\got\dist\source\as-promise\index.js:33:21)
    at getPromiseOrStream (D:\projects\sandboxes\httpyac-test\node_modules\got\dist\source\create.js:43:121) {
  code: 'ERR_GOT_REQUEST_ERROR',
  timings: undefined
}

as the parsing of the file breaks and header.name: xyz is now considered as the request body.

Version 2.15 causes GraphQL queries to fail.

###

# @name login
POST {{gqlUrl}}
Content-Type: application/json

query ($input: GenerateAPIKeyFromCredentialsInput) {
  generateAPIKeyFromCredentials(input: $input)
}

{
  "input": {
    "username": "my_user",
    "password": "my_password"
  }
}

This works in version 2.14.1. In 2.15 it results in this:

POST http://my_server/graphql
accept: */*
accept-encoding: gzip, deflate, br
content-length: 69
content-type: application/json
user-agent: httpyac

{
  "input": {
    "username": "admin",
    "password": "admin"
  }
}

HTTP/1.1 400 Bad Request
access-control-allow-credentials: true
connection: close
content-length: 26
content-type: text/html; charset=utf-8
date: Thu, 17 Jun 2021 05:00:02 GMT
etag: W/"1a-g3vOqhX4m1ggfybuQPoSyy5JUsg"
strict-transport-security: max-age=15552000; includeSubDomains
vary: Origin, Accept-Encoding
x-content-type-options: nosniff
x-dns-prefetch-control: off
x-download-options: noopen
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block

Must provide query string.

Unable to access exported variables from imported http file

I'm trying to access variables exported from the imported file, without success.

Sample

singup.http

POST /signup HTTP/1.1
...headers

{
  "var1": "var_value"
}

{{
exports.varFromSignup = "testValue"
}}

init.http

# @import ./signup.http

###
{{
  console.info(varFromSignup) // This line throws error
}}
GET /users/me HTTP/1.1
...headers

console statement throws error.

Is this expected behaviour? If so, is there a way I can access exported variables in another file?

Thank you

Variables shared across files

I wonder if there is something that supports a flow like the following:

FILE A

POST /endpoint/auth

{ "user": "user", "password": "password" }


{{
	// post-request
	httpyac.globals.set('token', response.parsedBody.token);
}}

FILE B

{{
	// pre-request
	exports.token = httpyac.globals.get('token');
}}

POST /endpoint/action-1
Authorization: Bearer {{token}}

{ "hello": "world" }

I tried using httpFile.variablesPerEnv but this collection only stores the variables for the current file, not for the whole environment.
Keep up the good work, thanks!

cli doesn't respect dotenv in same location as *.http file

Docs suggest that:

The .env files are searched from the following locations:

  • same location as *.http file

For the following files:

# spacex.http
GET {{HOST}}/launches/latest HTTP/1.1

# dev.env
HOST=https://api.spacexdata.com/v4

If I place these in the root of a git repo, then the following command works:

httpyac spacex.http --all -e dev

However, I move the files to a child of the root, for example, <repo>/test, running the command above from the test folder throws:

ReplaceVariableHook: javascript failed
BeforeRequestHook: requestVariableReplacer failed
{{HOST}}/launches/latest {
  url: '{{HOST}}/launches/latest',
  method: 'GET',
  http2: false,
  headers: {},
  cookieJar: CookieJar {
    rejectPublicSuffixes: true,
    enableLooseMode: false,
    allowSpecialUseDomain: false,
    store: { idx: {} },
    prefixSecurity: 'silent',
    _cloneSync: [Function (anonymous)],
    _importCookiesSync: [Function (anonymous)],
    getCookiesSync: [Function (anonymous)],
    getCookieStringSync: [Function (anonymous)],
    getSetCookieStringsSync: [Function (anonymous)],
    removeAllCookiesSync: [Function (anonymous)],
    setCookieSync: [Function (anonymous)],
    serializeSync: [Function (anonymous)]
  },
  proxy: undefined
} ReferenceError: HOST is not defined
    at Object.<anonymous> (spacex.http:3:20)
    at Me (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:18161)
    at z (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:18526)
    at Object.jo [as action] (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:2:43344)
    at wt.trigger (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:3409)
    at async me (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:27307)
    at async Object.Qr [as action] (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:55373)
    at async be.trigger (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:3392)
    at async ie (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:14816)
    at async $e.trigger (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:3392)
ExecuteHook: httpClient failed
ReferenceError: HOST is not defined
    at Object.<anonymous> (spacex.http:3:20)
    at Me (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:18161)
    at z (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:18526)
    at Object.jo [as action] (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:2:43344)
    at wt.trigger (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:3409)
    at async me (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:27307)
    at async Object.Qr [as action] (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:55373)
    at async be.trigger (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:3392)
    at async ie (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:14816)
    at async $e.trigger (/home/stafford/.nvm/versions/node/v14.17.0/lib/node_modules/httpyac/dist/index.js:1:3392)

I think it's because this code is passing context.httpFile.rootDir, but I don't understand the relevance of rootDir at that position.

I also note that the vscode extension does not have this issue. The environment is selectable even under /test and the send suceeds.

Need help with disabling a request based on condition in @ref chain

Hi,

I've a requirement where one request refers to multiple other requests out of which some of them should be disabled based on dynamic condition. I've tried with httpRegion.metaData.disabled but main request region throws below error

ERROR: ExecuteHook: ref failed
ERROR: RangeError - Maximum call stack size exceeded
RangeError: Maximum call stack size exceeded
    at Array.values (<anonymous>)

If I remove @disabled it works, but I can't disable request that should be disabled.

sample

{{
  httpRegion.metaData.disabled = !createAccount
}}

# @name signup
@email = {{$input Enter Email $value:}}
@password = {{$input Enter Password $value: Vizmo123}}
@firstName = {{faker.name.firstName()}}
@lastName = {{faker.name.lastName()}}
POST /functions/user:signup HTTP/1.1
...defaultHeaders

{
  "firstName": "{{firstName}}",
  "lastName": "{{lastName}}",
  "email": "{{email}}",
  "phone": "{{faker.phone.phoneNumber(`9#########`)}}",
  "password": "{{password}}",
  "company": "{{faker.company.companyName()}}"
}

###

{{
  httpRegion.metaData.disabled = createAccount || account.sessionToken
}}

# @name login
POST /login HTTP/1.1
...defaultHeaders

{
  "username": "{{account.email}}",
  "password": "{{account.password}}",
}

###

# @ref signup
# @ref login
# @name user
GET  classes/_User/me HTTP/1.1
...headersWithSession

Here I would like to disable either signup or login conditionally

Any help would be appreciated.
Thank you

Variable replacer does not take dotenv variables into account

GET {{Url}}

The line above errors when Url is a dotenv variable. I added a breakpoint to the javascriptVariableReplacer function and inspected the context parameter. Sure enough, config-file variables were present in context.variables, but dotenv variables were not.

export async function javascriptVariableReplacer(text: unknown, type: VariableType | string, context: ProcessorContext): Promise<unknown> {
if (!utils.isString(text)) {
return text;
}
let match: RegExpExecArray | null;
let start;
let result = text;
while (start !== result) {
start = result;
while ((match = ParserRegex.javascript.scriptSingleLine.exec(start)) !== null) {
const [searchValue, jsVariable] = match;
try {
const value = await utils.evalExpression(jsVariable, context);
if (utils.isString(value) || typeof value === 'number') {
result = result.replace(searchValue, `${value}`);
} else if (value instanceof Date) {
result = result.replace(searchValue, `${value.toISOString()}`);
} else if (value) {
result = result.replace(searchValue, `${value}`);
}
} catch (err) {
if (type === VariableType.variable) {
log.trace(`variable ${jsVariable} not defined`);
} else {
throw err;
}
}
}
}
return result;
}

[Feature Request] Support OAuth2 Device code authorisation flow

I would like httpyac to support the OAuth 2.0 Device authorization grant for the openid variable replacer.

Ref. RFC8628
Example of usage: Microsoft Identity platform

Proposal for httpyac:

GET https://graph.microsoft.com/v1.0/me
Authorization: openid device_code msidp

Reason:

This is a great way of authenticating using applications where you cannot/don't want to modify the redirect Url, and don't have access to/don't want to leak the client secret. And contrary to the implicit and hybrid authorization flows, the device code flow hasn't been deprecated by the OAuth standard and best practices.

Promise statements in script blocks

Hi,

Could you please help me figure out how to resolve promise statements in script blocks?

I would like to open QuickPick directly using vscode api which is an async operation.

Here is the sample code

  const account = getAccount(accountsData)

  exports.account = account;

  exports.signup = !!account
		? { sessionToken: acc.sessionToken }
		: null

getAccount is an async function which calls vscode.window.showQuickPick.

Response body formatting is not working

The JSON response body in response view is not formatted (indented). It seems that fairly short responses are being formatted. But anything trivially longer (eg 50 lines of JSON) remains in a single line.

The response body formatting used to work for even very long responses until today.

Maybe this commit? cd4ca00

BTW httpyac is one of my favourite VS Code extensions :) Awesome work!

Enhance formatting

I see some eslint coverage on the project but ponder whether you'd be open to something with wider coverage, for example prettier or standardjs.

I'd also like to propose save on format either in place of, or in addition to the pre-commit hook. eslint, prettier and standardjs all have options to enable format on save in vscode and help contributors know while inside the IDE that they don't need to worry about formatting.

OAuth2 token handling

I'm currently researching an alternative for PostMan. Your extension is very impressive. We use PostMan mostly with endpoints using OAuth2 code flow to provide tokens. So I currently try to understand if there is already any way to request arbitrary OAuth2 tokens with httpyac.

I just discovered openIdVariableReplacer.ts and I'm wondering how to use it? Are you planning to add some kind of OAuth2 token handling and/or are you open to PR in that area?

.httpyac.json file not overriding hard coded defaults

What was I trying to do
I want to turn off console ansi colouring in the output

What did I try
I added a file called .httpyac.json and set the commandline --root parameter to the folder the file was in.
My .httpyac.json file contains:

{
    "log":{
        "supportAnsiColors":false
    }
}

What did I expect to happen
I expected the console output to not contain Colour Code characters.
Rather than this

�[33maccept-encoding�[0m: gzip, deflate, br

I expected
accept-encoding: gzip, deflate, br

What happened
The output still contained the colour code information
�[33maccept-encoding�[0m: gzip, deflate, br

Offer of help
I'm happy to make change and submit a PR, it may be overkill as it seems to be a one line change
https://github.com/AnWeber/httpyac/blob/main/src/environments/environmentStore.ts#L108

const environmentConfig: EnvironmentConfig = merge({}, ...(await this.loadFileEnvironemntConfigs(rootDirs)), config);
should be
const environmentConfig: EnvironmentConfig = merge({}, config, ...(await this.loadFileEnvironemntConfigs(rootDirs)));
to allow the .httpyac.config to overwrite the default configuration.

OMG! Thank you! Httpyac rocks!

Hey @AnWeber. This is not a real issue, but a BIG THANK YOU. You created what I always was dreaming of. I see so many developers being 'locked in' with postman and waste time with point&click or, the other extreme, writing crazy bash/curl/* scripts which are tedious to maintain & understand. Not speaking of version control, open standards etc...

With httpyac I think you hit the right trade-of for being developer focused but with a sane Framework & UX so minimise any overhead - by full scripting flexibility - this encourages automating 'manual' testing at it's best.

Throughout the day I read the guide and ran already a couple of tests for my scenarios. I'm amazed! I found some minor things here and there, will open dedicated issues for that. THANKS again - Tobi

[gRPC] Error: The includeDirs option must be an array

When I try to use the includeDirs option of @grpc/proto-loader I get the following error:

ERROR: ExecuteHook: protoImport failed
ERROR: Error - The includeDirs option must be an array
Error: The includeDirs option must be an array
	at Object.IZe [as loadProtosWithOptions] (/Users/user.name/.vscode/extensions/anweber.vscode-httpyac-4.0.3/dist/extension.js:84:29203)
	at KZe (/Users/user.name/.vscode/extensions/anweber.vscode-httpyac-4.0.3/dist/extension.js:84:31987)
	at Eae.process (/Users/user.name/.vscode/extensions/anweber.vscode-httpyac-4.0.3/dist/extension.js:90:126676)
	at runMicrotasks (<anonymous>)
	at processTicksAndRejections (internal/process/task_queues.js:93:5)
	at async Iq.trigger (/Users/user.name/.vscode/extensions/anweber.vscode-httpyac-4.0.3/dist/extension.js:90:76164)
	at async Vp (/Users/user.name/.vscode/extensions/anweber.vscode-httpyac-4.0.3/dist/extension.js:90:93948)
	at async Lw (/Users/user.name/.vscode/extensions/anweber.vscode-httpyac-4.0.3/dist/extension.js:90:94554)
	at async zst (/Users/user.name/.vscode/extensions/anweber.vscode-httpyac-4.0.3/dist/extension.js:90:101698)
	at async Object.iP (/Users/user.name/.vscode/extensions/anweber.vscode-httpyac-4.0.3/dist/extension.js:90:101567)

This is an example of what I'm using:

proto < /Users/user.name/go/my-service/my-service.proto
enums: String,
includeDirs: [ "../../proto/third_party/googleapis" ],

###

GRPC http://localhost:9090/myservice.MyService/GetUser
{
  "userId": "123456",
}

Is it something wrong with my .http file?

GRPC Authorization header

Hello,

Thank you againg for your great work =)!

But I have one more problem =). When using GRPC - header "Authorization" just disapearing. Can be tested with:

proto < ./grpcbin.proto
GRPC grpcb.in:9000/grpcbin.GRPCBin/HeadersUnary
Authorization: Bearer 111

grpcb.in just returns response without our header. And doesn't matter if it is "Bearer" or anything else. Also want to mention that openid/oauth2 will not work here coz token also received using GRPC not via HTTP =). So i need manually to provide header.

Using event also gives nothing:

{{@request
 request.headers.Authorization = 'Bearer XXX';
}}

Using simple HTTP get, for example:

@host=https://httpbin.org
###
GET /anything?q=1 HTTP/1.1
Authorization: Bearer 1111

Works well.
Version of vscode plugin: v4.7.2

GraphQL queries without variables fail to execute

Repro

For this file:

POST https://api.spacex.land/graphql
Content-Type: application/json

query company_query {
  company {
    coo
  }
}

run httpyac test.http --all

Expected

{
  "data": {
    "company": {
      "coo": "Gwynne Shotwell"
    }
  }
}

Actual

POST https://api.spacex.land/graphql
accept: */*
accept-encoding: gzip, deflate, br
content-length: 47
content-type: application/json
user-agent: httpyac

query company_query {
  company {
    coo
  }
}

HTTP/1.1 400  - Bad Request
access-control-allow-origin: *
connection: close
content-length: 138
content-security-policy: default-src 'none'
content-type: text/html; charset=utf-8
date: Mon, 22 Nov 2021 13:38:10 GMT
server: Cowboy
via: 1.1 vegur
x-content-type-options: nosniff
x-powered-by: Express

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Bad Request</pre>
</body>
</html>

Summary mode

Thanks again for the excellent work. Here's a suggestion to hopefully make the CLI more versatile.

Goals

  1. focus on only high level info
  2. efficiently go through many requests
  3. use in continuous monitoring and trigger alarms

Proposal

There is a helpful --verbose mode, but there doesn't seem to be a way to make httpyac more concise.

For just one request being tested in the normal mode, with a tiny body response:

https://the.server.dev/checks/health => 200
GET https://the.server.dev/checks/health
accept: */*
accept-encoding: gzip, deflate, br
user-agent: httpyac

HTTP/1.1 200 OK
alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400, h3=":443"; ma=86400
cf-ray: 66b9e0e55d873469-NRT
connection: close
content-length: 15
content-type: application/json
date: Thu, 08 Jul 2021 14:07:22 GMT
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
nel: {"report_to":"cf-nel","max_age":604800}
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v2?s=u2dylFQnhzyetY8zUENOcv4l0%2FvmxRW8%2FmAKXfC0Kyna8uVZddEaWx6oSfQBJfM%2FwDfKchWeiwRdwhXSP7VykaQnTuM0mNTl0HCkd4%2BWhjtUB%2FcmtTroVQnfMEe%2Bs%2F8dw8Lh"}],"group":"cf-nel","max_age":604800}
server: cloudflare
vary: Accept-Encoding

{
  "status": "OK"
}
Tests for /checks/health
✓ Request succeeded
✖ Schema is valid (AssertionError [ERR_ASSERTION]: Response schema is incorrect: does not exactly match expected constant: ok - t.IntellijHttpClient.assert (/Users/name/.nvm/versions/node/v14.15.5/lib/node_modules/httpyac/dist/index.js:1:32228)

This is very helpful a lot of the time, but it is a bit difficult to use when running large collections of tests, or tests with large bodies, or if trying to use it in a continuous monitoring situation.

We could imagine something like this as an extra output mode:
summary-ex

Summary line

The summary line would be of some simple format like:

? requests tested (? succeeded, ? failed with ? CRITICAL)

So that an evaluation script may look at the last line and check that 0 failed or 0 CRITICAL is found, or do something if not (like trigger alerts, save or forward the full log...).

Options

Perhaps something like:

--summary             summary as above, with all requests included
--summary --failed    same format but showing just requests involving at least one failed test
--summary --critical  same format but showing just requests which have CRITICAL failures
--summary --json      outputs everything in json format for easy parsing

http-client.env.json is not used

I am using version v2.3.1 of the command line tool. In the same directory where my test.http file is placed I have http-client.env.json file with the following content:

{
"dev": {
"target_host": "http://test.com"
}
}

When I run
httpyac -v test.http -e dev

I get this error
ReferenceError: target_host is not defined

The same files work fine in VS Code with httpyac plug-in. I wonder if there is an error in CLI tool or I am doing something wrong calling httpyac

test.http references environment target_host as here:

GET {{target_host}}/{{uri}}

Sensitive Data in Log

comment of @gerukin in #49

one issue that I'm not sure is addressed by httpyac yet is redaction of confidential / sensitive / secret data in cookies, headers, query strings, req body and so on. If not saving the output, we avoid it there, but it's still potentially an issue with the request... and perhaps even with the response headers and so on. One short term way to deal with this would be to only include the summary info for now while you consider what to do (if anything) for data redaction. Another solution is to include everything, have no built-in redaction mechanism... and leave it to a post script or future adapter too.

Meta option to handle rate limiting (HTTP 429)

Often endpoints are rate limited. Sometimes by endpoint and sometimes by API key (or both). Usually by span of time between requests or by max requests in span of time. I think it would be difficult to try to perfectly handle all scenarios, but something approximative can still be very useful.

A # @wait ??? could be used for each request to indicate the number of ms to wait before [re]executing the request.

A slightly better version IMO could be # @interval ??? which would wait just long enough to make sure ??? ms have passed since the last executed request (ex: if this is the first request, it doesn't wait at all, if the last request was executed 2s ago, it waits only ??? - 2s, which may be 0).

Maybe this is enough to handle most use cases (although it might be a bit wasteful in max requests in span of time scenarios, they can still be addressed). It would certainly be enough to take care of my own.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.