Skip to content

Instantly share code, notes, and snippets.

@katio
Last active December 28, 2015 08:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save katio/7472688 to your computer and use it in GitHub Desktop.
Save katio/7472688 to your computer and use it in GitHub Desktop.
Small modification to Lotusscript HttpRequest-class. original author: Tommy Valand http://dontpanic82.blogspot.com/2007/12/httprequest-class.html This is a usefull classic lotusscript created by Tommy Valand. It allow you to capture parameters POST, GET and Cookies. i just made a couple of small modifications for my personal use with POST parame…
Class HttpRequest
'##############################################################
'## ##
'## A class to simplify fetching parameters from Post/Get-requests ##
'## The class also supports fetching cookies from a request ##
'## ##
'## Example of use: ##
'## Dim request As New HttpRequest ##
'## ##
'## Dim action As String ##
'## action = request.parameter( "action" ) ##
'## 'e.g. ?OpenAgent&action=hello&debug ##
'## If request.hasParameter( "debug" ) Then ##
'## Print "Action: " + action ##
'## End If ##
'## ##
'## 'To get a cookie: cookieValue = request.cookie( "cookieName" ) ##
'## ##
'## 'To get a report of all CGI-variables/request-content ##
'## Print request.htmlReport (64k limited) ##
'## 'To print a non-64k limited report ##
'## Call request.printHtmlReport ##
'## ##
'## Made by Tommy Valand/DontPanic, http://dontpanic82.blogspot.com ##
'## ##
'##############################################################
Private session As NotesSession
Private context As NotesDocument
Private request As String
Private request_method As String
Private requestParameterList List As Variant
Private cookieList List As String
Sub New
On Error GoTo bubbleError
Set session = New NotesSession
Set context = session.DocumentContext
'// Check that session has DocumentContext
If context Is Nothing Then Error 1001, "The session doesn't have DocumentContext (agent not run on the web?)"
Me.request_method = context.GetItemValue( "request_method" )(0)
'// Check that context has request-method (agent run by URL)
If context.HasItem( "request_method" ) Then
'// Get request-string
If method = "GET" Then
Me.request = context.GetItemValue( "query_string_decoded" )(0)
Else
Me.request = Me.requestContent()
End If
Else
Error 1001, "Couldn't get request method (agent not run on the web?)"
End If
'// Extract all parameters into a String List
Dim requestArr As Variant, parameterName As String, parameterValue As String
requestArr = Split( Me.request, "&" )
ForAll parameter In requestArr
parameterName = StrToken( parameter, "=", 1 )
parameterValue = Replace( parameter, parameterName + "=", "" )
If IsElement( requestParameterList( parameterName ) ) Then '// Parameter passed several times - multivalue
Dim currentValue As Variant
currentValue = Me.requestParameterList( parameterName )
'// A String - convert to a dynamic array
If DataType( currentValue ) = 8 Then currentValue = Split( currentValue, "¤%#¤%" )
'// Append value to array
Me.requestParameterList( parameterName ) = ArrayAppend( currentValue, parameterValue )
Else
'// First occurence of parameter - add to list as string
Me.requestParameterList( parameterName ) = parameterValue
End If
End ForAll
'// Extract all cookies into a String List
Dim cookies As String, cookiesArr As Variant
cookies = context.GetItemValue( "HTTP_COOKIE" )(0)
cookiesArr = Split( cookies, "; " )
ForAll cookie In cookiesArr
Dim cookieName As String
cookieName = StrToken( cookie, "=", 1 )
cookieList( cookieName ) = Replace( cookie, cookieName + "=", "" )
End ForAll
Exit Sub
bubbleError:
Error Err, Me.errorMessage()
End Sub
'// Check to see that a parameter exists. More or less equal to isset in PHP
Property Get hasParameter( ByVal parameterName As String ) As Boolean
hasParameter = ( IsElement( Me.requestParameterList( parameterName ) ) )
End Property
'// Returns the value of the parameter specified by name. If not found it returns an empty string
'// If the parameter is a result of a multi-select item, the property is a dynamic array, else a String
Property Get parameter( ByVal parameterName As String ) As Variant
On Error GoTo bubbleError
If Me.hasParameter( parameterName ) Then
parameter = Me.requestParameterList( parameterName )
Else
parameter = ""
End If
Exit Property
bubbleError:
Error Err, Me.errorMessage()
End Property
'// Check to see if a cookie is set
Property Get hasCookie( ByVal cookieName As String ) As Boolean
hasCookie = ( IsElement( Me.cookieList( cookieName ) ) )
End Property
'// Returns the value of the cookie specified by name, or an empty string
Property Get cookie( ByVal cookieName As String )
If Me.hasCookie( cookieName ) Then cookie = Me.cookieList( cookieName )
End Property
'// Returns the request-string
Property Get content As String
content = Me.request
End Property
'// Returns the request-method
Property Get method As String
method = Me.request_method
End Property
'// Function to determine if requestContent is longer than 64k/combine the fields
Private Function requestContent() As String
On Error GoTo bubbleError
If Me.context.hasItem( "request_content" ) Then
requestContent = Me.context.getItemValue( "request_content" )(0)
'Begin Johann Echavarría adition 20131113
requestContent = me.urlDecodeNewLineAndOthers(requestContent)
'End Johann Echavarría adition 20131113
Exit Function
End If
Dim requestContentFieldNames As Variant
requestContentFieldNames = Evaluate( |@Trim( @Word( @DocFields ; "REQUEST_CONTENT_" ; 2 ) )|, Me.context )
Dim stringBuffer As NotesStream
Set stringBuffer = Me.session.CreateStream
ForAll requestContentFieldName In requestContentFieldNames
Call stringBuffer.WriteText( context.GetItemValue( "REQUEST_CONTENT_" + requestContentFieldName )(0) )
End ForAll
stringBuffer.Position = 0
requestContent = stringBuffer.ReadText
'Begin Johann Echavarría adition 20131113
requestContent = me.urlDecodeNewLineAndOthers(requestContent)
'End Johann Echavarría adition 20131113
Exit Function
bubbleError:
Error Err, Me.errorMessage()
End Function
'// Prints full report - No 64k limit
Function printHtmlReport
On Error GoTo bubbleError
Dim report As String
report = Me.htmlReport()
Dim position As Long, increment As Long
position = 1
increment = 60000
Print |<h1>Content length: | & Format( Len( report ), "Standard" ) & | characters</h1>|
If Len( report ) < increment Then
Print report
Else
Print |<strong>Number of request_content fields: | & Join( Evaluate( |@Elements( @Trim( @Word( @DocFields ; "REQUEST_CONTENT_" ; 2 ) ) )|, Me.context ) ) & |</strong>|
While position < Len( report )
Print Mid( report, position, increment )
position = position + increment
Wend
Print Mid( report, position )
End If
Exit Function
bubbleError:
Error Err, Me.errorMessage()
End Function
Function htmlReport As String
On Error GoTo handleErr
Dim stringbuffer As NotesStream
Set stringbuffer = Me.session.CreateStream
Call stringbuffer.WriteText( |
<style>
* { font-family: arial; font-size: 12px; }
table { border-collapse: collapse; }
caption { background-color: #ddd; font-size: 16px; margin: 0; padding: 10px 0; font-weight: bold; }
tr { vertical-align: top; }
td {border: 1px solid #ccc; padding: 3px; }
tfoot td { background-color: #669922; color: #fff; font-size: 14px; text-align: center; }
#label { background-color: #eee; }
</style>| )
Call stringbuffer.WriteText( |
<table>
<col id="label"/>
<col id="value"/>
<caption>Request content</caption>| )
Call stringbuffer.WriteText( |<tbody>| )
ForAll item In context.Items
Call stringbuffer.WriteText( |<tr><td>| + item.name + |</td><td>| )
ForAll itemval In item.Values
Call stringbuffer.WriteText( itemval )
End ForAll
Call stringbuffer.WriteText( |</td></tr>| )
End ForAll
Call stringbuffer.WriteText( | </tbody><tfoot><tr><td colspan="2">Routine created by
<a href="http://dontpanic82.blogspot.com">Tommy Valand/DontPanic</a></td></tr></tfoot>
</table>| )
'Extract stream content to string
stringbuffer.Position = 0
htmlReport = stringbuffer.ReadText()
Exit Function
handleErr:
Print Me.errorMessage()
Resume Next
End Function
Private Function errorMessage As String
'// Simple function to generate more readable errors when dealing with error-bubbling
Dim message As String
message = Error
If CStr( GetThreadInfo(10) ) = "INITIALIZE" Then
errorMessage = "Error " & Err & " on line " & Erl & " in function " & GetThreadInfo( 10 ) & ": " + Error
Else
errorMessage = Chr(13) + Chr(9) + "Error " & Err & " on line " & Erl & " in function " & GetThreadInfo( 10 ) & ": " + Error$
End If
End Function
'Begin Johann Echavarría adition 20131113
Property Get parameterList As Variant
On Error GoTo bubbleError
parameterList = Me.requestParameterList
Exit Property
bubbleError:
Error Err, Me.errorMessage()
End Property
Private Function urlDecode(s As String) As String
'Taken from Johan Känngård blog
If Len(s) = 0 Then Exit Function
Dim i As Integer
Dim tmp As String
Dim c As String
For i = 1 To Len(s)
c = Mid$(s, i, 1)
If c = "+" Then c = " "
If c = "%" Then
c = Chr$("&H" + Mid$(s, i + 1, 2))
c = uChr$("&H" + Mid$(s, i + 1, 2))
i = i + 2
End If
tmp = tmp + c
Next i
urlDecode = tmp
End Function
private Function decodeURI$(txt$)
'source: http://www.sencha.com/forum/showthread.php?66046-Notes-Agent-working-with-POST-or-GET
'decodes a UTF-8 encoding string
decodeURI = txt
'replace + by spaces first: @URLDecode doesn't conver these back to spaces
If InStr(decodeURI, "+")>0 Then
decodeURI = Replace(decodeURI, "+", " ")
End If
Const MAX_LENGTH = 2048
'NOTE: evaluate has an input limit of 2 Kb (len = 2048)
If Len(decodeURI) <= MAX_LENGTH Then
decodeURI = Join( Evaluate( {@URLDecode("utf-8"; "} & decodeURI & {")} ), "" )
Else
Dim s As New NotesSession
Dim stream As NotesStream
Set stream = s.CreateStream
Dim pStart As Long
Dim part As String, i As Integer, intLen As Integer, char As String
pStart = 1
While pStart <= Len(decodeURI)
part = Mid$( decodeURI, pStart, MAX_LENGTH )
intLen = Len(part)
For i=1 To 2
char = Left(Right(part, i), 1)
If char = "%" Then 'dont split in the middle of an encoded char
part = Left( part, intLen-i )
intLen = Len(part)
Exit For
End If
Next
stream.WriteText Join( Evaluate( {@URLDecode("utf-8"; "} & part & {")} ) )
pStart = pStart + intLen 'new start position
Wend
stream.Position = 0
decodeURI = stream.ReadText
End If
End Function
private Function Unescape(s As String) As String 'this is a backup function for (decodeURI). Seems to work with UTF-8
%REM
Dencodes a string from the "x-www-form-urlencoded" form, enhanced with the UTF-8-in-URL proposal. This is the official
standard to encode URL's to support any possible character set (all Unicode characters).
%END REM
Dim result As String
Dim b As Long, c As Long
Dim i As Integer
Dim sumb As Long
For i = 1 To Len(s)
c = Uni(Mid$(s, i, 1))
Select Case c
Case Uni("%"):
b = CInt("&H"+Mid$(s, i+1,2))
i = i + 2
Case Uni("+")
b = Uni(" ")
Case Else
b = c
End Select
' Decode byte b as UTF-8, sumb collects incomplete chars
If (b And &Hc0) = &H80 Then
sumb = (sumb*64) Or (b And &H3f)
Else
If (sumb<>0) Then
result = result & UChr(sumb)
End If
If (b And &H80) = 0 Then
sumb = b
Else
sumb = b And &H1f
End If
End If
Next
If (sumb<>0) Then
result = result & UChr(sumb)
End If
Unescape = result
End Function
Private Function urlDecodeNewLineAndOthers (s As String) As String
On Error GoTo bubbleError
'urlDecodeNewLineAndOthers = me.urlDecode(s) 'urlDecode doesn't works with UTF-8 encoding
'urlDecodeNewLineAndOthers = me.Decodeuri(s) 'Decodeuri seems to work for UTF-8 encoding
urlDecodeNewLineAndOthers = me.Unescape(s) 'backup for Decodeuri seems to work for UTF-8 too
urlDecodeNewLineAndOthers = Replace(urlDecodeNewLineAndOthers, UChr(10) , "\n")
urlDecodeNewLineAndOthers = Replace(urlDecodeNewLineAndOthers, UChr(13) , "\r")
Exit Function
bubbleError:
Error Err, Me.errorMessage()
Exit function
End Function
'End Johann Echavarría adition 20131113
End Class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment