1<?php
2/*
3** Zabbix
4** Copyright (C) 2001-2021 Zabbix SIA
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19**/
20
21
22require_once dirname(__FILE__).'/include/config.inc.php';
23require_once dirname(__FILE__).'/include/hosts.inc.php';
24require_once dirname(__FILE__).'/include/httptest.inc.php';
25require_once dirname(__FILE__).'/include/forms.inc.php';
26
27$page['title'] = _('Configuration of web monitoring');
28$page['file'] = 'httpconf.php';
29$page['scripts'] = ['class.cviewswitcher.js'];
30
31require_once dirname(__FILE__).'/include/page_header.php';
32
33// VAR	TYPE	OPTIONAL	FLAGS	VALIDATION	EXCEPTION
34$fields = [
35	'groupid'			=> [T_ZBX_INT, O_OPT, P_SYS,	DB_ID,				null],
36	'new_httpstep'		=> [T_ZBX_STR, O_OPT, P_NO_TRIM,	null,				null],
37	'group_httptestid'	=> [T_ZBX_INT, O_OPT, null,	DB_ID,				null],
38	// form
39	'hostid'          => [T_ZBX_INT, O_OPT, P_SYS, DB_ID.NOT_ZERO,          'isset({form}) || isset({add}) || isset({update})'],
40	'applicationid'   => [T_ZBX_INT, O_OPT, null,  DB_ID,                   null, _('Application')],
41	'httptestid'      => [T_ZBX_INT, O_NO,  P_SYS, DB_ID,                   'isset({form}) && {form} == "update"'],
42	'name'            => [T_ZBX_STR, O_OPT, null,  NOT_EMPTY,               'isset({add}) || isset({update})', _('Name')],
43	'delay'           => [T_ZBX_STR, O_OPT, null,  null,					'isset({add}) || isset({update})'],
44	'retries'         => [T_ZBX_INT, O_OPT, null,  BETWEEN(1, 10),          'isset({add}) || isset({update})',
45		_('Attempts')
46	],
47	'status'          => [T_ZBX_STR, O_OPT, null,  null,                    null],
48	'agent'           => [T_ZBX_STR, O_OPT, null, null,                     'isset({add}) || isset({update})'],
49	'agent_other'     => [T_ZBX_STR, O_OPT, null, null,
50		'(isset({add}) || isset({update})) && {agent} == '.ZBX_AGENT_OTHER
51	],
52	'pairs'           => [T_ZBX_STR, O_OPT, P_NO_TRIM,  null,                    null],
53	'steps'           => [T_ZBX_STR, O_OPT, P_NO_TRIM,  null,                    'isset({add}) || isset({update})', _('Steps')],
54	'authentication'  => [T_ZBX_INT, O_OPT, null,  IN('0,1,2'),             'isset({add}) || isset({update})'],
55	'http_user'       => [T_ZBX_STR, O_OPT, null,  null,
56		'(isset({add}) || isset({update})) && isset({authentication}) && ({authentication}=='.HTTPTEST_AUTH_BASIC.
57			' || {authentication}=='.HTTPTEST_AUTH_NTLM.
58		')',
59		_('User')
60	],
61	'http_password'		=> [T_ZBX_STR, O_OPT, P_NO_TRIM, null,
62		'(isset({add}) || isset({update})) && isset({authentication}) && ({authentication}=='.HTTPTEST_AUTH_BASIC.
63			' || {authentication}=='.HTTPTEST_AUTH_NTLM.
64		')',
65		_('Password')
66	],
67	'http_proxy'		=> [T_ZBX_STR, O_OPT, null,	null,				'isset({add}) || isset({update})'],
68	'new_application'	=> [T_ZBX_STR, O_OPT, null,	null,				null],
69	'hostname'			=> [T_ZBX_STR, O_OPT, null,	null,				null],
70	'templated'			=> [T_ZBX_STR, O_OPT, null,	null,				null],
71	'verify_host'		=> [T_ZBX_STR, O_OPT, null,	null,				null],
72	'verify_peer'		=> [T_ZBX_STR, O_OPT, null,	null,				null],
73	'ssl_cert_file'		=> [T_ZBX_STR, O_OPT, null, null,					'isset({add}) || isset({update})'],
74	'ssl_key_file'		=> [T_ZBX_STR, O_OPT, null, null,					'isset({add}) || isset({update})'],
75	'ssl_key_password'	=> [T_ZBX_STR, O_OPT, P_NO_TRIM, null,				'isset({add}) || isset({update})'],
76	// filter
77	'filter_set' =>			[T_ZBX_STR, O_OPT, P_SYS,	null,		null],
78	'filter_rst' =>			[T_ZBX_STR, O_OPT, P_SYS,	null,		null],
79	'filter_status' =>		[T_ZBX_INT, O_OPT, null,
80		IN([-1, HTTPTEST_STATUS_ACTIVE, HTTPTEST_STATUS_DISABLED]), null
81	],
82	// actions
83	'action'			=> [T_ZBX_STR, O_OPT, P_SYS|P_ACT,
84								IN('"httptest.massclearhistory","httptest.massdelete","httptest.massdisable",'.
85									'"httptest.massenable"'
86								),
87								null
88							],
89	'clone'				=> [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null,			null],
90	'del_history'		=> [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null,			null],
91	'add'				=> [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null,			null],
92	'update'			=> [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null,			null],
93	'delete'			=> [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null,			null],
94	'cancel'			=> [T_ZBX_STR, O_OPT, P_SYS,	null,				null],
95	'form'				=> [T_ZBX_STR, O_OPT, P_SYS,	null,				null],
96	'form_refresh'		=> [T_ZBX_INT, O_OPT, null,	null,				null],
97	// sort and sortorder
98	'sort'				=> [T_ZBX_STR, O_OPT, P_SYS, IN('"hostname","name","status"'),				null],
99	'sortorder'			=> [T_ZBX_STR, O_OPT, P_SYS, IN('"'.ZBX_SORT_DOWN.'","'.ZBX_SORT_UP.'"'),	null]
100];
101
102check_fields($fields);
103
104if (!empty($_REQUEST['steps'])) {
105	order_result($_REQUEST['steps'], 'no');
106}
107
108/*
109 * Permissions
110 */
111//*
112if (hasRequest('httptestid')) {
113	$httptests = API::HttpTest()->get([
114		'output' => [],
115		'httptestids' => getRequest('httptestid'),
116		'editable' => true
117	]);
118
119	if (!$httptests) {
120		access_deny();
121	}
122}
123
124if (getRequest('hostid') && !isWritableHostTemplates([getRequest('hostid')])) {
125	access_deny();
126}
127
128$groupId = getRequest('groupid');
129if ($groupId && !API::HostGroup()->get(['groupids' => $groupId])) {
130	access_deny();
131}
132
133/*
134 * Actions
135 */
136// add new steps
137if (isset($_REQUEST['new_httpstep'])) {
138	$_REQUEST['steps'] = getRequest('steps', []);
139	$_REQUEST['new_httpstep']['no'] = count($_REQUEST['steps']) + 1;
140	array_push($_REQUEST['steps'], $_REQUEST['new_httpstep']);
141
142	unset($_REQUEST['new_httpstep']);
143}
144
145if (hasRequest('delete') && hasRequest('httptestid')) {
146	DBstart();
147
148	$result = API::HttpTest()->delete([getRequest('httptestid')]);
149
150	$result = DBend($result);
151
152	if ($result) {
153		uncheckTableRows(getRequest('hostid'));
154	}
155
156	show_messages($result, _('Web scenario deleted'), _('Cannot delete web scenario'));
157
158	unset($_REQUEST['form']);
159}
160elseif (isset($_REQUEST['clone']) && isset($_REQUEST['httptestid'])) {
161	unset($_REQUEST['httptestid']);
162	unset($_REQUEST['templated']);
163	$_REQUEST['form'] = 'clone';
164}
165elseif (hasRequest('del_history') && hasRequest('httptestid')) {
166	$result = true;
167
168	$httpTestId = getRequest('httptestid');
169
170	$httpTests = API::HttpTest()->get([
171		'output' => ['name'],
172		'httptestids' => [$httpTestId],
173		'selectHosts' => ['name'],
174		'editable' => true
175	]);
176
177	if ($httpTests) {
178		DBstart();
179
180		$result = deleteHistoryByHttpTestIds([$httpTestId]);
181		$result = ($result && DBexecute('UPDATE httptest SET nextcheck=0 WHERE httptestid='.zbx_dbstr($httpTestId)));
182
183		if ($result) {
184			$httpTest = reset($httpTests);
185			$host = reset($httpTest['hosts']);
186
187			add_audit(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_SCENARIO,
188				_('Web scenario').' ['.$httpTest['name'].'] ['.$httpTestId.'] '.
189					_('Host').' ['.$host['name'].'] '._('History cleared')
190			);
191		}
192
193		$result = DBend($result);
194	}
195
196	show_messages($result, _('History cleared'), _('Cannot clear history'));
197}
198elseif (hasRequest('add') || hasRequest('update')) {
199	if (hasRequest('update')) {
200		$messageTrue = _('Web scenario updated');
201		$messageFalse = _('Cannot update web scenario');
202	}
203	else {
204		$messageTrue = _('Web scenario added');
205		$messageFalse = _('Cannot add web scenario');
206	}
207
208	try {
209		DBstart();
210
211		$new_application = getRequest('new_application');
212
213		if (!empty($_REQUEST['applicationid']) && $new_application) {
214			throw new Exception(_('Cannot create new application, web scenario is already assigned to application.'));
215		}
216
217		$steps = getRequest('steps', []);
218		$field_names = ['headers', 'variables', 'post_fields', 'query_fields'];
219		$i = 1;
220
221		foreach ($steps as &$step) {
222			$step['no'] = $i++;
223			$step['follow_redirects'] = $step['follow_redirects']
224				? HTTPTEST_STEP_FOLLOW_REDIRECTS_ON
225				: HTTPTEST_STEP_FOLLOW_REDIRECTS_OFF;
226			$step['retrieve_mode'] = $step['retrieve_mode']
227				? HTTPTEST_STEP_RETRIEVE_MODE_HEADERS
228				: HTTPTEST_STEP_RETRIEVE_MODE_CONTENT;
229
230			foreach ($field_names as $field_name) {
231				$step[$field_name] = [];
232			}
233
234			if (array_key_exists('pairs', $step)) {
235				foreach ($field_names as $field_name) {
236					foreach ($step['pairs'] as $pair) {
237						if (array_key_exists('type', $pair) && $field_name === $pair['type'] &&
238							((array_key_exists('name', $pair) && $pair['name'] !== '') ||
239							(array_key_exists('value', $pair) && $pair['value'] !== ''))) {
240							$step[$field_name][] = [
241								'name' => (array_key_exists('name', $pair) ? $pair['name'] : ''),
242								'value' => (array_key_exists('value', $pair) ? $pair['value'] : '')
243							];
244						}
245					}
246				}
247				unset($step['pairs']);
248			}
249
250			foreach ($step['variables'] as &$variable) {
251				$variable['name'] = trim($variable['name']);
252			}
253			unset($variable);
254
255			if ($step['post_type'] == ZBX_POSTTYPE_FORM) {
256				$step['posts'] = $step['post_fields'];
257			}
258			unset($step['post_fields'], $step['post_type']);
259		}
260		unset($step);
261
262		$httpTest = [
263			'hostid' => $_REQUEST['hostid'],
264			'name' => $_REQUEST['name'],
265			'authentication' => $_REQUEST['authentication'],
266			'applicationid' => getRequest('applicationid', 0),
267			'delay' => getRequest('delay', DB::getDefault('httptest', 'delay')),
268			'retries' => $_REQUEST['retries'],
269			'status' => hasRequest('status') ? HTTPTEST_STATUS_ACTIVE : HTTPTEST_STATUS_DISABLED,
270			'agent' => hasRequest('agent_other') ? getRequest('agent_other') : getRequest('agent'),
271			'variables' => [],
272			'http_proxy' => $_REQUEST['http_proxy'],
273			'steps' => $steps,
274			'http_user' => ($_REQUEST['authentication'] == HTTPTEST_AUTH_NONE) ? '' : $_REQUEST['http_user'],
275			'http_password' => ($_REQUEST['authentication'] == HTTPTEST_AUTH_NONE) ? '' : $_REQUEST['http_password'],
276			'verify_peer' => getRequest('verify_peer', HTTPTEST_VERIFY_PEER_OFF),
277			'verify_host' => getRequest('verify_host', HTTPTEST_VERIFY_HOST_OFF),
278			'ssl_cert_file' => getRequest('ssl_cert_file'),
279			'ssl_key_file' => getRequest('ssl_key_file'),
280			'ssl_key_password' => getRequest('ssl_key_password'),
281			'headers' => []
282		];
283
284		foreach (getRequest('pairs', []) as $pair) {
285			if (array_key_exists('type', $pair) && in_array($pair['type'], ['variables', 'headers']) &&
286				((array_key_exists('name', $pair) && $pair['name'] !== '') ||
287				(array_key_exists('value', $pair) && $pair['value'] !== ''))) {
288
289				$httpTest[$pair['type']][] = [
290					'name' => (array_key_exists('name', $pair) ? $pair['name'] : ''),
291					'value' => (array_key_exists('value', $pair) ? $pair['value'] : '')
292				];
293			}
294		}
295
296		foreach ($httpTest['variables'] as &$variable) {
297			$variable['name'] = trim($variable['name']);
298		}
299		unset($variable);
300
301		if ($new_application) {
302			$exApp = API::Application()->get([
303				'output' => ['applicationid', 'flags'],
304				'hostids' => $_REQUEST['hostid'],
305				'filter' => ['name' => $new_application]
306			]);
307
308			/*
309			 * If application exists and it is a discovered application, prevent adding it to web scenario. If it is
310			 * a normal application, assign it to web scenario. Otherwise create new application.
311			 */
312			if ($exApp) {
313				if ($exApp[0]['flags'] == ZBX_FLAG_DISCOVERY_CREATED) {
314					throw new Exception(_s('Application "%1$s" already exists.', $new_application));
315				}
316				else {
317					$httpTest['applicationid'] = $exApp[0]['applicationid'];
318				}
319			}
320			else {
321				$result = API::Application()->create([
322					'name' => $new_application,
323					'hostid' => $_REQUEST['hostid']
324				]);
325				if ($result) {
326					$httpTest['applicationid'] = reset($result['applicationids']);
327				}
328				else {
329					throw new Exception(_s('Cannot add new application "%1$s".', $new_application));
330				}
331			}
332		}
333
334		if (isset($_REQUEST['httptestid'])) {
335			// unset fields that did not change
336			$dbHttpTest = API::HttpTest()->get([
337				'httptestids' => $_REQUEST['httptestid'],
338				'output' => API_OUTPUT_EXTEND,
339				'selectSteps' => API_OUTPUT_EXTEND
340			]);
341			$dbHttpTest = reset($dbHttpTest);
342			$dbHttpSteps = zbx_toHash($dbHttpTest['steps'], 'httpstepid');
343
344			$httpTest = CArrayHelper::unsetEqualValues($httpTest, $dbHttpTest, ['applicationid']);
345			foreach (['headers', 'variables'] as $field_name) {
346				if (count($httpTest[$field_name]) !== count($dbHttpTest[$field_name])) {
347					continue;
348				}
349
350				$changed = false;
351				foreach ($httpTest[$field_name] as $key => $field) {
352					if ($dbHttpTest[$field_name][$key]['name'] !== $field['name']
353							|| $dbHttpTest[$field_name][$key]['value'] !== $field['value']) {
354						$changed = true;
355						break;
356					}
357				}
358
359				if (!$changed) {
360					unset($httpTest[$field_name]);
361				}
362			}
363
364			foreach ($httpTest['steps'] as $snum => $step) {
365				if ($step['httpstepid'] < 1) {
366					unset($step['httpstepid']);
367					unset($httpTest['steps'][$snum]['httpstepid']);
368				}
369				if (array_key_exists('httpstepid', $step) && array_key_exists($step['httpstepid'], $dbHttpSteps)) {
370					$db_step = $dbHttpSteps[$step['httpstepid']];
371					$new_step = CArrayHelper::unsetEqualValues($step, $db_step, ['httpstepid']);
372					foreach (['headers', 'variables', 'posts', 'query_fields'] as $field_name) {
373						if (!array_key_exists($field_name, $new_step)
374								|| !is_array($new_step[$field_name]) || !is_array($db_step[$field_name])
375								|| count($new_step[$field_name]) !== count($db_step[$field_name])) {
376							continue;
377						}
378
379						$changed = false;
380						foreach ($new_step[$field_name] as $key => $field) {
381							if ($db_step[$field_name][$key]['name'] !== $field['name']
382									|| $db_step[$field_name][$key]['value'] !== $field['value']) {
383								$changed = true;
384								break;
385							}
386						}
387
388						if (!$changed) {
389							unset($new_step[$field_name]);
390						}
391					}
392					$httpTest['steps'][$snum] = $new_step;
393				}
394			}
395
396			$httpTest['httptestid'] = $httpTestId = $_REQUEST['httptestid'];
397
398			$result = API::HttpTest()->update($httpTest);
399			if (!$result) {
400
401				throw new Exception();
402			}
403			else {
404				uncheckTableRows(getRequest('hostid'));
405			}
406		}
407		else {
408			foreach ($httpTest['steps'] as &$step) {
409				unset($step['httptestid'], $step['httpstepid']);
410			}
411			unset($step);
412
413			$result = API::HttpTest()->create($httpTest);
414			if (!$result) {
415				throw new Exception();
416			}
417			else {
418				uncheckTableRows(getRequest('hostid'));
419			}
420			$httpTestId = reset($result['httptestids']);
421		}
422
423		unset($_REQUEST['form']);
424		show_messages(true, $messageTrue);
425		DBend(true);
426	}
427	catch (Exception $e) {
428		DBend(false);
429
430
431		$msg = $e->getMessage();
432		if (!empty($msg)) {
433			error($msg);
434		}
435		show_messages(false, null, $messageFalse);
436	}
437}
438elseif (hasRequest('action') && str_in_array(getRequest('action'), ['httptest.massenable', 'httptest.massdisable'])
439		&& hasRequest('group_httptestid') && is_array(getRequest('group_httptestid'))) {
440	$enable = (getRequest('action') === 'httptest.massenable');
441	$status = $enable ? HTTPTEST_STATUS_ACTIVE : HTTPTEST_STATUS_DISABLED;
442	$updated = 0;
443	$result = true;
444
445	$upd_httptests = [];
446
447	foreach (getRequest('group_httptestid') as $httptestid) {
448		$upd_httptests[] = [
449			'httptestid' => $httptestid,
450			'status' => $status
451		];
452	}
453
454	if ($upd_httptests) {
455		$result = (bool) API::HttpTest()->update($upd_httptests);
456	}
457
458	$updated = count($upd_httptests);
459
460	$messageSuccess = $enable
461		? _n('Web scenario enabled', 'Web scenarios enabled', $updated)
462		: _n('Web scenario disabled', 'Web scenarios disabled', $updated);
463	$messageFailed = $enable
464		? _n('Cannot enable web scenario', 'Cannot enable web scenarios', $updated)
465		: _n('Cannot disable web scenario', 'Cannot disable web scenarios', $updated);
466
467	if ($result) {
468		uncheckTableRows(getRequest('hostid'));
469	}
470
471	show_messages($result, $messageSuccess, $messageFailed);
472}
473elseif (hasRequest('action') && getRequest('action') === 'httptest.massclearhistory'
474		&& hasRequest('group_httptestid') && is_array(getRequest('group_httptestid'))) {
475	$result = false;
476
477	$httpTestIds = getRequest('group_httptestid');
478
479	$httpTests = API::HttpTest()->get([
480		'output' => ['httptestid', 'name'],
481		'httptestids' => $httpTestIds,
482		'selectHosts' => ['name'],
483		'editable' => true
484	]);
485
486	if ($httpTests) {
487		DBstart();
488
489		$result = deleteHistoryByHttpTestIds($httpTestIds);
490		$result = ($result && DBexecute(
491			'UPDATE httptest SET nextcheck=0 WHERE '.dbConditionInt('httptestid', $httpTestIds)
492		));
493
494		if ($result) {
495			foreach ($httpTests as $httpTest) {
496				$host = reset($httpTest['hosts']);
497
498				add_audit(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_SCENARIO,
499					_('Web scenario').' ['.$httpTest['name'].'] ['.$httpTest['httptestid'].'] '.
500						_('Host').' ['.$host['name'].'] '._('History cleared')
501				);
502			}
503		}
504
505		$result = DBend($result);
506
507		if ($result) {
508			uncheckTableRows(getRequest('hostid'));
509		}
510	}
511
512	show_messages($result, _('History cleared'), _('Cannot clear history'));
513}
514elseif (hasRequest('action') && getRequest('action') === 'httptest.massdelete'
515		&& hasRequest('group_httptestid') && is_array(getRequest('group_httptestid'))) {
516	$result = API::HttpTest()->delete(getRequest('group_httptestid'));
517
518	if ($result) {
519		uncheckTableRows(getRequest('hostid'));
520	}
521	show_messages($result, _('Web scenario deleted'), _('Cannot delete web scenario'));
522}
523
524if (hasRequest('action') && hasRequest('group_httptestid') && !$result) {
525	$httptests = API::HttpTest()->get([
526		'output' => [],
527		'httptestids' => getRequest('group_httptestid'),
528		'editable' => true
529	]);
530
531	uncheckTableRows(getRequest('hostid'), zbx_objectValues($httptests, 'httptestid'));
532}
533
534show_messages();
535
536/*
537 * Display
538 */
539if (isset($_REQUEST['form'])) {
540	$data = [
541		'hostid' => getRequest('hostid', 0),
542		'httptestid' => getRequest('httptestid'),
543		'form' => getRequest('form'),
544		'form_refresh' => getRequest('form_refresh'),
545		'templates' => []
546	];
547
548	$host = API::Host()->get([
549		'output' => ['status'],
550		'hostids' => $data['hostid'],
551		'templated_hosts' => true
552	]);
553	$data['host'] = reset($host);
554
555	if (hasRequest('httptestid') && !hasRequest('form_refresh')) {
556		$db_httptests = API::HttpTest()->get([
557			'output' => ['name', 'applicationid', 'delay', 'retries', 'status', 'agent', 'authentication',
558				'http_user', 'http_password', 'http_proxy', 'templateid', 'verify_peer', 'verify_host', 'ssl_cert_file',
559				'ssl_key_file', 'ssl_key_password', 'headers', 'variables'
560			],
561			'selectSteps' => ['httpstepid', 'name', 'no', 'url', 'timeout', 'posts', 'required', 'status_codes',
562				'follow_redirects', 'retrieve_mode', 'headers', 'variables', 'query_fields', 'post_type'
563			],
564			'httptestids' => getRequest('httptestid')
565		]);
566
567		$db_httptest = $db_httptests[0];
568
569		$data['name'] = $db_httptest['name'];
570		$data['applicationid'] = $db_httptest['applicationid'];
571		$data['new_application'] = '';
572		$data['delay'] = $db_httptest['delay'];
573		$data['retries'] = $db_httptest['retries'];
574		$data['status'] = $db_httptest['status'];
575		$data['templates'] = makeHttpTestTemplatesHtml($db_httptest['httptestid'],
576			getHttpTestParentTemplates($db_httptests)
577		);
578
579		$data['agent'] = ZBX_AGENT_OTHER;
580		$data['agent_other'] = $db_httptest['agent'];
581
582		foreach (userAgents() as $userAgents) {
583			if (array_key_exists($db_httptest['agent'], $userAgents)) {
584				$data['agent'] = $db_httptest['agent'];
585				$data['agent_other'] = '';
586				break;
587			}
588		}
589
590		// Used for both, Scenario and Steps pairs.
591		$id = 1;
592		$data['pairs'] = [];
593
594		$fields = [
595			'headers' => 'headers',
596			'variables' => 'variables'
597		];
598
599		CArrayHelper::sort($db_httptest['variables'], ['name']);
600
601		foreach ($fields as $type => $field_name) {
602			foreach ($db_httptest[$field_name] as $pair) {
603				$data['pairs'][] = [
604					'id' => $id++,
605					'type' => $type,
606					'name' => $pair['name'],
607					'value' => $pair['value']
608				];
609			}
610		}
611
612		$data['authentication'] = $db_httptest['authentication'];
613		$data['http_user'] = $db_httptest['http_user'];
614		$data['http_password'] = $db_httptest['http_password'];
615		$data['http_proxy'] = $db_httptest['http_proxy'];
616		$data['templated'] = (bool) $db_httptest['templateid'];
617
618		$data['verify_peer'] = $db_httptest['verify_peer'];
619		$data['verify_host'] = $db_httptest['verify_host'];
620		$data['ssl_cert_file'] = $db_httptest['ssl_cert_file'];
621		$data['ssl_key_file'] = $db_httptest['ssl_key_file'];
622		$data['ssl_key_password'] = $db_httptest['ssl_key_password'];
623		$data['steps'] = $db_httptest['steps'];
624		CArrayHelper::sort($data['steps'], ['no']);
625
626		$fields = [
627			'headers' => 'headers',
628			'variables' => 'variables',
629			'query_fields' => 'query_fields',
630			'post_fields' => 'posts'
631		];
632
633		foreach ($data['steps'] as &$step) {
634			$step['pairs'] = [];
635
636			CArrayHelper::sort($step['variables'], ['name']);
637
638			foreach ($fields as $type => $field_name) {
639				if ($field_name !== 'posts' || $step['post_type'] == ZBX_POSTTYPE_FORM) {
640					foreach ($step[$field_name] as $pair) {
641						$step['pairs'][] = [
642							'id' => $id++,
643							'type' => $type,
644							'name' => $pair['name'],
645							'value' => $pair['value']
646						];
647					}
648
649					if ($field_name === 'posts') {
650						$step['posts'] = '';
651					}
652					else {
653						unset($step[$field_name]);
654					}
655				}
656			}
657		}
658		unset($step);
659
660	}
661	else {
662		if (isset($_REQUEST['form_refresh'])) {
663			$data['status'] = isset($_REQUEST['status']) ? HTTPTEST_STATUS_ACTIVE : HTTPTEST_STATUS_DISABLED;
664		}
665		else {
666			$data['status'] = HTTPTEST_STATUS_ACTIVE;
667		}
668
669		$data['name'] = getRequest('name', '');
670		$data['applicationid'] = getRequest('applicationid');
671		$data['new_application'] = getRequest('new_application', '');
672		$data['delay'] = getRequest('delay', DB::getDefault('httptest', 'delay'));
673		$data['retries'] = getRequest('retries', 1);
674
675		$data['agent'] = getRequest('agent', ZBX_DEFAULT_AGENT);
676		$data['agent_other'] = getRequest('agent_other');
677
678		if ($data['agent'] == ZBX_AGENT_OTHER) {
679			foreach (userAgents() as $userAgents) {
680				if (array_key_exists($data['agent_other'], $userAgents)) {
681					$data['agent'] = $data['agent_other'];
682					$data['agent_other'] = '';
683					break;
684				}
685			}
686		}
687
688		$data['authentication'] = getRequest('authentication', HTTPTEST_AUTH_NONE);
689		$data['http_user'] = getRequest('http_user', '');
690		$data['http_password'] = getRequest('http_password', '');
691		$data['http_proxy'] = getRequest('http_proxy', '');
692		$data['templated'] = (bool) getRequest('templated');
693		$data['steps'] = getRequest('steps', []);
694		$data['verify_peer'] = getRequest('verify_peer');
695		$data['verify_host'] = getRequest('verify_host');
696		$data['ssl_cert_file'] = getRequest('ssl_cert_file');
697		$data['ssl_key_file'] = getRequest('ssl_key_file');
698		$data['ssl_key_password'] = getRequest('ssl_key_password');
699		$data['pairs'] = array_values(getRequest('pairs', []));
700	}
701
702	$data['application_list'] = [];
703	if (!empty($data['hostid'])) {
704		$db_applications = API::Application()->get([
705			'output' => ['name'],
706			'hostids' => $data['hostid'],
707			'filter' => ['flags' => ZBX_FLAG_DISCOVERY_NORMAL],
708			'preservekeys' => true
709		]);
710
711		CArrayHelper::sort($db_applications, ['name']);
712		foreach ($db_applications as $applicationid => $db_application) {
713			$data['application_list'][$applicationid] = $db_application['name'];
714		}
715	}
716
717	$i = 1;
718
719	foreach($data['steps'] as $stepid => $step) {
720		$pairs_grouped = [
721			'query_fields' => [],
722			'post_fields' => [],
723			'variables' => [],
724			'headers' => []
725		];
726
727		if (array_key_exists('pairs', $step)) {
728			foreach ($step['pairs'] as $field) {
729				$pairs_grouped[$field['type']][] = $field;
730			}
731			$data['steps'][$stepid]['pairs'] = $pairs_grouped;
732		}
733		$data['steps'][$stepid]['no'] = $i++;
734	}
735
736	// render view
737	$httpView = new CView('configuration.httpconf.edit', $data);
738	$httpView->render();
739	$httpView->show();
740}
741else {
742	$sortField = getRequest('sort', CProfile::get('web.'.$page['file'].'.sort', 'name'));
743	$sortOrder = getRequest('sortorder', CProfile::get('web.'.$page['file'].'.sortorder', ZBX_SORT_UP));
744
745	CProfile::update('web.'.$page['file'].'.sort', $sortField, PROFILE_TYPE_STR);
746	CProfile::update('web.'.$page['file'].'.sortorder', $sortOrder, PROFILE_TYPE_STR);
747
748	if (hasRequest('filter_set')) {
749		CProfile::update('web.httpconf.filter_status', getRequest('filter_status', -1), PROFILE_TYPE_INT);
750	}
751	elseif (hasRequest('filter_rst')) {
752		CProfile::delete('web.httpconf.filter_status');
753	}
754
755	$pageFilter = new CPageFilter([
756		'groups' => [
757			'editable' => true
758		],
759		'hosts' => [
760			'editable' => true,
761			'templated_hosts' => true
762		],
763		'hostid' => getRequest('hostid'),
764		'groupid' => getRequest('groupid')
765	]);
766
767	$data = [
768		'hostid' => $pageFilter->hostid,
769		'pageFilter' => $pageFilter,
770		'filter_status' => CProfile::get('web.httpconf.filter_status', -1),
771		'httpTests' => [],
772		'httpTestsLastData' => [],
773		'paging' => null,
774		'sort' => $sortField,
775		'sortorder' => $sortOrder,
776		'profileIdx' => 'web.httpconf.filter',
777		'active_tab' => CProfile::get('web.httpconf.filter.active', 1)
778	];
779
780	// show the error column only for hosts
781	if (getRequest('hostid') != 0) {
782		$data['showInfoColumn'] = (bool) API::Host()->get([
783			'hostids' => getRequest('hostid'),
784			'output' => ['status']
785		]);
786	}
787	else {
788		$data['showInfoColumn'] = true;
789	}
790
791	if ($data['pageFilter']->hostsSelected) {
792		$config = select_config();
793
794		$options = [
795			'editable' => true,
796			'output' => ['httptestid', $sortField],
797			'limit' => $config['search_limit'] + 1
798		];
799		if ($data['filter_status'] != -1) {
800			$options['filter']['status'] = $data['filter_status'];
801		}
802		if ($data['pageFilter']->hostid > 0) {
803			$options['hostids'] = $data['pageFilter']->hostid;
804		}
805		elseif ($data['pageFilter']->groupid > 0) {
806			$options['groupids'] = $data['pageFilter']->groupids;
807		}
808		$httpTests = API::HttpTest()->get($options);
809
810		$dbHttpTests = DBselect(
811			'SELECT ht.httptestid,ht.name,ht.delay,ht.status,ht.hostid,ht.templateid,h.name AS hostname,ht.retries,'.
812				'ht.authentication,ht.http_proxy,a.applicationid,a.name AS application_name'.
813				' FROM httptest ht'.
814				' INNER JOIN hosts h ON h.hostid=ht.hostid'.
815				' LEFT JOIN applications a ON a.applicationid=ht.applicationid'.
816				' WHERE '.dbConditionInt('ht.httptestid', zbx_objectValues($httpTests, 'httptestid'))
817		);
818		$httpTests = [];
819		while ($dbHttpTest = DBfetch($dbHttpTests)) {
820			$httpTests[$dbHttpTest['httptestid']] = $dbHttpTest;
821		}
822
823		order_result($httpTests, $sortField, $sortOrder);
824
825		$url = (new CUrl('httpconf.php'))
826			->setArgument('hostid', $data['hostid'])
827			->setArgument('groupid', $data['pageFilter']->groupid);
828
829		$data['paging'] = getPagingLine($httpTests, $sortOrder, $url);
830
831		if($data['showInfoColumn']) {
832			$httpTestsLastData = Manager::HttpTest()->getLastData(array_keys($httpTests));
833
834			foreach ($httpTestsLastData as $httpTestId => &$lastData) {
835				if ($lastData['lastfailedstep'] !== null) {
836					$lastData['failedstep'] = get_httpstep_by_no($httpTestId, $lastData['lastfailedstep']);
837				}
838			}
839			unset($lastData);
840		}
841		else {
842			$httpTestsLastData = [];
843		}
844
845		$dbHttpSteps = DBselect(
846			'SELECT hs.httptestid,COUNT(*) AS stepscnt'.
847				' FROM httpstep hs'.
848				' WHERE '.dbConditionInt('hs.httptestid', zbx_objectValues($httpTests, 'httptestid')).
849				' GROUP BY hs.httptestid'
850		);
851		while ($dbHttpStep = DBfetch($dbHttpSteps)) {
852			$httpTests[$dbHttpStep['httptestid']]['stepscnt'] = $dbHttpStep['stepscnt'];
853		}
854
855		order_result($httpTests, $sortField, $sortOrder);
856
857		$data['parent_templates'] = getHttpTestParentTemplates($httpTests);
858		$data['httpTests'] = $httpTests;
859		$data['httpTestsLastData'] = $httpTestsLastData;
860	}
861
862	// render view
863	$httpView = new CView('configuration.httpconf.list', $data);
864	$httpView->render();
865	$httpView->show();
866}
867
868require_once dirname(__FILE__).'/include/page_footer.php';
869