浏览代码

AWS metadata service connection timeout is by default one second and AWS_METADATA_SERVICE_TIMEOUT is respected

Source commit: 59fc680d0aaab81fc29e111bca22267edf7df510
Martin Prikryl 9 月之前
父节点
当前提交
5ed3336f29
共有 5 个文件被更改,包括 25 次插入3 次删除
  1. 14 0
      libs/neon/src/ne_socket.c
  2. 2 0
      source/core/Http.cpp
  3. 2 0
      source/core/Http.h
  4. 4 2
      source/core/S3FileSystem.cpp
  5. 3 1
      source/core/WebDAVFileSystem.cpp

+ 14 - 0
libs/neon/src/ne_socket.c

@@ -137,12 +137,16 @@ typedef struct in_addr ne_inet_addr;
 #endif
 
 /* "Be Conservative In What You Build". */
+#ifdef WINSCP
+#define USE_NONBLOCKING_CONNECT
+#else
 #if defined(HAVE_FCNTL) && defined(O_NONBLOCK) && defined(F_SETFL) \
     && defined(HAVE_GETSOCKOPT) && defined(SO_ERROR) \
     && defined(HAVE_SOCKLEN_T) && defined(SOL_SOCKET) \
     && defined(EINPROGRESS)
 #define USE_NONBLOCKING_CONNECT
 #endif
+#endif
 
 #include "ne_internal.h"
 #include "ne_utils.h"
@@ -1345,6 +1349,10 @@ static int timed_connect(ne_socket *sock, int fd,
     if (sock->cotimeout) {
         int errnum, flags;
 
+        #ifdef WINSCP
+        flags = 1;
+        ioctlsocket(fd, FIONBIO, &flags);
+        #else
         /* Get flags and then set O_NONBLOCK. */
         flags = fcntl(fd, F_GETFL);
         if (flags & O_NONBLOCK) {
@@ -1356,6 +1364,7 @@ static int timed_connect(ne_socket *sock, int fd,
             set_strerror(sock, errno);
             return NE_SOCK_ERROR;
         }
+        #endif
         
         ret = raw_connect(fd, sa, salen);
         if (ret == -1) {
@@ -1394,10 +1403,15 @@ static int timed_connect(ne_socket *sock, int fd,
         }
         
         /* Reset to old flags; fail on error if no previous error. */
+        #ifdef WINSCP
+        flags = 0;
+        ioctlsocket(fd, FIONBIO, &flags);
+        #else
         if (fcntl(fd, F_SETFL, flags) == -1 && !ret) {
             set_strerror(sock, errno);
             ret = NE_SOCK_ERROR;
         }
+        #endif
     } else 
 #endif /* USE_NONBLOCKING_CONNECT */
     {

+ 2 - 0
source/core/Http.cpp

@@ -18,6 +18,7 @@ THttp::THttp()
   FOnDownload = NULL;
   FOnError = NULL;
   FResponseLimit = -1;
+  FConnectTimeout = 0;
 
   FRequestHeaders = NULL;
   FResponseHeaders = new TStringList();
@@ -72,6 +73,7 @@ void THttp::SendRequest(const char * Method, const UnicodeString & Request)
     {
       TProxyMethod ProxyMethod = ProxyHost.IsEmpty() ? ::pmNone : pmHTTP;
       InitNeonSession(NeonSession, ProxyMethod, ProxyHost, ProxyPort, UnicodeString(), UnicodeString(), NULL);
+      ne_set_connect_timeout(NeonSession, ConnectTimeout);
 
       if (IsTls)
       {

+ 2 - 0
source/core/Http.h

@@ -37,6 +37,7 @@ public:
   __property THttpDownloadEvent OnDownload = { read = FOnDownload, write = FOnDownload };
   __property THttpErrorEvent OnError = { read = FOnError, write = FOnError };
   __property UnicodeString Certificate = { read = FCertificate, write = FCertificate };
+  __property int ConnectTimeout = { read = FConnectTimeout, write = FConnectTimeout };
 
 private:
   UnicodeString FURL;
@@ -52,6 +53,7 @@ private:
   TStrings * FRequestHeaders;
   TStrings * FResponseHeaders;
   UnicodeString FCertificate;
+  int FConnectTimeout;
 
   static int NeonBodyReader(void * UserData, const char * Buf, size_t Len);
   int NeonBodyReaderImpl(const char * Buf, size_t Len);

+ 4 - 2
source/core/S3FileSystem.cpp

@@ -183,11 +183,12 @@ TStrings * GetS3Profiles()
   return Result.release();
 }
 //---------------------------------------------------------------------------
-static UnicodeString ReadUrl(const UnicodeString & Url)
+static UnicodeString ReadUrl(const UnicodeString & Url, int ConnectTimeout = 0)
 {
   std::unique_ptr<THttp> Http(new THttp());
   Http->URL = Url;
   Http->ResponseLimit = BasicHttpResponseLimit;
+  Http->ConnectTimeout = ConnectTimeout;
   Http->Get();
   return Http->Response.Trim();
 }
@@ -315,7 +316,8 @@ static UnicodeString GetS3ConfigValue(
         UnicodeString SecurityCredentialsUrl = AWSMetadataService + L"iam/security-credentials/";
 
         AppLogFmt(L"Retrieving AWS security credentials from %s", (SecurityCredentialsUrl));
-        S3SecurityProfile = ReadUrl(SecurityCredentialsUrl);
+        int ConnectTimeout = StrToIntDef(GetEnvironmentVariable(L"AWS_METADATA_SERVICE_TIMEOUT"), 1);
+        S3SecurityProfile = ReadUrl(SecurityCredentialsUrl, ConnectTimeout);
 
         if (S3SecurityProfile.IsEmpty())
         {

+ 3 - 1
source/core/WebDAVFileSystem.cpp

@@ -321,7 +321,9 @@ void __fastcall TWebDAVFileSystem::InitSession(TSessionContext * SessionContext,
 
   ne_set_read_timeout(Session, Data->Timeout);
 
-  ne_set_connect_timeout(Session, Data->Timeout);
+  // The ne_set_connect_timeout was called here previously, but as neon does not support non-blocking
+  // connection on Windows, it was noop.
+  // Restore the call once ours non-blocking connection implementation proves working.
 
   ne_set_session_private(Session, SESSION_CONTEXT_KEY, SessionContext);