2017-10-12 5 views
0

メトリクス収集の目的で毎週実行されるQualysのスキャン結果をフェッチするスクリプトを作成しました。実行時にPyCurlリクエストが無限にハングアップ

このスクリプトの最初の部分は、さらに処理するために過去1週間に実行された各スキャンの参照リストを取得することです。

この問題は完全にうまくいくものの、それ以外のときにはc.perform()行にハングすることがあります。これは、手動でスクリプトを実行するときに、スクリプトが機能するまで再実行するだけで管理することができます。しかし、私はこれを毎週スケジュールされたタスクとして手動で操作することなく実行することを検討しています。

ハングアップが発生したことを検出し、動作するまでPyCurlリクエストを再送信することができますか?

私はc.TIMEOUTc.CONNECTTIMEOUTオプションを設定しようとしましたが、これらは有効ではないようです。また、例外がスローされないので、try-exceptブロックに入れるだけでは飛ばない。

問題になっている機能は以下の通りです:

# Retrieve a list of all scans conducted in the past week 
# Save this to refs_raw.txt 
def getScanRefs(usr, pwd): 

    print("getting scan references...") 

    with open('refs_raw.txt','wb') as refsraw: 
     today = DT.date.today() 
     week_ago = today - DT.timedelta(days=7) 
     strtoday = str(today) 
     strweek_ago = str(week_ago) 

     c = pycurl.Curl() 

     c.setopt(c.URL, 'https://qualysapi.qualys.eu/api/2.0/fo/scan/?action=list&launched_after_datetime=' + strweek_ago + '&launched_before_datetime=' + strtoday) 
     c.setopt(c.HTTPHEADER, ['X-Requested-With: pycurl', 'Content-Type: text/xml']) 
     c.setopt(c.USERPWD, usr + ':' + pwd) 
     c.setopt(c.POST, 1) 
     c.setopt(c.PROXY, 'companyproxy.net:8080') 
     c.setopt(c.CAINFO, certifi.where()) 
     c.setopt(c.SSL_VERIFYPEER, 0) 
     c.setopt(c.SSL_VERIFYHOST, 0) 
     c.setopt(c.CONNECTTIMEOUT, 3) 
     c.setopt(c.TIMEOUT, 3) 

     refsbuffer = BytesIO() 
     c.setopt(c.WRITEDATA, refsbuffer) 
     c.perform() 

     body = refsbuffer.getvalue() 
     refsraw.write(body) 
     c.close() 

    print("Got em!") 
+0

変数に名前を付けるときに、私はnothingatall under_scores、私はキャメルケースの恐ろしいミックスを使用していたことを今実現し、そして。あまりにも厳しく裁かないでください。 –

答えて

0

それがより長いために行く場合、私は、別のプロセスでAPI呼び出しを起動するmultiprocessingを使用して別のプロセスを起動殺害し、再起動することで、問題を自分自身を固定しました5秒。それほど美しいものではありませんが、クロスプラットフォームです。 は、* nixでしか動作しません。より具体的には、the signal library、特にSIGALRMを参照してください。

以下のコード:

# As this request for scan references sometimes hangs it will be run in a separate thread here 
# This will be terminated and relaunched if no response is received within 5 seconds 
def performRequest(usr, pwd): 
    today = DT.date.today() 
    week_ago = today - DT.timedelta(days=7) 
    strtoday = str(today) 
    strweek_ago = str(week_ago) 

    c = pycurl.Curl() 

    c.setopt(c.URL, 'https://qualysapi.qualys.eu/api/2.0/fo/scan/?action=list&launched_after_datetime=' + strweek_ago + '&launched_before_datetime=' + strtoday) 
    c.setopt(c.HTTPHEADER, ['X-Requested-With: pycurl', 'Content-Type: text/xml']) 
    c.setopt(c.USERPWD, usr + ':' + pwd) 
    c.setopt(c.POST, 1) 
    c.setopt(c.PROXY, 'companyproxy.net:8080') 
    c.setopt(c.CAINFO, certifi.where()) 
    c.setopt(c.SSL_VERIFYPEER, 0) 
    c.setopt(c.SSL_VERIFYHOST, 0) 

    refsBuffer = BytesIO() 
    c.setopt(c.WRITEDATA, refsBuffer) 
    c.perform() 
    c.close() 
    body = refsBuffer.getvalue() 
    refsraw = open('refs_raw.txt', 'wb') 
    refsraw.write(body) 
    refsraw.close() 

# Retrieve a list of all scans conducted in the past week 
# Save this to refs_raw.txt 
def getScanRefs(usr, pwd): 

    print("Getting scan references...") 

    # Occasionally the request will hang infinitely. Launch in separate method and retry if no response in 5 seconds 
    success = False 
    while success != True: 
     sendRequest = multiprocessing.Process(target=performRequest, args=(usr, pwd)) 
     sendRequest.start() 

     for seconds in range(5): 
      print("...") 
      time.sleep(1) 

     if sendRequest.is_alive(): 
      print("Maximum allocated time reached... Resending request") 
      sendRequest.terminate() 
      del sendRequest 
     else: 
      success = True 

    print("Got em!") 
関連する問題