Skip to content

Commit 8ca187c

Browse files
committed
refactoring
1 parent cae36ab commit 8ca187c

File tree

1 file changed

+55
-45
lines changed

1 file changed

+55
-45
lines changed

httpscan.py

Lines changed: 55 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def deduplicate(seq):
8383

8484

8585
class HttpScannerOutput(object):
86+
8687
def __init__(self, args):
8788
# TODO: make separate queues for fast logging
8889
self.args = args
@@ -236,59 +237,63 @@ def write_func(self, worker_id, url, response, exception):
236237
# Acquire lock
237238
self.lock.acquire()
238239
parsed = self._parse_response(url, response)
240+
status = parsed['status']
239241

240242
# Calculate progreess
241243
self.urls_scanned += 1
242244
percentage = '{percent:.2%}'.format(percent=float(self.urls_scanned) / self.args.urls_count)
243245
# TODO: add detailed stats
244246

245247
# Generate and print colored output
246-
out = '[%s] [worker:%02i] [%s]\t%s -> %i' % (strnow(), worker_id, percentage, parsed['url'], parsed['status'])
248+
out = '[%s] [worker:%02i] [%s]\t%s -> %i' % (strnow(), worker_id, percentage, parsed['url'], status)
247249
if exception is not None:
248250
out += '(%s)' % str(exception)
249-
if parsed['status'] == 200:
251+
if status == 200:
250252
print(Fore.GREEN + out + Fore.RESET)
251-
elif 400 <= parsed['status'] < 500 or parsed['status'] == -1:
253+
elif 400 <= status < 500 or status == -1:
252254
print(Fore.RED + out + Fore.RESET)
253255
else:
254256
print(Fore.YELLOW + out + Fore.RESET)
255257

256258
# Write to log file
257259
if self.logger is not None:
258-
out = '[worker:%02i] %s %s %i' % (worker_id, url, parsed['status'], parsed['length'])
260+
out = '[worker:%02i] %s %s %i' % (worker_id, url, status, parsed['length'])
259261
if exception is None:
260262
self.logger.info(out)
261263
else:
262264
self.logger.error("%s %s" % (out, str(exception)))
263265

264266
# Check for exception
265-
if exception is not None:
266-
self.lock.release()
267-
return
267+
if exception is None:
268+
self._filter_and_write(url, response, parsed)
269+
270+
# Realse lock
271+
self.lock.release()
268272

273+
def _filter_and_write(self, url, response, parsed):
269274
# Filter responses and save responses that are matching ignore, allow rules
270275
if (self.args.allow is None and self.args.ignore is None) or \
271276
(self.args.allow is not None and parsed['status'] in self.args.allow) or \
272277
(self.args.ignore is not None and parsed['status'] not in self.args.ignore):
278+
self._write_csv(parsed)
279+
self._write_json(parsed)
280+
self._write_dump(url, response)
281+
self._write_db(parsed)
282+
283+
def _write_csv(self, parsed):
284+
# Write to CSV file
285+
if self.csv is None:
286+
return
273287

274-
# Write to CSV file
275-
if self.csv is not None:
276-
self.csv.writerow([parsed['url'], parsed['status'], parsed['length'], parsed['headers']])
277-
278-
# Write to JSON file
279-
if self.json is not None:
280-
self.json.write(unicode(dumps(parsed, ensure_ascii=False)))
281-
282-
# Save contents to file
283-
if self.dump is not None:
284-
self._write_dump(url, response)
288+
self.csv.writerow([parsed['url'], parsed['status'], parsed['length'], parsed['headers']])
285289

286-
# Write to database
287-
if self.engine is not None:
288-
self._write_db(parsed)
290+
def _write_json(self, parsed):
291+
# Write to JSON file
292+
if self.json is None:
293+
return
289294

290-
# Realse lock
291-
self.lock.release()
295+
# TODO: bugfix appending json
296+
self.json.write(unicode(dumps(parsed, ensure_ascii=False)))
292297

293298
def _write_dump(self, url, response):
294299
"""
@@ -297,7 +302,7 @@ def _write_dump(self, url, response):
297302
:param response: response
298303
:return: None
299304
"""
300-
if response is None:
305+
if response is None or self.dump is None:
301306
return
302307

303308
# Generate folder and file path
@@ -322,6 +327,8 @@ def _write_dump(self, url, response):
322327
f.close()
323328

324329
def _write_db(self, parsed):
330+
if self.engine is None:
331+
return
325332
# TODO: check if url exists in table
326333
self.scan_table.insert()
327334
self.engine.execute(self.scan_table.insert().execution_options(autocommit=True), parsed)
@@ -556,18 +563,11 @@ def _scan_host(self, worker_id, host):
556563
errors_count += 1
557564

558565
if self.args.skip is not None and errors_count == self.args.skip:
559-
self.output.logger.warning('Errors limit reached on %s Skipping other urls.' % host)
566+
self.output.write_log('Errors limit reached on %s Skipping other urls.' % host, logging.WARNING)
560567
self.output.urls_scanned += len(self.urls) - urls_scanned
561568
return
562569

563-
def _scan_url(self, worker_id, url, use_head=False):
564-
"""
565-
Scan specified URL with HTTP GET request
566-
:param url: url to scan
567-
:return: HTTP response
568-
"""
569-
self.output.write_log('Scanning %s' % url, logging.DEBUG)
570-
570+
def _fill_headers(self):
571571
# Fill UserAgent in headers
572572
headers = {}
573573
if self.args.user_agent is not None:
@@ -579,29 +579,39 @@ def _scan_url(self, worker_id, url, use_head=False):
579579
if self.args.referer is not None:
580580
headers['Referer'] = self.args.referer
581581

582+
return headers
583+
584+
def _scan_url(self, worker_id, url, use_head=False):
585+
"""
586+
Scan specified URL with HTTP GET request
587+
:param url: url to scan
588+
:return: HTTP response
589+
"""
590+
self.output.write_log('Scanning %s' % url, logging.DEBUG)
591+
582592
# Query URL and handle exceptions
583593
response, exception = None, None
584594
try:
585595
# TODO: add support for user:password in URL
586596
if use_head:
587-
response = self.session.head(url, headers=headers, allow_redirects=self.args.allow_redirects)
597+
response = self.session.head(url, headers=self._fill_headers(), allow_redirects=self.args.allow_redirects)
588598
else:
589-
response = self.session.get(url, headers=headers, allow_redirects=self.args.allow_redirects)
590-
except ConnectionError as e:
599+
response = self.session.get(url, headers=self._fill_headers(), allow_redirects=self.args.allow_redirects)
600+
except ConnectionError as ex:
591601
self.output.write_log('Connection error while quering %s' % url, logging.ERROR)
592-
exception = e
593-
except HTTPError as e:
602+
exception = ex
603+
except HTTPError as ex:
594604
self.output.write_log('HTTP error while quering %s' % url, logging.ERROR)
595-
exception = e
596-
except Timeout as e:
605+
exception = ex
606+
except Timeout as ex:
597607
self.output.write_log('Timeout while quering %s' % url, logging.ERROR)
598-
exception = e
599-
except TooManyRedirects as e:
608+
exception = ex
609+
except TooManyRedirects as ex:
600610
self.output.write_log('Too many redirects while quering %s' % url, logging.ERROR)
601-
exception = e
602-
except Exception as e:
611+
exception = ex
612+
except Exception as ex:
603613
self.output.write_log('Unknown exception while quering %s' % url, logging.ERROR)
604-
exception = e
614+
exception = ex
605615

606616
self.output.write(worker_id, url, response, exception)
607617
return response if exception is None else None

0 commit comments

Comments
 (0)