DCL 4.0
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 148 of file HttpCollection.h.

Constructor & Destructor Documentation

◆ HttpFormDataDecoder()

HttpFormDataDecoder::HttpFormDataDecoder ( size_t _bufferSize = 4096)

◆ ~HttpFormDataDecoder()

HttpFormDataDecoder::~HttpFormDataDecoder ( )
virtual

Definition at line 298 of file HttpCollection.cpp.

299{
300 if (__buffer) {
301 free(__buffer);
302 }
303}

Member Function Documentation

◆ decode()

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

Definition at line 305 of file HttpCollection.cpp.

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

◆ warnings()

const String HttpFormDataDecoder::warnings ( ) const
inline

Definition at line 171 of file HttpCollection.h.

171{ return __warnings; }

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