MicrosoftDocs / azure-docs

Open source documentation of Microsoft Azure
https://docs.microsoft.com/azure
Creative Commons Attribution 4.0 International
10.29k stars 21.47k forks source link

Document Enhancement Proposal: Resolving WinINet API Error 12031 (ERROR_INTERNET_CONNECTION_RESET) in VBA for Uploading Files to Azure Blob Storage #124846

Open S-Venkatesan-326 opened 1 day ago

S-Venkatesan-326 commented 1 day ago

Overview

This enhancement provides a step-by-step guide for resolving the common error ERROR_INTERNET_CONNECTION_RESET (error code 12031) encountered while uploading files to Azure Blob Storage using the WinINet API in VBA. The guide will help users address the issues that arise with the HttpSendRequestW function, offering a clear approach to resolve connection resets and successfully upload files to Azure Blob Storage.

Enhancement Details

The solution focuses on uploading files to Azure Blob Storage using the WinINet API, while providing a structured method to troubleshoot and resolve common errors such as ERROR_INTERNET_CONNECTION_RESET.

Steps to Resolve Error 12031 and Upload Files to Azure Blob Storage Using VBA

1. Prerequisites:

2. Ensure Correct Headers:

One common cause of the ERROR_INTERNET_CONNECTION_RESET error is improperly set headers in the HttpSendRequestW function. Double-check that the correct headers, including Content-Type and x-ms-blob-type, are used when making the request.

3. Declare Required WinINet Functions in VBA:

You can use the following VBA declarations to interact with WinINet functions:

Private Declare PtrSafe Function InternetOpenA Lib "wininet.dll" ( _
    ByVal sAgent As String, ByVal lAccessType As Long, _
    ByVal sProxyName As String, ByVal sProxyBypass As String, _
    ByVal lFlags As Long) As Long

Private Declare PtrSafe Function InternetConnectA Lib "wininet.dll" ( _
    ByVal hInternet As Long, ByVal sServerName As String, _
    ByVal nServerPort As Integer, ByVal sUserName As String, _
    ByVal sPassword As String, ByVal lService As Long, _
    ByVal lFlags As Long, ByVal lContext As Long) As Long

Private Declare PtrSafe Function HttpOpenRequestA Lib "wininet.dll" ( _
    ByVal hConnect As Long, ByVal sVerb As String, _
    ByVal sObjectName As String, ByVal sVersion As String, _
    ByVal sReferrer As String, ByVal sAcceptTypes As String, _
    ByVal lFlags As Long, ByVal lContext As Long) As Long

Private Declare PtrSafe Function HttpSendRequestA Lib "wininet.dll" ( _
    ByVal hRequest As Long, ByVal sHeaders As String, _
    ByVal lHeadersLength As Long, ByVal sOptional As Any, _
    ByVal lOptionalLength As Long) As Long

Private Declare PtrSafe Function InternetCloseHandle Lib "wininet.dll" ( _
    ByVal hInternet As Long) As Long

Const INTERNET_FLAG_SECURE = &H800000` 

4. Upload File Using VBA with Correct Headers:

Ensure the correct setup for headers and the file path. Here’s an example of how to upload a file using the WinINet API:

Sub UploadFileToAzureBlob()
    Dim hInternetSession As Long
    Dim hConnect As Long
    Dim hRequest As Long
    Dim fileBytes() As Byte
    Dim filePath As String
    Dim sasToken As String
    Dim blobName As String
    Dim serverName As String
    Dim requestPath As String
    Dim result As Long
    Dim header As String
    Dim lastError As Long

    ' Define the file path, Azure Blob Storage URL, SAS token, and blob name '
    filePath = "C:\Users\Downloads\test.png" 
    sasToken = "sv=2022-11-02&ss=bfqt&srt=sco&sp=rwdlacupiytfx&se=2024-10-07T15:35:17Z&st=2024-10-07T07:35:17Z&spr=https&sig=redacted" 
    blobName = "data.png" 
    serverName = "<storage account name>.blob.core.windows.net"
    requestPath = "/<container name>/" & blobName & "?" & sasToken

    fileBytes = ReadFileToBytes(filePath)

    hInternetSession = InternetOpenA("AzureUploadAgent", 1, vbNullString, vbNullString, 0)

    hConnect = InternetConnectA(hInternetSession, serverName, 443, vbNullString, vbNullString, 3, 0, 0)

    hRequest = HttpOpenRequestA(hConnect, "PUT", requestPath, "HTTP/1.1", vbNullString, vbNullString, INTERNET_FLAG_SECURE, 0)

    header = "Content-Type: application/octet-stream" & vbCrLf & "x-ms-blob-type: BlockBlob" & vbCrLf

    result = HttpSendRequestA(hRequest, header, Len(header), VarPtr(fileBytes(1)), UBound(fileBytes))

    If result = 0 Then
        lastError = Err.LastDllError
        MsgBox "Upload failed! Error: " & lastError
    Else
        MsgBox "Upload succeeded!"
    End If

    InternetCloseHandle hRequest
    InternetCloseHandle hConnect
    InternetCloseHandle hInternetSession
End Sub

Function ReadFileToBytes(filePath As String) As Byte()
    Dim fileNum As Integer
    Dim fileSize As Long
    Dim fileBytes() As Byte

    fileNum = FreeFile
    Open filePath For Binary As fileNum
    fileSize = LOF(fileNum)
    ReDim fileBytes(1 To fileSize)
    Get fileNum, 1, fileBytes
    Close fileNum

    ReadFileToBytes = fileBytes
End Function` 

5. Troubleshooting Common Errors:

6. Output:

Upload succeeded!

Reference:

Justification for Documentation Enhancement

Currently, documentation lacks detailed guidance on resolving the ERROR_INTERNET_CONNECTION_RESET in the context of VBA and WinINet API usage. This enhancement improves clarity for developers working with Azure Blob Storage via VBA, reducing the occurrence of errors and providing concrete troubleshooting steps.

Conclusion

By following this guide, users can resolve the ERROR_INTERNET_CONNECTION_RESET error when uploading files to Azure Blob Storage using the WinINet API in VBA. This structured approach improves reliability, helping users successfully upload files while avoiding common pitfalls.

TPavanBalaji commented 2 hours ago

@S-Venkatesan-326 Thanks for your feedback! We will investigate and update as appropriate.