Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- *usage;
- Dim r As THTTPResponse
- r = HTTPOperation(eHTTPGet, eHttps, "google.com", "/search", "q=beer")
- Debug.Print r.lngCode
- Debug.Print StrConv(r.abData, vbUnicode)
- *in a module
- Option Explicit
- Public Const HTTP_OK As Long = 200&
- Private Const HTTP_VERSION As String * 8 = "HTTP/1.1"
- Private Const INTERNET_OPEN_TYPE_PRECONFIG As Long = 0
- Private Const INTERNET_SERVICE_HTTP As Long = 3
- Private Const INTERNET_FLAG_RELOAD As Long = &H80000000
- Private Const INTERNET_FLAG_NO_CACHE_WRITE As Long = &H4000000
- Private Const INTERNET_FLAG_SECURE As Long = &H800000
- Private Const INTERNET_DEFAULT_HTTP_PORT As Long = 80
- Private Const INTERNET_DEFAULT_HTTPS_PORT As Long = 443
- Private Const BUFF_LEN As Long = 512&
- Private Const DUMMY_BUFF_MULTIPLIER As Long = 4
- Private Const HTTP_ADDREQ_FLAG_ADD As Long = &H20000000
- Private Const HTTP_ADDREQ_FLAG_REPLACE As Long = &H80000000
- Private Const HTTP_QUERY_CONTENT_LENGTH As Long = 5
- Private Const HTTP_QUERY_STATUS_CODE As Long = 19
- Private Const HTTP_QUERY_STATUS_TEXT As Long = 20
- Private Const HTTP_HEADER_UTF8 As String = "Content-Type: application/x-www-form-urlencoded; charset=""UTF-8""" & vbCrLf
- Private Const HTTP_HEADER_UTF8_PLAIN As String = "Content-Type: text/html; charset=""UTF-8""" & vbCrLf
- Public Type THTTPResponse
- strCode As String
- abData() As Byte
- lngSizeOf As Long
- lngCode As Long
- strError As String
- End Type
- Public Enum eHttpVerb
- eHTTPpost
- eHTTPGet
- End Enum
- Public Enum eHttpPort
- eHttp = INTERNET_DEFAULT_HTTP_PORT
- eHttps = INTERNET_DEFAULT_HTTPS_PORT
- End Enum
- Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Long) As Long
- Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (ByVal hInternetSession As Long, ByVal lpstrServerName As String, ByVal nProxyPort As Integer, ByVal lpstrUsername As String, ByVal lpstrPassword As String, ByVal dwService As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long
- Private Declare Function HttpOpenRequest Lib "wininet.dll" Alias "HttpOpenRequestA" (ByVal hInternetSession As Long, ByVal lpstrVerb As String, ByVal lpstrObjectName As String, ByVal lpstrVersion As String, ByVal lpstrReferer As String, ByVal lpstrAcceptTypes As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long
- Private Declare Function HttpAddRequestHeaders Lib "wininet.dll" Alias "HttpAddRequestHeadersA" (ByVal hHttpRequest As Long, ByVal sHeaders As String, ByVal lHeadersLength As Long, ByVal lModifiers As Long) As Integer
- Private Declare Function HttpSendRequest Lib "wininet.dll" Alias "HttpSendRequestA" (ByVal hHttpRequest As Long, ByVal sHeaders As String, ByVal lHeadersLength As Long, ByVal sOptional As String, ByVal lOptionalLength As Long) As Boolean
- Private Declare Function HttpQueryInfo Lib "wininet.dll" Alias "HttpQueryInfoA" (ByVal hHttpRequest As Long, ByVal lInfoLevel As Long, ByRef strBuffer As Any, ByRef lBufferLength As Long, ByRef lIndex As Long) As Long
- Private Declare Function InternetReadFileBinary Lib "wininet.dll" Alias "InternetReadFile" (ByVal hFile As Long, ByVal lpBuffer As Long, ByVal lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer
- Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInet As Long) As Integer
- Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (xDest As Any, xSource As Any, ByVal nbytes As Long)
- Public Function HTTPOperation(eVerb As eHttpVerb, ePort As eHttpPort, strHost As String, strObjectPath As String, strQueryString As String) As THTTPResponse
- Dim HCONNECT As Long
- Dim HREQUEST As Long
- Dim HOPEN As Long
- Dim HSEND As Long
- Dim strVerb As String
- Dim strTargetURL As String
- Dim strBuff As String * BUFF_LEN
- Dim abytReadBuffFixed(BUFF_LEN) As Byte
- Dim abytReadBuff() As Byte
- Dim bDoLoop As Boolean
- Dim lngPtrBuff As Long
- Dim sngDlTimer As Single
- Dim lNumberOfBytesRead As Long
- Dim bRet As Boolean
- Dim lngTotalBytesRead As Long
- Dim lngContentLen As Long
- On Error GoTo ERR_DL
- strVerb = IIf(eVerb = eHTTPpost, "POST", "GET")
- If (eVerb = eHTTPGet) Then
- strVerb = "GET"
- If (strQueryString <> "") Then strTargetURL = strObjectPath & "?" & strQueryString
- Else
- strVerb = "POST"
- strTargetURL = strObjectPath
- End If
- HOPEN = InternetOpen(HTTPGetUAString(), INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString, 0&)
- If (HOPEN = 0) Then Err.Raise vbObjectError + 1000, "InternetOpen()", "Failed to open an Internet connection"
- HCONNECT = InternetConnect(HOPEN, strHost, ePort, vbNullString, vbNullString, INTERNET_SERVICE_HTTP, 0&, 0&)
- If (HCONNECT = 0) Then Err.Raise vbObjectError + 1001, "InternetConnect()", "Failed to open an Internet connection (ii)"
- HREQUEST = HttpOpenRequest(HCONNECT, strVerb, strTargetURL, HTTP_VERSION, vbNullString, 0&, IIf(ePort = eHttps, INTERNET_FLAG_SECURE, 0) Or (INTERNET_FLAG_NO_CACHE_WRITE Or INTERNET_FLAG_RELOAD), 0&)
- If (HREQUEST = 0) Then Err.Raise vbObjectError + 1002, "HttpOpenRequest()", "Failed to open HTTP request"
- If (eVerb = eHTTPpost) Then
- Call HttpAddRequestHeaders(HREQUEST, HTTP_HEADER_UTF8, Len(HTTP_HEADER_UTF8), HTTP_ADDREQ_FLAG_REPLACE Or HTTP_ADDREQ_FLAG_ADD)
- HSEND = HttpSendRequest(HREQUEST, vbNullChar, 0&, strQueryString, Len(strQueryString))
- Else
- Call HttpAddRequestHeaders(HREQUEST, HTTP_HEADER_UTF8_PLAIN, Len(HTTP_HEADER_UTF8_PLAIN), HTTP_ADDREQ_FLAG_REPLACE Or HTTP_ADDREQ_FLAG_ADD)
- HSEND = HttpSendRequest(HREQUEST, vbNullChar, 0&, vbNullChar, 0&)
- End If
- If (HSEND = 0) Then Err.Raise vbObjectError + 1003, "HttpSendRequest()", "Failed to send HTTP Request"
- HTTPOperation = HTTPGetResponse(HREQUEST)
- If (HTTPOperation.lngCode <> HTTP_OK) Then Err.Raise vbObjectError + 1501, "HTTPGetResponse()", "HTTP Error, Code: " & HTTPOperation.lngCode & ": " & HTTPOperation.strCode
- '//get data size
- Call HttpQueryInfo(HREQUEST, HTTP_QUERY_CONTENT_LENGTH, ByVal strBuff, BUFF_LEN, 0&)
- lngContentLen = Val(strBuff)
- If (lngContentLen = 0&) Then lngContentLen = (BUFF_LEN * DUMMY_BUFF_MULTIPLIER)
- '//chunk read the object
- bDoLoop = True
- lngPtrBuff = VarPtr(abytReadBuffFixed(0))
- sngDlTimer = Timer()
- While bDoLoop
- bRet = InternetReadFileBinary(HREQUEST, ByVal lngPtrBuff, BUFF_LEN, lNumberOfBytesRead)
- If Not bRet Then Err.Raise vbObjectError + 1500, "InternetReadFileBinary()", "An Error occured reading from the URL"
- If (lNumberOfBytesRead > 0) Then
- lngTotalBytesRead = (lngTotalBytesRead + lNumberOfBytesRead)
- ReDim Preserve abytReadBuff(lngTotalBytesRead - 1)
- CopyMemory abytReadBuff(lngTotalBytesRead - lNumberOfBytesRead), abytReadBuffFixed(0), lNumberOfBytesRead
- Debug.Print "READ " & lngTotalBytesRead
- Else
- bDoLoop = False
- End If
- Wend
- HTTPOperation.abData = abytReadBuff
- If (lngTotalBytesRead > 0) Then HTTPOperation.lngSizeOf = UBound(abytReadBuff) + 1
- GoSub L_CLOSEH
- Exit Function
- L_CLOSEH:
- Call InternetCloseHandle(HREQUEST)
- Call InternetCloseHandle(HOPEN)
- Call InternetCloseHandle(HSEND)
- Call InternetCloseHandle(HCONNECT)
- Return
- ERR_DL:
- HTTPOperation.strError = Err.Description & " (" & Err.Source & ", Code: " & Hex(Err.Number) & ")"
- GoSub L_CLOSEH
- Err.Raise Err.Number, Err.Source, HTTPOperation.strError
- End Function
- Private Function HTTPGetUAString() As String
- HTTPGetUAString = App.EXEName & "/" & App.Major & "." & App.Minor & "." & App.Revision & " (N; en-GB; DAEMON)"
- End Function
- Public Function HTTPEncode(strRawData As String) As String
- Dim strChar As String
- Dim strBuff As String
- Dim lngChar As Long
- Dim abytChar() As Byte
- abytChar = StrConv(strRawData, vbFromUnicode)
- For lngChar = 0 To UBound(abytChar)
- Select Case abytChar(lngChar)
- Case 96 To 123: strChar = ChrW$(abytChar(lngChar))
- Case 64 To 91: strChar = ChrW$(abytChar(lngChar))
- Case 47 To 58: strChar = ChrW$(abytChar(lngChar))
- Case Else
- strChar = (Hex(abytChar(lngChar)))
- If (abytChar(lngChar) < 16) Then
- strChar = "%0" + strChar
- Else
- strChar = "%" + strChar
- End If
- End Select
- strBuff = strBuff + strChar
- Next
- HTTPEncode = strBuff
- End Function
- Private Function HTTPGetResponse(hOpenHTTPRequest As Long) As THTTPResponse
- Dim strBuff As String * BUFF_LEN&
- Dim lngBufflen As Long
- lngBufflen = BUFF_LEN
- With HTTPGetResponse
- Call HttpQueryInfo(hOpenHTTPRequest, HTTP_QUERY_STATUS_TEXT, ByVal strBuff, lngBufflen, 0&)
- .strCode = Left$(strBuff, lngBufflen)
- lngBufflen = BUFF_LEN
- Call HttpQueryInfo(hOpenHTTPRequest, HTTP_QUERY_STATUS_CODE, ByVal strBuff, lngBufflen, 0&)
- .lngCode = Val(Left$(strBuff, lngBufflen))
- .strCode = "[" & .lngCode & "] " & .strCode
- If (.lngCode = 0&) Then .strCode = "[Bad/Unknown Response]"
- End With
- End Function
Advertisement
Add Comment
Please, Sign In to add comment