Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Accessing POSTed binary data

Posted on 2010-01-08
7
Medium Priority
?
1,016 Views
Last Modified: 2012-08-13
I am uploading a binary file to a server running ASP.  The upload occurs from a web page that has a simple form that has a browse/file upload button on it.  The ASP page follows.  After reading the binary data into the string, I search for the uploaded file part of the form data and extract it to a string in an attempt to get at the binary data (not shown).

My intention is to process the uploaded binary file and use the data to generate a response that is served back to the browser.

The problem is that the uploaded file data I extract into the string seems to have the bit 8 of each character stripped off.  Ive tried various charsets with varying (wrong) results.

I know I can use an existing ASP upload component but I don't need to baggage they have and I was trying to code something leaner.

Did the MSB binary data make it?  If I were to save the binary data stream to a file would the MSB's be there?  I don't want to save to a file and read it back.  I'd rather process the data at this point.  How can I access each byte of data in the SafeArray BinaryData? Or perhaps read it byte by byte from the stream?  


<%
var InputStream = Server.CreateObject ("ADODB.Stream") ;
InputStream.Type = 1 ;
InputStream.Open () ;
var BinaryData = Request.BinaryRead (Request.TotalBytes) ;
InputStream.Write (BinaryData) ;

InputStream.Position = 0 ;
InputStream.Type = 2 ; // adTypeText=2
InputStream.Charset = "us-ascii" ;
var StringData = InputStream.ReadText () ;
Response.Write ("StringData = ") ;
Response.Write (StringData) ;
Response.Write ("<br><br>") ;
%>

Open in new window

0
Comment
Question by:rossmcm
  • 4
  • 2
6 Comments
 
LVL 9

Expert Comment

by:CCongdon
ID: 26213508
Does your sending form have multi-part set as its type?
0
 
LVL 9

Assisted Solution

by:CCongdon
CCongdon earned 200 total points
ID: 26213519
<form action="process.asp" method="post" enctype="multipart/form-data" name="frmEdit" id="frmEdit">
0
 

Author Comment

by:rossmcm
ID: 26216076
Yes.  If I load the binary data into a string, I can parse the string, find the start boundary of the posted data, the end boundary, then do a substring of the data to get the uploaded file contents.  Trouble is, the MSB is stripped from all the characters.  Actual code follows (with debug statements).

After this code has executed the string variable UploadedFileContents has the correct number of bytes, but no MSBs.

var InputStream = Server.CreateObject ("ADODB.Stream") ;
InputStream.Type = 1 ;
InputStream.Open () ;
var BinaryData = Request.BinaryRead (Request.TotalBytes) ;
InputStream.Write (BinaryData) ;

InputStream.Position = 0 ;
InputStream.Type = 2 ; // adTypeText=2
InputStream.Charset = "us-ascii" ;
var StringData = InputStream.ReadText () ;

//  Get the boundary header

var EndOfStartBoundaryPosition = 0 ;
var EndBoundaryPosition = 0 ;
var BoundaryText = "" ;
var ContentTypePosition = 0 ;
var UploadedFileStartPosition = 0 ;
var UploadedFileLength        = 0 ;
var EndBoundaryPosition = 0 ;
var UploadedFileContents = "" ;

EndOfStartBoundaryPosition = StringData.indexOf ("\r\n", 0) ;
Response.Write ("EndOfStartBoundaryPosition = " + EndOfStartBoundaryPosition + "<br><br>") ;

BoundaryText = StringData.substring (0, EndOfStartBoundaryPosition) ;
Response.Write ("BoundaryText = " + BoundaryText + "<br><br>") ;

ContentTypePosition = StringData.indexOf ("Content-Type:", EndBoundaryPosition) ;
Response.Write ("ContentTypePosition = " + ContentTypePosition + "<br><br>") ;

UploadedFileStartPosition = StringData.indexOf ("\r\n", ContentTypePosition) + 4 ;
Response.Write ("UploadedFileStartPosition = " + UploadedFileStartPosition + "<br><br>") ;

EndBoundaryPosition  = StringData.indexOf (BoundaryText, UploadedFileStartPosition) ;
Response.Write ("EndBoundaryPosition = " + EndBoundaryPosition + "<br><br>") ;

UploadedFileLength   = EndBoundaryPosition - UploadedFileStartPosition - 2 ;
Response.Write ("UploadedFileLength = " + UploadedFileLength + "<br><br>") ;

UploadedFileContents = StringData.substring (UploadedFileStartPosition, UploadedFileStartPosition + UploadedFileLength) ;

Response.Write ("UploadedFileContents = " + UploadedFileContents) ;
Response.Write ("<br><br>") ;

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Accepted Solution

by:
rossmcm earned 0 total points
ID: 27648351
I think I may have solved this one myself.  The key was finding UTF encoding that preserved all of the binary data and UTF-16 seems to do the trick.  The attached code has the details.

The basic sequence of events is:

Get the HTTP Post request as a binary lump
Write the lump to a stream
Write the stream to a string of UTF-16 characters.
Unravel the UTF-16 character string to a string of 8 bit characters
Parse the string to find the boundary of the posted file data
Copy that portion of the string to an array.

The array is then a faithful (I hope!) binary representation of the uploaded file, and there was no need to write any data to a file on the server.

The key was encoding the binary image as UTF16 characters.  Any other encoding played funnies with some characters, especially those with the MSB set.

Warning:  The parsing of the request is pretty minimal and assumes there are no extra controls on the upload form.  
var InputStream = Server.CreateObject ("ADODB.Stream") ;
InputStream.Type = 1 ;                                      // 1 = binary
InputStream.Open () ;
var BinaryData = Request.BinaryRead (Request.TotalBytes) ;  // read the entire HTTP request as a binary lump
InputStream.Write (BinaryData) ;                            // write it to a stream
InputStream.Position = 0 ;
InputStream.Type = 2 ;                                      // 2 = Text                      
InputStream.Charset = "UTF-16" ;                            // read as double-byte characters
var StringData = InputStream.ReadText () ;

//  StringData now has the entire response as character pairs.  UTF-16 appears to be the only coding that does not
//  munge the data.

//  read through the character pairs and construct an 8-bit character string.

var Character1 ;
var Character2 ;
var WordData ;
var StringData8 = "" ;
for (var Index = 0;Index < StringData.length;Index ++)
    {
    WordData = StringData.charCodeAt (Index) ;
    Character1 = String.fromCharCode (WordData & 255) ;
    Character2 = String.fromCharCode (WordData >>> 8) ;
    StringData8 = StringData8 + Character1 + Character2 ;
    }
StringData = null ;
    
//  we now have the request as a standard 8-byte string.    
//  assume the request has posted data.  Get the boundary header.

var EndOfStartBoundaryPosition = StringData8.indexOf ("\r\n", 0) ;                          // find the end of the start boundary
var BoundaryText = StringData8.substring (0, EndOfStartBoundaryPosition) ;                  // record the boundary text

var FilenamePosition = StringData8.indexOf ("filename=\"", EndOfStartBoundaryPosition) + 10 ;
var FilenameEndPosition = StringData8.indexOf ("\"", FilenamePosition) ;
var Filename = StringData8.substring (FilenamePosition, FilenameEndPosition) ;
var ContentTypePosition = StringData8.indexOf ("Content-Type:", FilenameEndPosition) ;      
var UploadedFileStartPosition = StringData8.indexOf ("\r\n", ContentTypePosition) + 4 ;     // record start of uploaded file binary data (+4 accounts for 2xCRLF)
var EndBoundaryPosition  = StringData8.indexOf (BoundaryText, UploadedFileStartPosition) ;  // find the end of the uploaded file data
var UploadedFileLength   = EndBoundaryPosition - UploadedFileStartPosition - 2 ;            // (-2 accounts for CRLF)

var UploadedFileContents = StringData8.substring (UploadedFileStartPosition, UploadedFileStartPosition + UploadedFileLength) ;
StringData8          = null ;

//  transfer the string data to an array

FileDataArray.length = UploadedFileLength ;
for (var Index = 0;Index < UploadedFileContents.length;Index ++)
    {
    FileDataArray [Index] = UploadedFileContents.charCodeAt (Index) ;
    }
UploadedFileContents = null ;

Open in new window

0
 

Author Comment

by:rossmcm
ID: 27648357
I have submitted my own solution to the problem and request that the question be marked as answered and not deleted as I believe it is still of value.
0
 

Author Comment

by:rossmcm
ID: 27648358
I have submitted my own solution to the problem and request that the question be marked as answered and not deleted as I believe it is still of value.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I recently decide that I needed a way to make my pages scream on the net.   While searching around how I can accomplish this I stumbled across a great article that stated "minimize the server requests." I got to thinking, hey, I use more than one…
I was asked about the differences between classic ASP and ASP.NET, so let me put them down here, for reference: Let's make the introductions... Classic ASP was launched by Microsoft in 1998 and dynamically generate web pages upon user interact…
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses
Course of the Month10 days, 3 hours left to enroll

571 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question