Fixed issue #2321 - IMAP fetch stops because of request timeout
This commit is contained in:
parent
13b3b841d5
commit
ea318fb695
1 changed files with 61 additions and 23 deletions
|
@ -94,32 +94,40 @@ example
|
||||||
Rails.logger.info "fetching imap (#{options[:host]}/#{options[:user]} port=#{port},ssl=#{ssl},starttls=#{starttls},folder=#{folder},keep_on_server=#{keep_on_server})"
|
Rails.logger.info "fetching imap (#{options[:host]}/#{options[:user]} port=#{port},ssl=#{ssl},starttls=#{starttls},folder=#{folder},keep_on_server=#{keep_on_server})"
|
||||||
|
|
||||||
# on check, reduce open_timeout to have faster probing
|
# on check, reduce open_timeout to have faster probing
|
||||||
timeout = 45
|
@timeout = 45
|
||||||
if check_type == 'check'
|
if check_type == 'check'
|
||||||
timeout = 6
|
@timeout = 6
|
||||||
end
|
end
|
||||||
|
|
||||||
Timeout.timeout(timeout) do
|
timeout do
|
||||||
@imap = ::Net::IMAP.new(options[:host], port, ssl, nil, false)
|
@imap = ::Net::IMAP.new(options[:host], port, ssl, nil, false)
|
||||||
if starttls
|
if starttls
|
||||||
@imap.starttls()
|
@imap.starttls()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@imap.login(options[:user], options[:password])
|
timeout do
|
||||||
|
@imap.login(options[:user], options[:password])
|
||||||
|
end
|
||||||
|
|
||||||
# select folder
|
timeout do
|
||||||
@imap.select(folder)
|
# select folder
|
||||||
|
@imap.select(folder)
|
||||||
|
end
|
||||||
|
|
||||||
# sort messages by date on server (if not supported), if not fetch messages via search (first in, first out)
|
# sort messages by date on server (if not supported), if not fetch messages via search (first in, first out)
|
||||||
filter = ['ALL']
|
filter = ['ALL']
|
||||||
if keep_on_server && check_type != 'check' && check_type != 'verify'
|
if keep_on_server && check_type != 'check' && check_type != 'verify'
|
||||||
filter = %w[NOT SEEN]
|
filter = %w[NOT SEEN]
|
||||||
end
|
end
|
||||||
begin
|
|
||||||
message_ids = @imap.sort(['DATE'], filter, 'US-ASCII')
|
message_ids = nil
|
||||||
rescue
|
timeout do
|
||||||
message_ids = @imap.search(filter)
|
begin
|
||||||
|
message_ids = @imap.sort(['DATE'], filter, 'US-ASCII')
|
||||||
|
rescue
|
||||||
|
message_ids = @imap.search(filter)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# check mode only
|
# check mode only
|
||||||
|
@ -131,7 +139,10 @@ example
|
||||||
# check messages
|
# check messages
|
||||||
message_ids.each do |message_id|
|
message_ids.each do |message_id|
|
||||||
|
|
||||||
message_meta = @imap.fetch(message_id, ['RFC822.HEADER'])[0].attr
|
message_meta = nil
|
||||||
|
timeout do
|
||||||
|
message_meta = @imap.fetch(message_id, ['RFC822.HEADER'])[0].attr
|
||||||
|
end
|
||||||
|
|
||||||
# check how many content messages we have, for notice used
|
# check how many content messages we have, for notice used
|
||||||
header = message_meta['RFC822.HEADER']
|
header = message_meta['RFC822.HEADER']
|
||||||
|
@ -158,7 +169,10 @@ example
|
||||||
# check for verify message
|
# check for verify message
|
||||||
message_ids.each do |message_id|
|
message_ids.each do |message_id|
|
||||||
|
|
||||||
message_meta = @imap.fetch(message_id, ['ENVELOPE'])[0].attr
|
message_meta = nil
|
||||||
|
timeout do
|
||||||
|
message_meta = @imap.fetch(message_id, ['ENVELOPE'])[0].attr
|
||||||
|
end
|
||||||
|
|
||||||
# check if verify message exists
|
# check if verify message exists
|
||||||
subject = message_meta['ENVELOPE'].subject
|
subject = message_meta['ENVELOPE'].subject
|
||||||
|
@ -166,8 +180,10 @@ example
|
||||||
next if subject !~ /#{verify_string}/
|
next if subject !~ /#{verify_string}/
|
||||||
|
|
||||||
Rails.logger.info " - verify email #{verify_string} found"
|
Rails.logger.info " - verify email #{verify_string} found"
|
||||||
@imap.store(message_id, '+FLAGS', [:Deleted])
|
timeout do
|
||||||
@imap.expunge()
|
@imap.store(message_id, '+FLAGS', [:Deleted])
|
||||||
|
@imap.expunge()
|
||||||
|
end
|
||||||
disconnect
|
disconnect
|
||||||
return {
|
return {
|
||||||
result: 'ok',
|
result: 'ok',
|
||||||
|
@ -189,7 +205,10 @@ example
|
||||||
count += 1
|
count += 1
|
||||||
Rails.logger.info " - message #{count}/#{count_all}"
|
Rails.logger.info " - message #{count}/#{count_all}"
|
||||||
|
|
||||||
message_meta = @imap.fetch(message_id, ['RFC822.SIZE', 'ENVELOPE', 'FLAGS', 'INTERNALDATE'])[0]
|
message_meta = nil
|
||||||
|
timeout do
|
||||||
|
message_meta = @imap.fetch(message_id, ['RFC822.SIZE', 'ENVELOPE', 'FLAGS', 'INTERNALDATE'])[0]
|
||||||
|
end
|
||||||
|
|
||||||
# ignore to big messages
|
# ignore to big messages
|
||||||
info = too_big?(message_meta, count, count_all)
|
info = too_big?(message_meta, count, count_all)
|
||||||
|
@ -205,19 +224,28 @@ example
|
||||||
next if already_imported?(message_id, message_meta, count, count_all, keep_on_server, channel)
|
next if already_imported?(message_id, message_meta, count, count_all, keep_on_server, channel)
|
||||||
|
|
||||||
# delete email from server after article was created
|
# delete email from server after article was created
|
||||||
msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
|
msg = nil
|
||||||
|
timeout do
|
||||||
|
msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
|
||||||
|
end
|
||||||
next if !msg
|
next if !msg
|
||||||
|
|
||||||
process(channel, msg, false)
|
process(channel, msg, false)
|
||||||
if !keep_on_server
|
|
||||||
@imap.store(message_id, '+FLAGS', [:Deleted])
|
timeout do
|
||||||
else
|
if !keep_on_server
|
||||||
@imap.store(message_id, '+FLAGS', [:Seen])
|
@imap.store(message_id, '+FLAGS', [:Deleted])
|
||||||
|
else
|
||||||
|
@imap.store(message_id, '+FLAGS', [:Seen])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
count_fetched += 1
|
count_fetched += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if !keep_on_server
|
if !keep_on_server
|
||||||
@imap.expunge()
|
timeout do
|
||||||
|
@imap.expunge()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
disconnect
|
disconnect
|
||||||
if count.zero?
|
if count.zero?
|
||||||
|
@ -234,7 +262,9 @@ example
|
||||||
def disconnect
|
def disconnect
|
||||||
return if !@imap
|
return if !@imap
|
||||||
|
|
||||||
@imap.disconnect()
|
timeout do
|
||||||
|
@imap.disconnect()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -273,7 +303,9 @@ returns
|
||||||
return false if ticket.preferences[:channel_id] != channel[:id]
|
return false if ticket.preferences[:channel_id] != channel[:id]
|
||||||
end
|
end
|
||||||
|
|
||||||
@imap.store(message_id, '+FLAGS', [:Seen])
|
timeout do
|
||||||
|
@imap.store(message_id, '+FLAGS', [:Seen])
|
||||||
|
end
|
||||||
Rails.logger.info " - ignore message #{count}/#{count_all} - because message message id already imported"
|
Rails.logger.info " - ignore message #{count}/#{count_all} - because message message id already imported"
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
@ -296,4 +328,10 @@ returns
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def timeout
|
||||||
|
Timeout.timeout(@timeout) do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue