DCL 3.7.4
Loading...
Searching...
No Matches
HttpFormDataDecoder Class Reference

#include <HttpCollection.h>

Inheritance diagram for HttpFormDataDecoder:
Object

Public Member Functions

 HttpFormDataDecoder (size_t _bufferSize=4096)
virtual ~HttpFormDataDecoder ()
void decode (InputStream &_input, const char *_contentType, size_t _contentLength, ListedStringToStringArrayMap &_mapForm, HttpFormData &_mapFormFile) __DCL_THROWS1(HttpFormDataDecoderException *)
const String warnings () const
Public Member Functions inherited from Object
virtual String toString () const
virtual void destroy ()
String className () const
bool isInstanceOf (const std::type_info &typeinfo) const
virtual const std::type_info & typeInfo () const

Additional Inherited Members

Protected Member Functions inherited from Object
virtual ~Object ()
 Object ()

Detailed Description

Definition at line 147 of file HttpCollection.h.

Constructor & Destructor Documentation

◆ HttpFormDataDecoder()

HttpFormDataDecoder::HttpFormDataDecoder ( size_t _bufferSize = 4096)

◆ ~HttpFormDataDecoder()

HttpFormDataDecoder::~HttpFormDataDecoder ( )
virtual

Definition at line 304 of file HttpCollection.cpp.

305{
306 if (__buffer) {
307 free(__buffer);
308 }
309}

Member Function Documentation

◆ decode()

void HttpFormDataDecoder::decode ( InputStream & _input,
const char * _contentType,
size_t _contentLength,
ListedStringToStringArrayMap & _mapForm,
HttpFormData & _mapFormFile )

Definition at line 311 of file HttpCollection.cpp.

318{
319 __DCL_ASSERT(_contentType != NULL && *_contentType != '\0');
320 __DCL_ASSERT(_contentLength > 0);
321
322 __input = &_input;
323 __contentLength = _contentLength;
324 __remainder = _contentLength;
325
326 ByteString boundary = "--";
327 {
328 ByteString strOrgBoundary = getBoundary(_contentType);
329 if (strOrgBoundary.isEmpty()) {
330 appendWarning(L"Error! invalid boundary");
331 return;
332 }
333 boundary = boundary + strOrgBoundary;
334 }
335
336 __DCL_ASSERT(__bufferSize > (size_t)(boundary.length() + 2));
337
338 __DCL_TRACE1_N(L"boundary[%hs]\n", boundary.data());
339
340 if(!readInput()) {
341 appendWarning(L"Warning! Input data empty");
342 return;
343 }
344
345 bool bNextPart = getFirstBoundary(boundary);
346
347 while(bNextPart) {
348 HttpFormData::PartHeader header;
349 if (!getPartHeader(header)) {
350 appendWarning(L"Warning! not found boundary delimiter");
351 break;
352 }
353
354 __DCL_TRACE1_N(L"partHeader %ls\n", header.toString().data());
355
356 // Content-Type: multipart/mixed 이면 위치에서
357 // HttpFormDataDecoder::decode를 재귀적으로 호출한다.
358 // RFC1867에는 2개이상의 파일을 포함할 경우 multipart/mixed
359 // 를 사용한다고 되어 있으나 Microsoft-IE, Netscape Navigator
360 // 모두 그렇게 하고 있지 않고 있다.
361
362 if (header.filename.isEmpty()) {
363 // normal data
364 ByteStringBuilder value;
365
366 char* _begin = NULL;
367 char* _end = NULL;
368 DataState ds = dsNeedMoreData;
369 while((ds = getDataBlock(boundary, _begin, _end)) == dsNeedMoreData) {
370 if (_begin < _end) {
371 value.append(_begin, _end);
372 }
373
374 if (!readInput()) {
375 // EOF : data error
376 break;
377 }
378 }
379
380 if (ds == dsNeedMoreData) {
381 // 데이터 에러: EOF or too small data
382 // 더이상 데이터가 없다. 데이터 에러이다.
383 // 데이터는 무시한다.
384 String strMsg = header.name
385 + L": invalid data, discarded";
386 appendWarning(strMsg);
387 __DCL_TRACE1_N(L"%ls\n", strMsg.data());
388
389 bNextPart = false;
390 }
391 else {
392 // 정상 데이터
393 // 마지막 데이터 추가
394 if (_begin < _end) {
395 value.append(_begin, _end);
396 }
397
398 (_mapForm[header.name]).add(UTF8Decoder::decode(value));
399
400 if (ds == dsBeforeCloseBoundary)
401 bNextPart = false;
402 }
403 }
404 else {
405 // input type=file
406 void* pCallbackData = NULL;
407 String strCallbackError;
408 if (!_mapFormFile.onFileStart(
409 header,
410 &pCallbackData,
411 strCallbackError
412 )) {
413 // callback 시작에서 에러가 발생하면 decoding을 중단한다.
414 throw new HttpFormDataDecoderException(
415 HttpFormDataDecoderException::eFormDataCallbackError,
416 strCallbackError
417 );
418 }
419
420 char* _begin = NULL;
421 char* _end = NULL;
422 DataState ds = dsNeedMoreData;
423 while((ds = getDataBlock(boundary, _begin, _end)) == dsNeedMoreData) {
424 if (_begin < _end) {
425 // 데이터가 있으면
426 if (!_mapFormFile.onFileData(
427 _begin,
428 _end - _begin,
429 pCallbackData,
430 strCallbackError
431 )) {
432 throw new HttpFormDataDecoderException(
433 HttpFormDataDecoderException::eFormDataCallbackError,
434 strCallbackError
435 );
436 }
437 }
438
439 try {
440 if (!readInput()) {
441 // EOF : data error
442 break;
443 }
444 }
445 catch (HttpFormDataDecoderException* e) {
446 if (!_mapFormFile.onFileEnd(
447 header,
448 pCallbackData,
449 false,
450 strCallbackError
451 )) {
452 __DCL_TRACE1(L"HttpFormData::onFileEnd: %ls\n", strCallbackError.data());
453 }
454
455 throw e;
456 }
457 } // end of while
458
459 if (ds == dsNeedMoreData) {
460 // 데이터 에러: EOF or too small data
461 // 더이상 데이터가 없다. 데이터 에러이다.
462 // 읽혀진 데이터는 버린다.
463 String strMsg = header.name
464 + L":\"" + header.filename
465 + L"\": invalid data, discarded";
466
467 appendWarning(strMsg);
468 __DCL_TRACE1_N(L"%ls\n", strMsg.data());
469
470 if (!_mapFormFile.onFileEnd(
471 header,
472 pCallbackData,
473 false,
474 strCallbackError
475 )) {
476 __DCL_TRACE1(L"HttpFormData::onFileEnd: %ls\n", strCallbackError.data());
477 }
478
479 bNextPart = false;
480 }
481 else {
482 // 정상 데이터
483 if (_begin < _end) {
484 if (!_mapFormFile.onFileData(
485 _begin,
486 _end - _begin,
487 pCallbackData,
488 strCallbackError
489 )) {
490 throw new HttpFormDataDecoderException(
491 HttpFormDataDecoderException::eFormDataCallbackError,
492 strCallbackError
493 );
494 }
495 }
496
497 if (!_mapFormFile.onFileEnd(
498 header,
499 pCallbackData,
500 true,
501 strCallbackError
502 )) {
503 throw new HttpFormDataDecoderException(
504 HttpFormDataDecoderException::eFormDataCallbackError,
505 strCallbackError
506 );
507 }
508
509 if (ds == dsBeforeCloseBoundary)
510 bNextPart = false;
511 }
512 }
513 }
514}
#define NULL
Definition Config.h:312
#define __DCL_TRACE1_N(fmt, arg)
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __DCL_ASSERT(expr)
Definition Object.h:394

◆ warnings()

const String HttpFormDataDecoder::warnings ( ) const
inline

Definition at line 170 of file HttpCollection.h.

170{ return __warnings; }

The documentation for this class was generated from the following files: