diamond-in commited on
Commit
36dd04b
·
verified ·
1 Parent(s): cd57c7a

Update features/http_requests.py

Browse files
Files changed (1) hide show
  1. features/http_requests.py +154 -0
features/http_requests.py CHANGED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ HTTP request handling features
3
+ """
4
+ import json
5
+ import logging
6
+ from datetime import datetime
7
+ from browser.driver import get_driver, cleanup_driver
8
+ from config.settings import MAX_REQUEST_HISTORY
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ # Request history storage
13
+ _request_history = []
14
+
15
+ def make_http_request(url: str, method: str = "GET", headers: str = "", data: str = "", use_persistent: bool = False) -> str:
16
+ """Make HTTP request with custom method, headers, and data (like Postman)"""
17
+ global _request_history
18
+ driver = None
19
+ try:
20
+ driver = get_driver(None, use_persistent) # Don't navigate yet
21
+
22
+ # Parse headers if provided
23
+ headers_dict = {}
24
+ if headers:
25
+ try:
26
+ headers_dict = json.loads(headers)
27
+ except:
28
+ # Try to parse as key:value lines
29
+ for line in headers.strip().split('\n'):
30
+ if ':' in line:
31
+ key, value = line.split(':', 1)
32
+ headers_dict[key.strip()] = value.strip()
33
+
34
+ # Build the JavaScript to make the request
35
+ js_code = f"""
36
+ async function makeRequest() {{
37
+ const options = {{
38
+ method: '{method}',
39
+ headers: {json.dumps(headers_dict)},
40
+ }};
41
+
42
+ if (['{method}'].includes('POST') || ['{method}'].includes('PUT') || ['{method}'].includes('PATCH')) {{
43
+ options.body = {json.dumps(data) if data else '""'};
44
+ }}
45
+
46
+ try {{
47
+ const startTime = performance.now();
48
+ const response = await fetch('{url}', options);
49
+ const endTime = performance.now();
50
+
51
+ const responseHeaders = {{}};
52
+ response.headers.forEach((value, key) => {{
53
+ responseHeaders[key] = value;
54
+ }});
55
+
56
+ let responseBody;
57
+ const contentType = response.headers.get('content-type');
58
+ if (contentType && contentType.includes('application/json')) {{
59
+ responseBody = await response.json();
60
+ }} else {{
61
+ responseBody = await response.text();
62
+ }}
63
+
64
+ return {{
65
+ status: response.status,
66
+ statusText: response.statusText,
67
+ headers: responseHeaders,
68
+ body: responseBody,
69
+ url: response.url,
70
+ type: response.type,
71
+ redirected: response.redirected,
72
+ responseTime: Math.round(endTime - startTime)
73
+ }};
74
+ }} catch (error) {{
75
+ return {{
76
+ error: error.message,
77
+ type: 'NetworkError'
78
+ }};
79
+ }}
80
+ }}
81
+
82
+ return makeRequest();
83
+ """
84
+
85
+ # Navigate to a blank page first to avoid CORS issues
86
+ driver.get("about:blank")
87
+
88
+ # Execute the request
89
+ result = driver.execute_script(js_code)
90
+
91
+ # If result is a promise, wait for it
92
+ if isinstance(result, dict) and 'then' in str(type(result)):
93
+ result = driver.execute_async_script("""
94
+ const callback = arguments[arguments.length - 1];
95
+ arguments[0].then(callback).catch(e => callback({error: e.toString()}));
96
+ """, result)
97
+
98
+ # Save to history
99
+ _request_history.append({
100
+ "timestamp": datetime.now().isoformat(),
101
+ "method": method,
102
+ "url": url,
103
+ "headers": headers_dict,
104
+ "data": data,
105
+ "response": result
106
+ })
107
+
108
+ # Keep only last N requests
109
+ if len(_request_history) > MAX_REQUEST_HISTORY:
110
+ _request_history = _request_history[-MAX_REQUEST_HISTORY:]
111
+
112
+ return json.dumps(result, indent=2, default=str)
113
+ except Exception as e:
114
+ logger.error(f"Error in make_http_request: {e}")
115
+ return f"Error: {e}"
116
+ finally:
117
+ cleanup_driver(driver, use_persistent)
118
+
119
+ def export_as_curl(method: str, url: str, headers: str = "", data: str = "") -> str:
120
+ """Convert HTTP request to cURL command"""
121
+ try:
122
+ curl_cmd = f"curl -X {method}"
123
+
124
+ # Add headers
125
+ if headers:
126
+ headers_dict = {}
127
+ try:
128
+ headers_dict = json.loads(headers)
129
+ except:
130
+ for line in headers.strip().split('\n'):
131
+ if ':' in line:
132
+ key, value = line.split(':', 1)
133
+ headers_dict[key.strip()] = value.strip()
134
+
135
+ for key, value in headers_dict.items():
136
+ curl_cmd += f' -H "{key}: {value}"'
137
+
138
+ # Add data
139
+ if data and method in ['POST', 'PUT', 'PATCH']:
140
+ curl_cmd += f" -d '{data}'"
141
+
142
+ # Add URL
143
+ curl_cmd += f' "{url}"'
144
+
145
+ return curl_cmd
146
+ except Exception as e:
147
+ return f"Error generating cURL command: {e}"
148
+
149
+ def get_request_history() -> str:
150
+ """Get history of HTTP requests"""
151
+ if not _request_history:
152
+ return "No requests in history"
153
+
154
+ return json.dumps(_request_history, indent=2, default=str)