Archived Forum Post

Index of archived forum posts

Question:

Trouble Receiving HTTP Uploads with Non-English Characters in Params

Nov 28 '12 at 18:46

I'm trying to receive an HTTP upload that contains a form field w/ non-English characters. Non-English characters such as German umlauts and French characters (Ä ä Ö ö Ü ü ß é è) do not display correctly. Is there a problem with the Chilkat.UploadRcv ActiveX object?


Answer

Let's walk through a simple example that demonstrates everything working correctly. First, some additional information was added to LastErrorHtml, so download this new build: http://www.chilkatsoft.com/preRelease/ChilkatUpload.zip. Stop IIS, register the new DLL with regsvr32, then re-start IIS. (If copying over the old ChilkatUpload.dll, there is no need to re-register w/ regsvr32)

Here's a simple HTML form that can be used to send the HTTP upload with an extra form param:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<form method="POST" enctype="multipart/form-data" action = "receiveUpload.asp" >
<input name=a1 type=file size=20><br>
<input name=p1 type=text size=50><br>
<input type=submit value="Upload">
</form> 
</body>
</html>
Create an HTML file on your web server w/ this content, then point your browser to the HTML. Select a small file to upload, and also cut-and-paste this string into the text box for the "p1" param: "Ä ä Ö ö Ü ü ß é è".

Here are the complete contents of the receiveUpload.asp file (which is the action URL in the form tag in the HTML above).

<%
set receiver = Server.CreateObject("Chilkat.UploadRcv")
set cks = Server.CreateObject("Chilkat.String")

' Consume the upload. Files are streamed to the UploadDir success = receiver.Consume() if (success = 0) then Response.Write receiver.LastErrorHtml else Response.Write "<html><head>" & vbCrLf Response.Write "<meta http-equiv="" content-type""="" content="" text="" html;="" charset="utf-8""">" & vbCrLf Response.Write "</head><body>" & vbCrLf

    ' Display the files received
    Response.Write receiver.LastErrorHtml
    Response.Write "<p>"

    for idx = 0 to receiver.NumParams-1
        sName = receiver.GetParamName(idx)
        sValue = receiver.getParamValue(idx)
        cks.Str = sValue
        Response.Write receiver.LastErrorHtml
        response.write sName & " = " 
        response.BinaryWrite cks.EmitMultibyte("utf-8")
        response.Write vbCrLf & "<br />"
    next

    Response.Write "<p>Num file received: " & receiver.NumFilesReceived & "</p>"
    if receiver.NumFilesReceived > 0 then
        for i = 0 to receiver.NumFilesReceived - 1
        Response.Write "<p>Received " & receiver.GetFilename(i) & 
                         " (" & receiver.GetFileSize(i) & " bytes)</p>"
        next
    end if
    Response.Write "Success."

end if

Response.Write "</body></html>" & vbCrLf

Response.Flush() %>

Put the receiveUpload.asp in the same directory as the HTML file. Load the HTML form in a browser and click the "Upload" button. This is a sample result:

ChilkatLog:
    Consume:
        DllDate: Nov 27 2012
        UnlockPrefix: NONE
        Username: CK2007:IUSR_CK2007
        Architecture: Little Endian; 32-bit
        Language: ActiveX
        VerboseLogging: 0
        bAsp: 1
        contentType:
        requestMethod:
        Assuming this is a POST...
        ContentLength: (NULL)
        doConsumeAspUpload:
            loadMimeBinary:
                MIME has no header. Auto-detecting boundary string (2)
                boundary: ---------------------------313223033317673
            numParts: 2
            partNum: 0
            part:
                name: a1
                PartHdr: Content-Disposition: form-data; name=a1; filename="cheese.jpg" Content-Type: image/jpeg
                filename: cheese.jpg
                Uploading to memory.
            partNum: 1
            part:
                name: p1
                PartHdr: Content-Disposition: form-data; name=p1
                paramNameUtf8_QP: p1
                paramValueUtf8_QP: =C3=84 =C3=A4 =C3=96 =C3=B6 =C3=9C =C3=BC =C3=9F =C3=A9 =C3=A8
        Finished consuming upload.
        Success.
ChilkatLog:
    GetParamValue:
        DllDate: Nov 27 2012
        UnlockPrefix: NONE
        Username: CK2007:IUSR_CK2007
        Architecture: Little Endian; 32-bit
        Language: ActiveX
        VerboseLogging: 0
        paramValueUtf8_QP: =C3=84 =C3=A4 =C3=96 =C3=B6 =C3=9C =C3=BC =C3=9F =C3=A9 =C3=A8
attach2 = Ä ä Ö ö Ü ü ß é è
Num file received: 1
Received cheese.jpg (1013 bytes)
Success. 

It can be see that in the LastErrorHtml, the "Ä ä Ö ö Ü ü ß é è" was correctly received. The utf-8 bytes of the string are logged using quoted-printable format so we can see the exact bytes, and as expected, for the non-us-ascii chars there are 2 bytes per char:

paramValueUtf8_QP: =C3=84 =C3=A4 =C3=96 =C3=B6 =C3=9C =C3=BC =C3=9F =C3=A9 =C3=A8

Also note that the HTML emitted is going to be utf-8, as indicated by the meta tag that specifies the charset. It would be incorrect to try to simply do a Response.Write passing the Unicode string returned by receiver.getParamValue(idx). (All strings in VBScript and passed to/from any ActiveX are always Unicode. Not utf-8, but utf-16.) Therefore, to emit utf-8 the Chilkat.String ActiveX is used. The Unicode param value is loaded into the Chilkat.String object by setting the cks.Str property, and then the following line emits the utf-8 string:

response.BinaryWrite cks.EmitMultibyte("utf-8")