Subversion Repositories DevTools

Rev

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