소스 검색

fix(http_request): send form data (#10431)

tags/0.11.1
-LAN- 11 달 전
부모
커밋
438ad8148b
No account linked to committer's email address

+ 9
- 13
api/core/workflow/nodes/http_request/executor.py 파일 보기

headers = self.variable_pool.convert_template(self.node_data.headers).text headers = self.variable_pool.convert_template(self.node_data.headers).text
self.headers = _plain_text_to_dict(headers) self.headers = _plain_text_to_dict(headers)


body = self.node_data.body
if body is None:
return
if "content-type" not in (k.lower() for k in self.headers) and body.type in BODY_TYPE_TO_CONTENT_TYPE:
self.headers["Content-Type"] = BODY_TYPE_TO_CONTENT_TYPE[body.type]
if body.type == "form-data":
self.boundary = f"----WebKitFormBoundary{_generate_random_string(16)}"
self.headers["Content-Type"] = f"multipart/form-data; boundary={self.boundary}"

def _init_body(self): def _init_body(self):
body = self.node_data.body body = self.node_data.body
if body is not None: if body is not None:
for k, v in files.items() for k, v in files.items()
if v.related_id is not None if v.related_id is not None
} }

self.data = form_data self.data = form_data
self.files = files
self.files = files or None


def _assembling_headers(self) -> dict[str, Any]: def _assembling_headers(self) -> dict[str, Any]:
authorization = deepcopy(self.auth) authorization = deepcopy(self.auth)
"timeout": (self.timeout.connect, self.timeout.read, self.timeout.write), "timeout": (self.timeout.connect, self.timeout.read, self.timeout.write),
"follow_redirects": True, "follow_redirects": True,
} }
# request_args = {k: v for k, v in request_args.items() if v is not None}


response = getattr(ssrf_proxy, self.method)(**request_args) response = getattr(ssrf_proxy, self.method)(**request_args)
return response return response
raw += f"Host: {url_parts.netloc}\r\n" raw += f"Host: {url_parts.netloc}\r\n"


headers = self._assembling_headers() headers = self._assembling_headers()
body = self.node_data.body
boundary = f"----WebKitFormBoundary{_generate_random_string(16)}"
if body:
if "content-type" not in (k.lower() for k in self.headers) and body.type in BODY_TYPE_TO_CONTENT_TYPE:
headers["Content-Type"] = BODY_TYPE_TO_CONTENT_TYPE[body.type]
if body.type == "form-data":
headers["Content-Type"] = f"multipart/form-data; boundary={boundary}"
for k, v in headers.items(): for k, v in headers.items():
if self.auth.type == "api-key": if self.auth.type == "api-key":
authorization_header = "Authorization" authorization_header = "Authorization"


body = "" body = ""
if self.files: if self.files:
boundary = self.boundary
for k, v in self.files.items(): for k, v in self.files.items():
body += f"--{boundary}\r\n" body += f"--{boundary}\r\n"
body += f'Content-Disposition: form-data; name="{k}"\r\n\r\n' body += f'Content-Disposition: form-data; name="{k}"\r\n\r\n'
elif self.data and self.node_data.body.type == "x-www-form-urlencoded": elif self.data and self.node_data.body.type == "x-www-form-urlencoded":
body = urlencode(self.data) body = urlencode(self.data)
elif self.data and self.node_data.body.type == "form-data": elif self.data and self.node_data.body.type == "form-data":
boundary = self.boundary
for key, value in self.data.items(): for key, value in self.data.items():
body += f"--{boundary}\r\n" body += f"--{boundary}\r\n"
body += f'Content-Disposition: form-data; name="{key}"\r\n\r\n' body += f'Content-Disposition: form-data; name="{key}"\r\n\r\n'

+ 69
- 0
api/tests/unit_tests/core/workflow/nodes/http_request/test_http_request_executor.py 파일 보기

) )


assert executor.params == {"test": "line1\nline2"} assert executor.params == {"test": "line1\nline2"}


def test_executor_with_form_data():
# Prepare the variable pool
variable_pool = VariablePool(
system_variables={},
user_inputs={},
)
variable_pool.add(["pre_node_id", "text_field"], "Hello, World!")
variable_pool.add(["pre_node_id", "number_field"], 42)

# Prepare the node data
node_data = HttpRequestNodeData(
title="Test Form Data",
method="post",
url="https://api.example.com/upload",
authorization=HttpRequestNodeAuthorization(type="no-auth"),
headers="Content-Type: multipart/form-data",
params="",
body=HttpRequestNodeBody(
type="form-data",
data=[
BodyData(
key="text_field",
type="text",
value="{{#pre_node_id.text_field#}}",
),
BodyData(
key="number_field",
type="text",
value="{{#pre_node_id.number_field#}}",
),
],
),
)

# Initialize the Executor
executor = Executor(
node_data=node_data,
timeout=HttpRequestNodeTimeout(connect=10, read=30, write=30),
variable_pool=variable_pool,
)

# Check the executor's data
assert executor.method == "post"
assert executor.url == "https://api.example.com/upload"
assert "Content-Type" in executor.headers
assert "multipart/form-data" in executor.headers["Content-Type"]
assert executor.params == {}
assert executor.json is None
assert executor.files is None
assert executor.content is None

# Check that the form data is correctly loaded in executor.data
assert isinstance(executor.data, dict)
assert "text_field" in executor.data
assert executor.data["text_field"] == "Hello, World!"
assert "number_field" in executor.data
assert executor.data["number_field"] == "42"

# Check the raw request (to_log method)
raw_request = executor.to_log()
assert "POST /upload HTTP/1.1" in raw_request
assert "Host: api.example.com" in raw_request
assert "Content-Type: multipart/form-data" in raw_request
assert "text_field" in raw_request
assert "Hello, World!" in raw_request
assert "number_field" in raw_request
assert "42" in raw_request

Loading…
취소
저장