@@ -160,6 +160,177 @@ def test_custom_authorization_header(setup_http_mock):
160160
161161 assert "?A=b" in data
162162 assert "X-Header: 123" in data
163+ # Custom authorization header should be set (may be masked)
164+ assert "X-Auth:" in data
165+
166+
167+ @pytest .mark .parametrize ("setup_http_mock" , [["none" ]], indirect = True )
168+ def test_custom_auth_with_empty_api_key_does_not_set_header (setup_http_mock ):
169+ """Test: In custom authentication mode, when the api_key is empty, no header should be set."""
170+ from core .workflow .entities .variable_pool import VariablePool
171+ from core .workflow .nodes .http_request .entities import (
172+ HttpRequestNodeAuthorization ,
173+ HttpRequestNodeData ,
174+ HttpRequestNodeTimeout ,
175+ )
176+ from core .workflow .nodes .http_request .executor import Executor
177+ from core .workflow .system_variable import SystemVariable
178+
179+ # Create variable pool
180+ variable_pool = VariablePool (
181+ system_variables = SystemVariable (user_id = "test" , files = []),
182+ user_inputs = {},
183+ environment_variables = [],
184+ conversation_variables = [],
185+ )
186+
187+ # Create node data with custom auth and empty api_key
188+ node_data = HttpRequestNodeData (
189+ title = "http" ,
190+ desc = "" ,
191+ url = "http://example.com" ,
192+ method = "get" ,
193+ authorization = HttpRequestNodeAuthorization (
194+ type = "api-key" ,
195+ config = {
196+ "type" : "custom" ,
197+ "api_key" : "" , # Empty api_key
198+ "header" : "X-Custom-Auth" ,
199+ },
200+ ),
201+ headers = "" ,
202+ params = "" ,
203+ body = None ,
204+ ssl_verify = True ,
205+ )
206+
207+ # Create executor
208+ executor = Executor (
209+ node_data = node_data , timeout = HttpRequestNodeTimeout (connect = 10 , read = 30 , write = 10 ), variable_pool = variable_pool
210+ )
211+
212+ # Get assembled headers
213+ headers = executor ._assembling_headers ()
214+
215+ # When api_key is empty, the custom header should NOT be set
216+ assert "X-Custom-Auth" not in headers
217+
218+
219+ @pytest .mark .parametrize ("setup_http_mock" , [["none" ]], indirect = True )
220+ def test_bearer_authorization_with_custom_header_ignored (setup_http_mock ):
221+ """
222+ Test that when switching from custom to bearer authorization,
223+ the custom header settings don't interfere with bearer token.
224+ This test verifies the fix for issue #23554.
225+ """
226+ node = init_http_node (
227+ config = {
228+ "id" : "1" ,
229+ "data" : {
230+ "title" : "http" ,
231+ "desc" : "" ,
232+ "method" : "get" ,
233+ "url" : "http://example.com" ,
234+ "authorization" : {
235+ "type" : "api-key" ,
236+ "config" : {
237+ "type" : "bearer" ,
238+ "api_key" : "test-token" ,
239+ "header" : "" , # Empty header - should default to Authorization
240+ },
241+ },
242+ "headers" : "" ,
243+ "params" : "" ,
244+ "body" : None ,
245+ },
246+ }
247+ )
248+
249+ result = node ._run ()
250+ assert result .process_data is not None
251+ data = result .process_data .get ("request" , "" )
252+
253+ # In bearer mode, should use Authorization header (value is masked with *)
254+ assert "Authorization: " in data
255+ # Should contain masked Bearer token
256+ assert "*" in data
257+
258+
259+ @pytest .mark .parametrize ("setup_http_mock" , [["none" ]], indirect = True )
260+ def test_basic_authorization_with_custom_header_ignored (setup_http_mock ):
261+ """
262+ Test that when switching from custom to basic authorization,
263+ the custom header settings don't interfere with basic auth.
264+ This test verifies the fix for issue #23554.
265+ """
266+ node = init_http_node (
267+ config = {
268+ "id" : "1" ,
269+ "data" : {
270+ "title" : "http" ,
271+ "desc" : "" ,
272+ "method" : "get" ,
273+ "url" : "http://example.com" ,
274+ "authorization" : {
275+ "type" : "api-key" ,
276+ "config" : {
277+ "type" : "basic" ,
278+ "api_key" : "user:pass" ,
279+ "header" : "" , # Empty header - should default to Authorization
280+ },
281+ },
282+ "headers" : "" ,
283+ "params" : "" ,
284+ "body" : None ,
285+ },
286+ }
287+ )
288+
289+ result = node ._run ()
290+ assert result .process_data is not None
291+ data = result .process_data .get ("request" , "" )
292+
293+ # In basic mode, should use Authorization header (value is masked with *)
294+ assert "Authorization: " in data
295+ # Should contain masked Basic credentials
296+ assert "*" in data
297+
298+
299+ @pytest .mark .parametrize ("setup_http_mock" , [["none" ]], indirect = True )
300+ def test_custom_authorization_with_empty_api_key (setup_http_mock ):
301+ """
302+ Test that custom authorization doesn't set header when api_key is empty.
303+ This test verifies the fix for issue #23554.
304+ """
305+ node = init_http_node (
306+ config = {
307+ "id" : "1" ,
308+ "data" : {
309+ "title" : "http" ,
310+ "desc" : "" ,
311+ "method" : "get" ,
312+ "url" : "http://example.com" ,
313+ "authorization" : {
314+ "type" : "api-key" ,
315+ "config" : {
316+ "type" : "custom" ,
317+ "api_key" : "" , # Empty api_key
318+ "header" : "X-Custom-Auth" ,
319+ },
320+ },
321+ "headers" : "" ,
322+ "params" : "" ,
323+ "body" : None ,
324+ },
325+ }
326+ )
327+
328+ result = node ._run ()
329+ assert result .process_data is not None
330+ data = result .process_data .get ("request" , "" )
331+
332+ # Custom header should NOT be set when api_key is empty
333+ assert "X-Custom-Auth:" not in data
163334
164335
165336@pytest .mark .parametrize ("setup_http_mock" , [["none" ]], indirect = True )
@@ -239,6 +410,7 @@ def test_json(setup_http_mock):
239410 assert "X-Header: 123" in data
240411
241412
413+ @pytest .mark .parametrize ("setup_http_mock" , [["none" ]], indirect = True )
242414def test_x_www_form_urlencoded (setup_http_mock ):
243415 node = init_http_node (
244416 config = {
@@ -285,6 +457,7 @@ def test_x_www_form_urlencoded(setup_http_mock):
285457 assert "X-Header: 123" in data
286458
287459
460+ @pytest .mark .parametrize ("setup_http_mock" , [["none" ]], indirect = True )
288461def test_form_data (setup_http_mock ):
289462 node = init_http_node (
290463 config = {
@@ -334,6 +507,7 @@ def test_form_data(setup_http_mock):
334507 assert "X-Header: 123" in data
335508
336509
510+ @pytest .mark .parametrize ("setup_http_mock" , [["none" ]], indirect = True )
337511def test_none_data (setup_http_mock ):
338512 node = init_http_node (
339513 config = {
@@ -366,6 +540,7 @@ def test_none_data(setup_http_mock):
366540 assert "123123123" not in data
367541
368542
543+ @pytest .mark .parametrize ("setup_http_mock" , [["none" ]], indirect = True )
369544def test_mock_404 (setup_http_mock ):
370545 node = init_http_node (
371546 config = {
@@ -394,6 +569,7 @@ def test_mock_404(setup_http_mock):
394569 assert "Not Found" in resp .get ("body" , "" )
395570
396571
572+ @pytest .mark .parametrize ("setup_http_mock" , [["none" ]], indirect = True )
397573def test_multi_colons_parse (setup_http_mock ):
398574 node = init_http_node (
399575 config = {
0 commit comments