Subversion Repositories DevTools

Rev

Rev 4804 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
119 ghuddy 1
<!--METADATA
2
	TYPE="TypeLib"
3
	NAME="Microsoft ActiveX Data Objects 2.5 Library"
4
	UUID="{00000205-0000-0010-8000-00AA006D2EA4}"
5
	VERSION="2.5"
6
-->
7
<!--#INCLUDE FILE="clsField.asp"-->
8
<%
9
' ------------------------------------------------------------------------------
10
'	Author:		Lewis Moten
11
'	Email:		Lewis@Moten.com
12
'	URL:		http://www.lewismoten.com
13
'	Date:		March 19, 2002
14
' ------------------------------------------------------------------------------
15
 
16
' Upload class retrieves multi-part form data posted to web page
17
' and parses it into objects that are easy to interface with.
18
' Requires MDAC (ADODB) COM components found on most servers today
19
' Additional compenents are not necessary.
20
'
21
' Demo:
22
'	Set objUpload = new clsUpload
23
'		Initializes object and parses all posted multi-part from data.
24
'		Once this as been done, Access to the Request object is restricted
25
'
26
'	objUpload.Count
27
'		Number of fields retrieved
28
'
29
'		use: Response.Write "There are " & objUpload.Count & " fields."
30
'
31
'	objUpload.Fields
32
'		Access to field objects.  This is the default propert so it does
33
'		not necessarily have to be specified.  You can also determine if
34
'		you wish to specify the field index, or the field name.
35
'
36
'		Use:
37
'			Set objField = objUpload.Fields("File1")
38
'			Set objField = objUpload("File1")
39
'			Set objField = objUpload.Fields(0)
40
'			Set objField = objUpload(0)
41
'			Response.Write objUpload("File1").Name
42
'			Response.Write objUpload(0).Name
43
'
44
' ------------------------------------------------------------------------------
45
'
46
' List of all fields passed:
47
'
48
'	For i = 0 To objUpload.Count - 1
49
'		Response.Write objUpload(i).Name & "<BR>"
50
'	Next
51
'
52
' ------------------------------------------------------------------------------
53
'
54
' HTML needed to post multipart/form-data
55
'
56
'<FORM method="post" encType="multipart/form-data" action="Upload.asp">
57
'	<INPUT type="File" name="File1">
58
'	<INPUT type="Submit" value="Upload">
59
'</FORM>
60
 
61
Class clsUpload
62
' ------------------------------------------------------------------------------
63
 
64
	Private mbinData			' bytes visitor sent to server
65
	Private mlngChunkIndex		' byte where next chunk starts
66
	Private mlngBytesReceived	' length of data
67
	Private mstrDelimiter		' Delimiter between multipart/form-data (43 chars)
68
 
69
	Private CR					' ANSI Carriage Return
70
	Private LF					' ANSI Line Feed
71
	Private CRLF				' ANSI Carriage Return & Line Feed
72
 
73
	Private mobjFieldAry()		' Array to hold field objects
74
	Private mlngCount			' Number of fields parsed
75
 
76
' ------------------------------------------------------------------------------
77
	Private Sub RequestData
78
 
79
		Dim llngLength		' Number of bytes received
80
 
81
		' Determine number bytes visitor sent
82
		mlngBytesReceived = Request.TotalBytes
83
 
84
		' Store bytes recieved from visitor
4804 dpurdie 85
		' Store bytes recieved from visitor
86
        ' Check C:\WINDOWS\system32\inetsrv\MetaBase.xml :: AspMaxRequestEntityAllowed 
87
        ' if this request fails
119 ghuddy 88
		mbinData = Request.BinaryRead(mlngBytesReceived)
89
 
90
	End Sub
91
' ------------------------------------------------------------------------------
92
	Private Sub ParseDelimiter()
93
 
94
		' Delimiter seperates multiple pieces of form data
95
			' "around" 43 characters in length
96
			' next character afterwards is carriage return (except last line has two --)
97
			' first part of delmiter is dashes followed by hex number
98
			' hex number is possibly the browsers session id?
99
 
100
		' Examples:
101
 
102
		' -----------------------------7d230d1f940246
103
		' -----------------------------7d22ee291ae0114
104
 
105
		mstrDelimiter = MidB(mbinData, 1, InStrB(1, mbinData, CRLF) - 1)
106
 
107
	End Sub
108
' ------------------------------------------------------------------------------
109
	Private Sub ParseData()
110
 
111
		' This procedure loops through each section (chunk) found within the
112
		' delimiters and sends them to the parse chunk routine
113
 
114
		Dim llngStart	' start position of chunk data
115
		Dim llngLength	' Length of chunk
116
		Dim llngEnd		' Last position of chunk data
117
		Dim lbinChunk	' Binary contents of chunk
118
 
119
		' Initialize at first character
120
		llngStart = 1
121
 
122
		' Find start position
123
		llngStart = InStrB(llngStart, mbinData, mstrDelimiter & CRLF)
124
 
125
		' While the start posotion was found
126
		While Not llngStart = 0
127
 
128
			' Find the end position (after the start position)
129
			llngEnd = InStrB(llngStart + 1, mbinData, mstrDelimiter) - 2
130
 
131
			' Determine Length of chunk
132
			llngLength = llngEnd - llngStart
133
 
134
			' Pull out the chunk
135
			lbinChunk = MidB(mbinData, llngStart, llngLength)
136
 
137
			' Parse the chunk
138
			Call ParseChunk(lbinChunk)
139
 
140
			' Look for next chunk after the start position
141
			llngStart = InStrB(llngStart + 1, mbinData, mstrDelimiter & CRLF)
142
 
143
		Wend
144
 
145
	End Sub
146
' ------------------------------------------------------------------------------
147
	Private Sub ParseChunk(ByRef pbinChunk)
148
 
149
		' This procedure gets a chunk passed to it and parses its contents.
150
		' There is a general format that the chunk follows.
151
 
152
		' First, the deliminator appears
153
 
154
		' Next, headers are listed on each line that define properties of the chunk.
155
 
156
		'	Content-Disposition: form-data: name="File1"; filename="C:\Photo.gif"
157
		'	Content-Type: image/gif
158
 
159
		' After this, a blank line appears and is followed by the binary data.
160
 
161
		Dim lstrName			' Name of field
162
		Dim lstrFileName		' File name of binary data
163
		Dim lstrContentType		' Content type of binary data
164
		Dim lbinData			' Binary data
165
		Dim lstrDisposition		' Content Disposition
166
		Dim lstrValue			' Value of field
167
 
168
		' Parse out the content dispostion
169
		lstrDisposition = ParseDisposition(pbinChunk)
170
 
171
			' And Parse the Name
172
			lstrName = ParseName(lstrDisposition)
173
 
174
			' And the file name
175
			lstrFileName = ParseFileName(lstrDisposition)
176
 
177
		' Parse out the Content Type
178
		lstrContentType = ParseContentType(pbinChunk)
179
 
180
		' If the content type is not defined, then assume the
181
		' field is a normal form field
182
		If lstrContentType = "" Then
183
 
184
			' Parse Binary Data as Unicode
185
			lstrValue = CStrU(ParseBinaryData(pbinChunk))
186
 
187
		' Else assume the field is binary data
188
		Else
189
 
190
			' Parse Binary Data
191
			lbinData = ParseBinaryData(pbinChunk)
192
 
193
		End If
194
 
195
		' Add a new field
196
		Call AddField(lstrName, lstrFileName, lstrContentType, lstrValue, lbinData)
197
 
198
	End Sub
199
' ------------------------------------------------------------------------------
200
	Private Sub AddField(ByRef pstrName, ByRef pstrFileName, ByRef pstrContentType, ByRef pstrValue, ByRef pbinData)
201
 
202
		Dim lobjField		' Field object class
203
 
204
		' Add a new index to the field array
205
		' Make certain not to destroy current fields
206
		ReDim Preserve mobjFieldAry(mlngCount)
207
 
208
		' Create new field object
209
		Set lobjField = New clsField
210
 
211
		' Set field properties
212
		lobjField.Name = pstrName
213
		lobjField.FilePath = pstrFileName				
214
		lobjField.ContentType = pstrContentType
215
 
216
		' If field is not a binary file
217
		If LenB(pbinData) = 0 Then
218
 
219
			lobjField.BinaryData = ChrB(0)
220
			lobjField.Value = pstrValue
221
			lobjField.Length = Len(pstrValue)
222
 
223
		' Else field is a binary file
224
		Else
225
 
226
			lobjField.BinaryData = pbinData
227
			lobjField.Length = LenB(pbinData)
228
			lobjField.Value = ""
229
 
230
		End If
231
 
232
		' Set field array index to new field
233
		Set mobjFieldAry(mlngCount) = lobjField
234
 
235
		' Incriment field count
236
		mlngCount = mlngCount + 1
237
 
238
	End Sub
239
' ------------------------------------------------------------------------------
240
	Private Function ParseBinaryData(ByRef pbinChunk)
241
 
242
		' Parses binary content of the chunk
243
 
244
		Dim llngStart	' Start Position
245
 
246
		' Find first occurence of a blank line
247
		llngStart = InStrB(1, pbinChunk, CRLF & CRLF)
248
 
249
		' If it doesn't exist, then return nothing
250
		If llngStart = 0 Then Exit Function
251
 
252
		' Incriment start to pass carriage returns and line feeds
253
		llngStart = llngStart + 4
254
 
255
		' Return the last part of the chunk after the start position
256
		ParseBinaryData = MidB(pbinChunk, llngStart)
257
 
258
	End Function
259
' ------------------------------------------------------------------------------
260
	Private Function ParseContentType(ByRef pbinChunk)
261
 
262
		' Parses the content type of a binary file.
263
		'	example: image/gif is the content type of a GIF image.
264
 
265
		Dim llngStart	' Start Position
266
		Dim llngEnd		' End Position
267
		Dim llngLength	' Length
268
 
269
		' Fid the first occurance of a line starting with Content-Type:
270
		llngStart = InStrB(1, pbinChunk, CRLF & CStrB("Content-Type:"), vbTextCompare)
271
 
272
		' If not found, return nothing
273
		If llngStart = 0 Then Exit Function
274
 
275
		' Find the end of the line
276
		llngEnd = InStrB(llngStart + 15, pbinChunk, CR)
277
 
278
		' If not found, return nothing
279
		If llngEnd = 0 Then Exit Function
280
 
281
		' Adjust start position to start after the text "Content-Type:"
282
		llngStart = llngStart + 15
283
 
284
		' If the start position is the same or past the end, return nothing
285
		If llngStart >= llngEnd Then Exit Function
286
 
287
		' Determine length
288
		llngLength = llngEnd - llngStart
289
 
290
		' Pull out content type
291
		' Convert to unicode
292
		' Trim out whitespace
293
		' Return results
294
		ParseContentType = Trim(CStrU(MidB(pbinChunk, llngStart, llngLength)))
295
 
296
	End Function
297
' ------------------------------------------------------------------------------
298
	Private Function ParseDisposition(ByRef pbinChunk)
299
 
300
		' Parses the content-disposition from a chunk of data
301
		'
302
		' Example:
303
		'
304
		'	Content-Disposition: form-data: name="File1"; filename="C:\Photo.gif"
305
		'
306
		'	Would Return:
307
		'		form-data: name="File1"; filename="C:\Photo.gif"
308
 
309
		Dim llngStart	' Start Position
310
		Dim llngEnd		' End Position
311
		Dim llngLength	' Length
312
 
313
		' Find first occurance of a line starting with Content-Disposition:
314
		llngStart = InStrB(1, pbinChunk, CRLF & CStrB("Content-Disposition:"), vbTextCompare)
315
 
316
		' If not found, return nothing
317
		If llngStart = 0 Then Exit Function
318
 
319
		' Find the end of the line
320
		llngEnd = InStrB(llngStart + 22, pbinChunk, CRLF)
321
 
322
		' If not found, return nothing
323
		If llngEnd = 0 Then Exit Function
324
 
325
		' Adjust start position to start after the text "Content-Disposition:"
326
		llngStart = llngStart + 22
327
 
328
		' If the start position is the same or past the end, return nothing
329
		If llngStart >= llngEnd Then Exit Function
330
 
331
		' Determine Length
332
		llngLength = llngEnd - llngStart
333
 
334
		' Pull out content disposition
335
		' Convert to Unicode
336
		' Return Results
337
		ParseDisposition = CStrU(MidB(pbinChunk, llngStart, llngLength))
338
 
339
	End Function
340
' ------------------------------------------------------------------------------
341
	Private Function ParseName(ByRef pstrDisposition)
342
 
343
		' Parses the name of the field from the content disposition
344
		'
345
		' Example
346
		'
347
		'	form-data: name="File1"; filename="C:\Photo.gif"
348
		'
349
		'	Would Return:
350
		'		File1
351
 
352
		Dim llngStart	' Start Position
353
		Dim llngEnd		' End Position
354
		Dim llngLength	' Length
355
 
356
		' Find first occurance of text name="
357
		llngStart = InStr(1, pstrDisposition, "name=""", vbTextCompare)
358
 
359
		' If not found, return nothing
360
		If llngStart = 0 Then Exit Function
361
 
362
		' Find the closing quote
363
		llngEnd = InStr(llngStart + 6, pstrDisposition, """")
364
 
365
		' If not found, return nothing
366
		If llngEnd = 0 Then Exit Function
367
 
368
		' Adjust start position to start after the text name="
369
		llngStart = llngStart + 6
370
 
371
		' If the start position is the same or past the end, return nothing
372
		If llngStart >= llngEnd Then Exit Function
373
 
374
		' Determine Length
375
		llngLength = llngEnd - llngStart
376
 
377
		' Pull out field name
378
		' Return results
379
		ParseName = Mid(pstrDisposition, llngStart, llngLength)
380
 
381
	End Function
382
' ------------------------------------------------------------------------------
383
	Private Function ParseFileName(ByRef pstrDisposition)
384
		' Parses the name of the field from the content disposition
385
		'
386
		' Example
387
		'
388
		'	form-data: name="File1"; filename="C:\Photo.gif"
389
		'
390
		'	Would Return:
391
		'		C:\Photo.gif
392
 
393
		Dim llngStart	' Start Position
394
		Dim llngEnd		' End Position
395
		Dim llngLength	' Length
396
 
397
		' Find first occurance of text filename="
398
		llngStart = InStr(1, pstrDisposition, "filename=""", vbTextCompare)
399
 
400
		' If not found, return nothing
401
		If llngStart = 0 Then Exit Function
402
 
403
		' Find the closing quote
404
		llngEnd = InStr(llngStart + 10, pstrDisposition, """")
405
 
406
		' If not found, return nothing
407
		If llngEnd = 0 Then Exit Function
408
 
409
		' Adjust start position to start after the text filename="
410
		llngStart = llngStart + 10
411
 
412
		' If the start position is the same of past the end, return nothing
413
		If llngStart >= llngEnd Then Exit Function
414
 
415
		' Determine length
416
		llngLength = llngEnd - llngStart
417
 
418
		' Pull out file name
419
		' Return results
420
		ParseFileName = Mid(pstrDisposition, llngStart, llngLength)
421
 
422
	End Function
423
' ------------------------------------------------------------------------------
424
	Public Property Get Count()
425
 
426
		' Return number of fields found
427
		Count = mlngCount
428
 
429
	End Property
430
' ------------------------------------------------------------------------------
431
 
432
	Public Default Property Get Fields(ByVal pstrName)
433
 
434
		Dim llngIndex	' Index of current field
435
 
436
		' If a number was passed
437
		If IsNumeric(pstrName) Then
438
 
439
			llngIndex = CLng(pstrName)
440
 
441
			' If programmer requested an invalid number
442
			If llngIndex > mlngCount - 1 Or llngIndex < 0 Then
443
				' Raise an error
444
				Call Err.Raise(vbObjectError + 1, "clsUpload.asp", "Object does not exist within the ordinal reference.")
445
				Exit Property
446
			End If
447
 
448
			' Return the field class for the index specified
449
			Set Fields = mobjFieldAry(pstrName)
450
 
451
		' Else a field name was passed
452
		Else
453
 
454
			' convert name to lowercase
455
			pstrName = LCase(pstrname)
456
 
457
			' Loop through each field
458
			For llngIndex = 0 To mlngCount - 1
459
 
460
				' If name matches current fields name in lowercase
461
				If LCase(mobjFieldAry(llngIndex).Name) = pstrName Then
462
 
463
					' Return Field Class
464
					Set Fields = mobjFieldAry(llngIndex)
465
					Exit Property
466
 
467
				End If
468
 
469
			Next
470
 
471
		End If
472
 
473
		' If matches were not found, return an empty field
474
		Set Fields = New clsField
475
 
476
'		' ERROR ON NonExistant:
477
'		' If matches were not found, raise an error of a non-existent field
478
'		Call Err.Raise(vbObjectError + 1, "clsUpload.asp", "Object does not exist within the ordinal reference.")
479
'		Exit Property
480
 
481
	End Property
482
' ------------------------------------------------------------------------------
483
	Private Sub Class_Terminate()
484
 
485
		' This event is called when you destroy the class.
486
		'
487
		' Example:
488
		'	Set objUpload = Nothing
489
		'
490
		' Example:
491
		'	Response.End
492
		'
493
		' Example:
494
		'	Page finnishes executing ...
495
 
496
		Dim llngIndex	' Current Field Index
497
 
498
		' Loop through fields
499
		For llngIndex = 0 To mlngCount - 1
500
 
501
			' Release field object
502
			Set mobjFieldAry(llngIndex) = Nothing
503
 
504
		Next
505
 
506
		' Redimension array and remove all data within
507
		ReDim mobjFieldAry(-1)
508
 
509
	End Sub
510
' ------------------------------------------------------------------------------
511
	Private Sub Class_Initialize()
512
 
513
		' This event is called when you instantiate the class.
514
		'
515
		' Example:
516
		'	Set objUpload = New clsUpload
517
 
518
		' Redimension array with nothing
519
		ReDim mobjFieldAry(-1)
520
 
521
		' Compile ANSI equivilants of carriage returns and line feeds
522
 
523
		CR = ChrB(Asc(vbCr))	' vbCr		Carriage Return
524
		LF = ChrB(Asc(vbLf))	' vbLf		Line Feed
525
		CRLF = CR & LF			' vbCrLf	Carriage Return & Line Feed
526
 
527
		' Set field count to zero
528
		mlngCount = 0
529
 
530
		' Request data
531
		Call RequestData
532
 
533
		' Parse out the delimiter
534
		Call ParseDelimiter()
535
 
536
		' Parse the data
537
		Call ParseData
538
 
539
	End Sub
540
' ------------------------------------------------------------------------------
541
	Private Function CStrU(ByRef pstrANSI)
542
 
543
		' Converts an ANSI string to Unicode
544
		' Best used for small strings
545
 
546
		Dim llngLength	' Length of ANSI string
547
		Dim llngIndex	' Current position
548
 
549
		' determine length
550
		llngLength = LenB(pstrANSI)
551
 
552
		' Loop through each character
553
		For llngIndex = 1 To llngLength
554
 
555
			' Pull out ANSI character
556
			' Get Ascii value of ANSI character
557
			' Get Unicode Character from Ascii
558
			' Append character to results
559
			CStrU = CStrU & Chr(AscB(MidB(pstrANSI, llngIndex, 1)))
560
 
561
		Next
562
 
563
	End Function
564
' ------------------------------------------------------------------------------
565
	Private Function CStrB(ByRef pstrUnicode)
566
 
567
		' Converts a Unicode string to ANSI
568
		' Best used for small strings
569
 
570
		Dim llngLength	' Length of ANSI string
571
		Dim llngIndex	' Current position
572
 
573
		' determine length
574
		llngLength = Len(pstrUnicode)
575
 
576
		' Loop through each character
577
		For llngIndex = 1 To llngLength
578
 
579
			' Pull out Unicode character
580
			' Get Ascii value of Unicode character
581
			' Get ANSI Character from Ascii
582
			' Append character to results
583
			CStrB = CStrB & ChrB(Asc(Mid(pstrUnicode, llngIndex, 1)))
584
 
585
		Next
586
 
587
	End Function
588
' ------------------------------------------------------------------------------
589
End Class
590
' ------------------------------------------------------------------------------
591
%>