WebClient DownloadFileAsync throwing random (504) Gateway Timeout - c#

I am facing a mysterious issue at one of my client site.
I am downloading a file from AWS S3 location using a signed url having expiration of 30 minutes. Although it works fine everywhere, one client has reported (504) Gateway Timeout issue while downloading file and that too comes once in a blue moon.
I am using the below VB.Net code to download the file
Imports System.IO
Imports System.Net
Imports System.Threading
Public Class DownloadFile
Dim _downloadCompletedEvent As ManualResetEventSlim
Dim _cts As New CancellationTokenSource()
Dim _maxWaitTimeForFileDownload As TimeSpan = TimeSpan.FromMinutes(15)
Dim _lastProgressedChangedTime As DateTime = DateTime.MinValue
Private Sub DownloadFile(ByVal url As String)
Console.WriteLine("File download started...")
_downloadCompletedEvent = New ManualResetEventSlim(False)
Using client = New Net.WebClient()
AddHandler client.DownloadProgressChanged, AddressOf wc_DownloadProgressChanged
AddHandler client.DownloadFileCompleted, AddressOf wc_DownloadFileCompleted
Dim urlIdentifier = New Uri(url)
Dim temp_filepath = Path.GetTempFileName
Try
'DownloadFile will only show progress in Async mode so using ManualResetEventSlim to wait
client.DownloadFileAsync(urlIdentifier, temp_filepath)
Dim isDownloadSuccessful As Boolean = _downloadCompletedEvent.Wait(_maxWaitTimeForFileDownload, _cts.Token)
If Not isDownloadSuccessful Then
'Timeout occured
Dim msg = String.Format("Unable to download File in {0} minutes. Seems to be some issue in internet connectivity so aborting download.", _maxWaitTimeForFileDownload.Minutes)
Console.WriteLine(msg)
End If
Finally
_downloadCompletedEvent.Dispose()
client.CancelAsync()
End Try
End Using
End Sub
Private Sub wc_DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs)
Dim progressChangedTime As DateTime = DateTime.Now
'Show progress at a defined interval
If (progressChangedTime - _lastProgressedChangedTime).TotalSeconds > 2 Then
_lastProgressedChangedTime = progressChangedTime
Dim dataReceivedInMb = Math.Round((e.BytesReceived / 1024 / 1024), 2)
Console.WriteLine("Data Received: " & dataReceivedInMb.ToString())
End If
End Sub
Private Sub wc_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs)
If e.Error IsNot Nothing Then
Console.WriteLine("File download failed. Error occured while downloading file.")
Console.WriteLine("Error: " & e.Error.Message)
Else
Console.WriteLine("100% | File download completed.")
End If
_downloadCompletedEvent.Set()
End Sub
Public Sub CancelDownload()
_cts.Cancel()
End Sub
End Class
By looking at the logs below, I can see that no sooner than it started, it throws error (504) Gateway Timeout.
12:17:00.300 (INFO) File download started...
12:17:00.341 (WARNING) File download failed. Error occured while downloading file.
12:17:00.341 (WARNING) Unable to download file in 0.0413338 seconds. Error: The remote server returned an error: (504) Gateway Timeout.
Moreover, I have started continous ping at the client site but did not observe any packet drop; thus, there is no problem with the internet connection. Besides, downloading directly from S3, so there should not be any problem from the server side.
I am bewildered that in which case this error could happen?
Within 41ms DownloadFileAsync has stopped downloading the file. I am quite sure that this method would be having some mechanism to handle minor internet glitches.
What should I do to find out the root cause of this issue?

You can try this options where the first send headers to AWS to keep connection alive.
The second option make .NET to negotiate TLS in 1.1 or 1.2 (maybe AWS refuse connections on TLS 1.0)
After that if you have the same this issue you need to check Proxy, Firewall or other around network.
Using client = ...
client.Headers.Add("Connection", "Keep-Alive")
System.Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls11 Or Net.SecurityProtocolType.Tls12

Related

Outlook calendars send and receive

Is there a way to synchronize Outlook local shared calendars with their Exchange vesion programatically?
I tried Namespace.SendAndReceive() but it seems it doesn't affect calendars...
Is there something I miss or is it just impossible ?
I would like to perform a "send" from my local shared calendar folder to his server folder.
(I know it is possible to work directly on the server version by unchecking "Download shared calendar" as showed here but I can't do this way)
EDIT :
Why do I try to force sync?
In my add-in, users create new appointments in a shared calendar, and then lauch a function that makes a HTTP request to a script working with EWS to get this exchange calendar. But as the new appointments aren't sent, the script communicating with EWS don't get new appointments.
I found out the "update folder" button in Send/Receive sends the folder to exchange server but looking at the folder object I don't find how to do it programatically...
I finally found a way to synchronize Outlook application's locally shared calendars with the exchange server version (actually it does a "send").
The VB.NET code below progratically opens each shared calendar and then simulate the click on "update calendar" button.
Dim app As New Outlook.Application
Dim ns As Outlook.NameSpace
Dim objExpl As Outlook.Explorer
Dim recip As Outlook.Recipient
Dim olPane As Outlook.NavigationPane
Dim olModule As Outlook.NavigationModule
Dim olGroup As Outlook.NavigationGroup
Dim navFoldersCount As Integer
ns = app.GetNamespace("MAPI")
objExpl = app.ActiveExplorer
For k = 1 To ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar).Folders.Count
Try
'Try catch allows to exclude non-shared calendars to work only with share ones
recip = ns.CreateRecipient(ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar).Folders.Item(k).Name)
recip.Resolve()
If recip.Resolved Then
objExpl.CurrentFolder = ns.GetSharedDefaultFolder(recip, Outlook.OlDefaultFolders.olFolderCalendar)
'accessing to the shared calendars creates their "Calendar - xxx#xxx.xxx" clone.
If Not objExpl Is Nothing Then
'Simulate the click on "UpdateFolder button
objExpl.CommandBars.ExecuteMso("UpdateFolder")
End If
End If
Catch
End Try
Next
olPane = ns.Application.ActiveExplorer.NavigationPane
olModule = olPane.Modules.GetNavigationModule(Outlook.OlNavigationModuleType.olModuleCalendar)
olGroup = olModule.NavigationGroups.GetDefaultNavigationGroup(Outlook.OlGroupType.olPeopleFoldersGroup)
'Removing calendar clones from the navigation pane
navFoldersCount = olGroup.NavigationFolders.Count
For i = navFoldersCount To 1 Step -1
If (olGroup.NavigationFolders.Item(i).DisplayName.Contains("Calendar - ")) Then
olGroup.NavigationFolders.Remove(olGroup.NavigationFolders.Item(i))
End If
Next

Trigger .exe upon receiving email from sender

I've written a C# application with .net framework. The purpose is to request data from an online spreadsheet app, do stuff with it, then send back updated data.
I think the best way to trigger the exe would be to use webhooks/callbacks, but I gather this would require runnning my program on a web sever with an external IP address.
Rather than periodically polling the spreadsheet app I would like the app to send emails to a specified account upon certain data changes. Upon receiving the email, VBA code checks that the email is from the app then runs the executable.
To run exe on receipt of email:
Private Sub Application_NewMail()
Dim path As String
Dim shl As Variant
path = "C:\Users\***\Desktop\SmartPlugin.exe"
shl = Shell(path, 1)
End Sub
How do I check the sender? The examples I found online loop through all emails but what I'm after is a method of returning the last email received.
Use Application.NewMailEx event instead - it passes the entry id of the new message as the parameter. Use that entry id to call Application.Session.GetItemfromID.
Got it working.
Private Sub Application_NewMail()
Dim objN As NameSpace
Dim objF As MAPIFolder
Set objN = GetNamespace("MAPI")
Set objF = objN.GetDefaultFolder(olFolderInbox)
Set mlItems = objF.Items
mlItems.Sort "CreationTime", True
Set mlItem = mlItems.Item(1)
Dim path As String
Dim shl As Variant
Dim sndString As String
sndString = CStr(mlItem.SenderName)
If InStr(1, sndString, "SmartSheet", vbTextCompare) > 0 Then
path = "C:\Users\Alex Rose\Desktop\SmartPlugin.exe"
shl = Shell(path, 1)
End If
End Sub

Send/Receive http request/response from MS Word addin

I'm trying to write a add-in for MS Word. Is it possible to for a MS Word add-in to listen on specific port and send/receive http request/response? Will there be a firewall between MS Word and an application that is running outside of Word?
An Office AddIn can make HTTP requests without triggering a firewall issue (using Windows Firewall in its default configuration), but it can't listen without triggering firewall issues.
If you're making requests from inside word to a service you have living outside of Word that service may encounter Firewall issues while listening on a port.
Windows Firewall, by default blocks incoming requests. Windows Firewall is included with all versions of Windows XP SP2 or later.
See MSDN for more.
Additionally,
Function GetRateCBR(dDate As Date) As String
Dim sUrlRequest, intTry As Integer, _
strResponse As String
Dim oXMLHTTP As Object
Dim oResponse As Object
Set oResponse = CreateObject("MSXML2.DOMDocument")
'Build URL for request
sUrlRequest = _
"http://www.cbr.ru/scripts/XML_dynamic.asp?date_req1=" _
& Format(dDate, "dd.mm.yyyy") _
& "&date_req2=" & Format(dDate, "dd.mm.yyyy") _
& "&VAL_NM_RQ=" & "R01235"
'Try to get a response, 10 tries
intTry = 1
Do Until intTry > 10
Set oXMLHTTP = CreateObject("MSXML2.XMLHTTP")
oXMLHTTP.Open "GET", sUrlRequest, False
oXMLHTTP.send
If oXMLHTTP.Status = 200 Then
If oResponse.loadXML(oXMLHTTP.responseText) Then _
Exit Do
End If
If Not oXMLHTTP Is Nothing Then oXMLHTTP.abort: _
Set oXMLHTTP = Nothing
DoEvents
intTry = intTry + 1
Loop
If Not oXMLHTTP Is Nothing Then oXMLHTTP.abort: _
Set oXMLHTTP = Nothing
If intTry <= 10 Then
GetRateCBR = Mid$(oResponse.Text, 3)
End If
If Not oResponse Is Nothing Then oResponse.abort: _
Set oResponse = Nothing
End Function
Example via Access Blog

Getting Dynamic Data in Lua

I have built an Instrumentation Cluster with the NVIDIA UI Composer Studio.
To control animations it uses the Lua Scripting Language. Now I'm really new to Lua and my question is the following:
I've got the following Code sequence in Lua which controls my Speedometer:
self.vehicleSpeedData = {} -- A lot of Values are put in here
function self.speedSim( inFrame, theController )
local timeInSec, dummy
timeInSec, dummy = getElapsedTime()
-- data based on 60fps
actualFrameNumber = math.floor(timeInSec * 60)
local theSample = ((actualFrameNumber-1) % #self.vehicleSpeedData) + 1
theController.value = self.vehicleSpeedData[theSample] *0.06
end
The array in this example is empty. So as you can see, the function reads out the Values of the Array.
But what I need is, that I can get this Data from an external Source (Such as RS232 or CAN Simulation) ... What I want to try is, if I can put Data from C# for example to that Lua Script.
It is hard do explain what I exactly want. My idea is that this Lua Script above listens and reads Data which I dynamically read in C# from my Data Source.
Thanks a lot for your help. This work is for my Bachelors Degree and I'm stuck at this point a long time and I'm nearly out of ideas.
It all kind of depends on what that Nvidia thing exposes to the user (in terms of API, and Lua base libraries).
Assuming it is available, you can use io.read to read in a datafile (say a csv) from another source, then parse it yourself into your table. If you can preprocess the file to have a valid Lua syntax (eg prepend a return {, have values separated by , , and end with a }, you could directly load the string with loadstring).
If they allow you to, you could use external libraries for interfacing with RS232, Excel, sockets, whatever.
PS: it's Lua not LUA (not an acronym, but the Portuguese noun for Moon ;))
Edit: example mkfifo
so in Linux it goes like this: make a fifo with mkfifo fff and feed it something echo ' '> fff to prevent Lua from blocking.
In Lua:
fh=io.open('fff','rb')
while true do
res = fh:read()
if res then
print(res)
end
end
Whatever cat into fff (eg cat 10 > fff) will come out in Lua. this way you can read out any available values and use them at each run of your function.
Another option is using standard input, but I'm not sure whether this composer thing lets you.
I hope your Bachelor's Degree turned out alright, what with this response being 1.5 years too late. :) Nonetheless:
As a member of the UI Composer team and a fellow Lua scripter, one technique I use often for streaming external data and events asynchronously into the runtime is to use the Lua Socket library. I have written an abstraction layer on top of it as a UIC behavior.
-- Expected message structure:
-- "<numbytes>,<optionaltag>\n<bytesofmessage>"
-- e.g. "11,simple\nHello World"
-- e.g. "40,\nThis has no tag,\nbut does have a newline"
local ok,socket = pcall(require,'socket')
if not ok then
output("Error loading socket: "..socket)
else
local output = output or print
local sscallbacks = {} -- indexed by simplesocket instance, then tag
SimpleSocket = {}
local SSMeta = {}
SSMeta.__index=SSMeta
function SimpleSocket:server(port,ip,timeout)
return self:create('server',port,ip,timeout)
end
function SimpleSocket:client(port,ip,timeout)
return self:create('client',port,ip,timeout)
end
function SimpleSocket:create(kind,port,ip,timeout)
if not port then port = 51423 end
if not ip then ip = '*' end
if not timeout then timeout = 10 end
local ss = setmetatable({
kind = kind,
ip = ip,
port = port,
timeout = timeout/1000,
queue = {}
},SSMeta)
sscallbacks[ss] = {}
return ss
end
function SSMeta:destroy()
if self.socket then self.socket:close() end
callbacks[self] = nil
end
function SSMeta:onData(callback,tag)
self:setCallback('handler',callback,tag)
end
function SSMeta:toEncode(callback,tag)
self:setCallback('encoder',callback,tag)
end
function SSMeta:toDecode(callback,tag)
self:setCallback('decoder',callback,tag)
end
function SSMeta:setCallback(type,callback,tag)
if not tag then tag = "" end
if not sscallbacks[self][tag] then sscallbacks[self][tag] = {} end
sscallbacks[self][tag][type] = callback
end
function self:onUpdate()
self:sendQueuedMessages()
self:receiveMessages()
end
function SSMeta:createSocket()
output("Creating new "..self.kind.." socket to "..self.ip..":"..self.port)
if self.kind=='server' then
self.socket = assert(socket.bind(self.ip,self.port))
self.socket:settimeout(self.timeout)
else
self.socket = assert(socket.connect(self.ip,self.port))
end
end
-- Attempts to send all messages from the queue
function self:sendQueuedMessages()
for ss,_ in pairs(sscallbacks) do
while ss.queue[1] do
if ss:sendMessage(message[1]) then
table.remove(ss.queue,1)
else
-- don't attempt any later messages, since ordering may be important
return
end
end
end
end
function self:receiveMessages()
for ss,callbacks in pairs(sscallbacks) do
if ss.kind=='client' then
if not ss.socket then ss:createSocket() end
ss.socket:settimeout(0) -- non-blocking for first byte
local char1, err = ss.socket:receive(1)
ss.socket:settimeout(ss.timeout) -- go back to blocking
if not char1 then
-- probably just timed out
else
local header, err = ss.socket:receive('*l')
if not header then
output(err)
else
header = char1..header
local comma = header:find(',')
local bytes = tonumber(header:sub(1,comma-1))
local tag = header:sub(comma+1)
local data,err = ss.socket:receive(bytes)
if not data then
output(err)
else
if callbacks[tag] and callbacks[tag].decoder then
data = callbacks[tag].decoder(data)
elseif callbacks[true] and callbacks[true].decoder then
data = callbacks[true].decoder(data)
end
if callbacks[tag] and callbacks[tag].handler then
callbacks[tag].handler(data)
elseif callbacks[true] and callbacks[true].handler then
callbacks[true].handler(data)
end
end
end
end
end
end
end
function SSMeta:send(data,tag)
return self:sendMessage(self:encodeMessage(data,tag))
end
function SSMeta:ensureSend(data,tag)
local message = self:encodeMessage(data,tag)
if not self:sendMessage(message) then
table.insert(self.queue,message)
end
end
-- Internal only; use send() or ensureSend()
function SSMeta:sendMessage(formattedMessage)
if not self.socket then self:createSocket() end
if not self.client then self.client = self.socket:accept() end
if self.client then
local lastbyte,err = self.client:send(formattedMessage)
if lastbyte then
-- TODO: verify that all bytes were sent
return true
else
output(err)
self.client:close()
self.client = nil
end
else
-- No client connected before the timeout
end
end
function SSMeta:encodeMessage(data,tag)
data = tostring(data)
local callbacks = sscallbacks[self]
if callbacks[tag] and callbacks[tag].encoder then
data = callbacks[tag].encoder(data)
elseif callbacks[true] and callbacks[true].encoder then
data = callbacks[true].encoder(data)
end
return tostring(#data)..","..(tag or "").."\n"..data
end
end
This allows multiple different systems to communicate on the same socket, with different tagged communication, and possibly different encoders/decoders to serialize/deserialize the data.
On the receiving end this is used for example like this:
local ss = require 'SimpleSocket'
local client = ss:client()
client:onData(function(d) print("Client got *: "..d) end,true)

Referenced DLL not declared?

I have added global error handling into my application to catch-all unhandled exceptions. I now just added the functionality to add the bug automatically to my fogbugz account. Now here is my issue.
I added a reference to the dll and also had to add the import declaration for the library. After doing this the code shows no errors. Although as soon as I go to debug the code or build it I get this error:
'BugReport' is not declared. It may be inaccessible due to its protection level.
I am geussing it has to do with some kind of protection? This catch all is in my applicationevents.vb class.
I have tried the same code in another project and it works without error so I know it is not the code. I just don't know what it is? Do I have to change something in my application settings? Here is the code anyways. I replaced the strings with my information for privacy.
Imports FogBugz
Namespace My
' The following events are available for MyApplication:
'
' Startup: Raised when the application starts, before the startup form is created.
' Shutdown: Raised after all application forms are closed. This event is not raised if the application terminates abnormally.
' UnhandledException: Raised if the application encounters an unhandled exception.
' StartupNextInstance: Raised when launching a single-instance application and the application is already active.
' NetworkAvailabilityChanged: Raised when the network connection is connected or disconnected.
Partial Friend Class MyApplication
Private Sub MyApplication_UnhandledException(ByVal _
sender As Object, ByVal e As _
Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs) _
Handles Me.UnhandledException
'TO DO: SET THESE VALUES BEFORE CALLING THIS METHOD!
Dim url As String = "StackOverFlowDemoString"
'example: http://localhost/fogbugz/scoutSubmit.asp
Dim user As String = "StackOverFlowDemoString"
'existing FogBugz User
Dim project As String = "StackOverFlowDemoString"
'existing FogBugz project
Dim area As String = "StackOverFlowDemoString"
'existing FogBugz area
Dim email As String = "StackOverFlowDemoString"
'email address of the customer who reports the bug
Dim defaultMessage As String = "Bug has been submitted. Every bug submitted helps us make this software that much better. We really do appreciate it."
'the message to return to the user if no Scout Message is found for an existing duplicate bug
Dim forceNewBug As Boolean = False
'If set to true, this forces FogBugz to create a new case for this bug, even if a bug with the same description already exists.
'************************************************************************************
'send the bug we created:
BugReport.Submit(url, user, project, area, email, forceNewBug, _
defaultMessage, e.Exception, True, "{0}.{1}.{2}.{3}", True)
' If the user clicks No, then exit.
e.ExitApplication = _
MessageBox.Show(e.Exception.Message & _
vbCrLf & "Oops! It looks like we have encountered a bug. A bug report has been sent to the developers, so they can have it fixed in a jiffy. Continue?", "An Error has occured.", _
MessageBoxButtons.YesNo, _
MessageBoxIcon.Question) _
= DialogResult.No
End Sub
End Class
End Namespace
The "protection level" refers to the access modifier on your BugReport class.
If you declare a class as Friend (Internal in C#), it is accessible to other classes in the same assembly (.dll).
When you attempt to reference that class from another project, it is not accessible.
You need to change Friend to Public.

Categories

Resources