Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ All notable changes to this project will be documented in this file.
- Global variables functionality
- Set and use variables that persist across requests within a session
- Global variables take precedence over environment variables

- New command `:HttpRunAll` to run all requests in the current file
- Warning message when environment variables are needed but not set
### Fixes
- Ability to run requests without selecting an environment file
- Dry run execution even when no environment file is selected

## 9/13/2024
### New Features
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ You can adjust these settings to your preferences.
- `:HttpEnvFile`: Select an environment file (.env.json) to use.
- `:HttpEnv {env}`: Set the current environment to use (e.g., `:HttpEnv production`).
- `:HttpRun`: Run the HTTP request under the cursor.
- `:HttpRunAll`: Run all HTTP requests in the current file.
- `:HttpStop`: Stop the currently running HTTP request.
- `:HttpVerbose`: Toggle verbose mode for debugging.
- `:HttpDryRun`: Perform a dry run of the request under the cursor.
Expand Down Expand Up @@ -183,6 +184,11 @@ GET {{base_url}}/protected
Authorization: Bearer {{auth_token}}
```

### Running Without Environment
You can now run requests without selecting an environment file. If environment variables are needed but not set, the plugin will display a message suggesting to select an environment file or set properties via a response handler.

Dry runs can be executed even if no environment file is selected. In this case, a warning will be displayed in the dry run output if environment variables are needed but not set.

## Telescope Integration

This plugin can be integrated with Telescope for a more interactive experience in selecting environment files and environments. To use the Telescope integration:
Expand Down
15 changes: 15 additions & 0 deletions doc/http_client.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ COMMANDS *http_client-commands*
:HttpDryRun *:HttpDryRun*
Perform a dry run of the request under the cursor.

:HttpRunAll *:HttpRunAll*
Run all HTTP requests in the current file.

------------------------------------------------------------------------------
KEYBINDINGS *http_client-keybindings*

Expand Down Expand Up @@ -239,6 +242,18 @@ To use a global variable in a request:

Global variables take precedence over environment variables with the same name.

------------------------------------------------------------------------------
RUNNING WITHOUT ENVIRONMENT *http_client-no-environment*

The plugin now allows running requests without selecting an environment file.
If environment variables are needed but not set, a message will be displayed
suggesting to select an environment file or set properties via a response
handler.

Dry runs can be executed even if no environment file is selected. In this case,
a warning will be displayed in the dry run output if environment variables are
needed but not set.

==============================================================================
vim:ft=help:et:ts=4:sw=4:sts=4:norl:

42 changes: 42 additions & 0 deletions examples/noenv.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
### Get XML data
GET https://httpbin.org/xml
User-Agent: heilgar/nvim-http-client
Accept: application/xml

### Post XML data
POST https://httpbin.org/post
User-Agent: heilgar/nvim-http-client
Content-Type: application/xml
Accept: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<person>
<name>John Doe</name>
<age>30</age>
<city>New York</city>
</person>

### Put XML data
PUT https://httpbin.org/put
User-Agent: heilgar/nvim-http-client
Content-Type: application/xml
Accept: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<post>
<id>1</id>
<title>Updated Title</title>
<body>This is an updated post.</body>
</post>

### Delete XML resource
DELETE https://httpbin.org/delete
User-Agent: heilgar/nvim-http-client
Content-Type: application/xml
Accept: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<delete>
<id>1</id>
</delete>

3 changes: 3 additions & 0 deletions examples/xml.http
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Accept: application/xml
POST {{base_url}}/post
User-Agent: heilgar/nvim-http-client
Content-Type: application/xml
Accept: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<person>
Expand All @@ -19,6 +20,7 @@ Content-Type: application/xml
PUT {{base_url}}/put
User-Agent: heilgar/nvim-http-client
Content-Type: application/xml
Accept: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<post>
Expand All @@ -31,6 +33,7 @@ Content-Type: application/xml
DELETE {{base_url}}/delete
User-Agent: heilgar/nvim-http-client
Content-Type: application/xml
Accept: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<delete>
Expand Down
39 changes: 39 additions & 0 deletions lua/http_client/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ M.run_request = function()
end

local env = environment.get_current_env()
local env_needed = environment.env_variables_needed(request)

if env_needed and not next(env) then
print(
'Environment variables are needed but not set. Please select an environment file or set properties via response handler.'
)
return
end

request = parser.replace_placeholders(request, env)

if verbose then
Expand Down Expand Up @@ -136,5 +145,35 @@ M.dry_run = function()
dry_run.display_dry_run(M)
end

M.run_all = function()
local verbose = vvv.get_verbose_mode()
vvv.set_verbose_mode(verbose)

local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
local requests = parser.parse_all_requests(lines)
local results = {}
local env = environment.get_current_env()

for _, request in ipairs(requests) do
local env_needed = environment.env_variables_needed(request)
if env_needed and not next(env) then
table.insert(results, string.format("SKIP: %s %s - Environment variables needed but not set", request.method, request.url))
else
request = parser.replace_placeholders(request, env)
local response = http_client.send_request_sync(request)
local result = string.format("%s: %s %s %s %s",
response.status < 400 and "OK" or "ERR",
request.method,
request.url,
request.http_version or "HTTP/1.1",
response.status)
table.insert(results, result)
end
end

local ui = require('http_client.ui.display')
ui.display_in_buffer(table.concat(results, "\n"), "HTTP Run All Results")
end

return M

22 changes: 22 additions & 0 deletions lua/http_client/core/environment.lua
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,27 @@ M.get_global_variable = function(key)
return global_variables[key]
end

M.env_variables_needed = function (request)
local function check_for_placeholders(str)
return str and str:match("{{.-}}")
end

if check_for_placeholders(request.url) then
return true
end

for _, header_value in pairs(request.headers) do
if check_for_placeholders(header_value) then
return true
end
end

if check_for_placeholders(request.body) then
return true
end

return false
end

return M

31 changes: 31 additions & 0 deletions lua/http_client/core/http_client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -256,5 +256,36 @@ M.get_current_request = function()
return current_request
end

M.send_request_sync = function(request)
local response = {}
local curl_options = {
url = request.url,
method = request.method,
body = request.body,
headers = request.headers,
}

if request.http_version then
if request.http_version == "HTTP/2" then
curl_options.http_version = "HTTP/2"
elseif request.http_version == "HTTP/2 (Prior Knowledge)" then
curl_options.http_version = "HTTP/2"
elseif request.http_version == "HTTP/1.1" then
curl_options.http_version = "HTTP/1.1"
end
end

local ssl_config = require('http_client.core.environment').get_ssl_config()
if ssl_config.verifyHostCertificate == false then
curl_options.insecure = true
end

response = curl.get(curl_options)
local pr = prepare_response(request, response)
handle_response(pr)

return response
end

return M

25 changes: 25 additions & 0 deletions lua/http_client/core/parser.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local M = {}
local environment = require('http_client.core.environment')

local function trim(s)
return s:match("^%s*(.-)%s*$")
Expand Down Expand Up @@ -147,6 +148,30 @@ M.parse_request = function(lines)
return request
end

M.parse_all_requests = function(lines)
local requests = {}
local current_request = {}
local in_request = false

for _, line in ipairs(lines) do
if line:match("^###") then
if in_request and #current_request > 0 then
table.insert(requests, M.parse_request(current_request))
current_request = {}
end
in_request = true
elseif in_request then
table.insert(current_request, line)
end
end

if #current_request > 0 then
table.insert(requests, M.parse_request(current_request))
end

return requests
end

M.replace_placeholders = function(request, env)
local function replace(str)
if str == nil then
Expand Down
6 changes: 6 additions & 0 deletions lua/http_client/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ function M.setup(opts)
desc = 'Perform a dry run of the HTTP request without sending it.'
})

vim.api.nvim_create_user_command('HttpRunAll', function()
M.commands.run_all()
end, {
desc = 'Run all HTTP requests in the current file.'
})



setup_docs()
Expand Down
12 changes: 11 additions & 1 deletion lua/http_client/ui/dry_run.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local M = {}
local environment = require('http_client.core.environment')

local function format_headers(headers)
local formatted = {}
Expand All @@ -11,14 +12,20 @@ end

M.display_dry_run = function(http_client)
local parser = http_client.parser
local environment = http_client.environment
local request = parser.get_request_under_cursor()
if not request then
print('No valid HTTP request found under cursor')
return
end

local merged_env = environment.get_current_env()
local env_needed = environment.env_variables_needed(request)
local env_warning = ""

if env_needed and not next(merged_env) then
env_warning = "WARNING: Environment variables are needed but not set.\n"
end

request = parser.replace_placeholders(request, merged_env)

local env_file = environment.get_current_env_file() or "Not set"
Expand All @@ -27,9 +34,11 @@ M.display_dry_run = function(http_client)
local merged_env_info = vim.inspect(merged_env)
local current_request = vim.inspect(http_client.http_client.get_current_request() or {})


local ui = require('http_client.ui.display')

local content = string.format([[
%s
Dry Run Information (%s):
--------------------
%s %s %s
Expand All @@ -52,6 +61,7 @@ Environment (including global variables):
Current request:
%s
]],
env_warning,
request.test_name or "N/A",
request.method,
request.url,
Expand Down