462 * @param aNetworkReply The QNetworkReply instance for which the http |
540 * @param aNetworkReply The QNetworkReply instance for which the http |
463 * transaction was made |
541 * transaction was made |
464 */ |
542 */ |
465 void SmfTransportManagerUtil::networkReplyFinished ( QNetworkReply *aNetworkReply ) |
543 void SmfTransportManagerUtil::networkReplyFinished ( QNetworkReply *aNetworkReply ) |
466 { |
544 { |
|
545 qDebug()<<"Inside SmfTransportManagerUtil::networkReplyFinished()"; |
|
546 qDebug()<<"QNetworkReply = "<<(long)aNetworkReply; |
|
547 qDebug()<<"QNetworkReply error code = "<<aNetworkReply->error(); |
|
548 |
467 // remove the QNetworkReply instance from the list of outstanding transactions |
549 // remove the QNetworkReply instance from the list of outstanding transactions |
468 int index = m_activeNetwReplyList.indexOf(aNetworkReply); |
550 int index = m_activeNetwReplyList.indexOf(aNetworkReply); |
469 if( index >= 0 ) |
551 if( index >= 0 ) |
470 m_activeNetwReplyList.removeAt(index); |
552 m_activeNetwReplyList.removeAt(index); |
471 |
553 |
472 // indicate the result of transaction to the plugin manager |
554 // indicate the result of transaction to the plugin manager |
473 SmfTransportResult trResult; |
555 SmfTransportResult trResult; |
474 convertErrorType(aNetworkReply->error(), trResult); |
556 convertErrorType(aNetworkReply->error(), trResult); |
475 |
557 |
476 // Store the data received |
558 // Read the response from the device |
|
559 QByteArray response = aNetworkReply->readAll(); |
|
560 qDebug()<<"Response size is = "<<response.size(); |
|
561 #ifdef DETAILEDDEBUGGING |
|
562 qDebug()<<"Response is = "<<QString(response); |
|
563 #endif |
|
564 |
|
565 // Store the number of bytes of data received |
477 bool converted = false; |
566 bool converted = false; |
478 quint64 data = m_settings->value("Received Data").toULongLong(&converted); |
567 quint64 data = m_settings->value("Received Data").toULongLong(&converted); |
479 if(converted) |
568 if(converted) |
480 { |
569 { |
481 data += aNetworkReply->readBufferSize(); |
570 data += response.size(); |
482 m_settings->setValue("Received Data", data); |
571 m_settings->setValue("Received Data", data); |
483 } |
572 } |
484 |
573 |
485 int error = 0; |
574 SmfError error = SmfUnknownError; |
486 QByteArray *arr = NULL; |
575 QByteArray *arr = NULL; |
487 |
576 |
488 // Read the response from the device |
577 #ifdef DETAILEDDEBUGGING |
489 QByteArray response = aNetworkReply->readAll(); |
578 foreach(QByteArray arr, aNetworkReply->rawHeaderList()) |
|
579 qDebug()<<QString(arr)<<" = "<<QString(aNetworkReply->rawHeader(arr)); |
|
580 #endif |
490 |
581 |
491 // Check if the http response header has the raw header "Content-Encoding:gzip" |
582 // Check if the http response header has the raw header "Content-Encoding:gzip" |
492 // If so, inflate the gzip deflated data |
583 bool gzipEncoded = false; |
493 QByteArray headerKey("Content-Encoding"); |
584 QByteArray headerKey("Content-Encoding"); |
494 if(aNetworkReply->hasRawHeader(headerKey)) |
585 if(aNetworkReply->hasRawHeader(headerKey)) |
495 { |
586 { |
496 SmfPluginManager::getInstance()->server()->writeLog("Response is gzip encoded!!!"); |
587 qDebug()<<"Content-Encoding:"<<QString(aNetworkReply->rawHeader(headerKey)); |
|
588 |
|
589 // If http response header has the raw header "Content-Encoding:gzip" |
497 if( "gzip" == QString(aNetworkReply->rawHeader(headerKey))) |
590 if( "gzip" == QString(aNetworkReply->rawHeader(headerKey))) |
|
591 { |
|
592 QByteArray firstByte(1, response[0]); |
|
593 QByteArray secondByte(1, response[1]); |
|
594 |
|
595 #ifdef DETAILEDDEBUGGING |
|
596 qDebug()<<"first byte : "<<QString(firstByte.toHex()); |
|
597 qDebug()<<"second byte : "<<QString(secondByte.toHex()); |
|
598 #endif |
|
599 |
|
600 // And the header says the response is a valid gzip data. |
|
601 // If so, inflate the gzip deflated data |
|
602 if((QString("1f") == QString(firstByte.toHex())) && (QString("8b") == QString(secondByte.toHex())) ) |
|
603 { |
|
604 gzipEncoded = true; |
|
605 qDebug()<<"Response is gzip encoded!!!"; |
498 arr = inflateResponse(response, error); |
606 arr = inflateResponse(response, error); |
|
607 if(!arr) |
|
608 trResult = SmfTransportOpGzipError; |
|
609 } |
499 else |
610 else |
500 SmfPluginManager::getInstance()->server()->writeLog("Unsupported encoding format!!! - error"); |
611 { |
501 } |
612 qDebug()<<"Header says gzip encoded, but response is not a valid data, so ignoring the header!!!"; |
|
613 arr = new QByteArray(response); |
|
614 } |
|
615 } |
|
616 else |
|
617 { |
|
618 qDebug()<<"Unsupported encoding format!!! - error"; |
|
619 trResult = SmfTransportOpUnsupportedContentEncodingFormat; |
|
620 } |
|
621 } |
|
622 |
502 else |
623 else |
503 SmfPluginManager::getInstance()->server()->writeLog("Response is not gzip encoded"); |
624 { |
504 |
625 qDebug()<<"Response is not gzip encoded"; |
|
626 arr = new QByteArray(response); |
|
627 } |
|
628 |
|
629 // Write the uncompressed data to a file |
|
630 #ifdef DETAILEDDEBUGGING |
|
631 if(arr) |
|
632 { |
|
633 QFile file1("c:\\data\\networkResponse.txt"); |
|
634 if (!file1.open(QIODevice::WriteOnly)) |
|
635 qDebug()<<"File to write the network response could not be opened"; |
|
636 file1.write(*arr); |
|
637 file1.close(); |
|
638 } |
|
639 #endif |
505 |
640 |
506 SmfPluginManager::getInstance()->responseAvailable ( trResult, aNetworkReply, arr ); |
641 SmfPluginManager::getInstance()->responseAvailable ( trResult, aNetworkReply, arr ); |
507 } |
642 } |
508 |
643 |
509 |
644 |
510 /** |
645 /** |
511 * Method to deflate a gzipped network response. Once this method is called, |
646 * Method to inflate a gzipped network response. |
512 * QNetworkReply internal buffer for holding network response is emptied. |
647 * @param aResponse The QByteArray holding the gzip encoded data |
513 * @param aResponse The QByteArray instance holding the gzip encoded data |
|
514 * @param aError Argument indicating error |
648 * @param aError Argument indicating error |
515 * @return a QByteArray* containing the deflated data. If deflating fails, |
649 * @return a QByteArray* containing the inflated data. If inflation fails, |
516 * the encoded data itself without deflation is returned. |
650 * NULL is returned |
517 */ |
651 */ |
518 QByteArray* SmfTransportManagerUtil::inflateResponse ( QByteArray &aResponse, int& aError ) |
652 QByteArray* SmfTransportManagerUtil::inflateResponse ( QByteArray &aResponse, SmfError& aError ) |
519 { |
653 { |
520 Q_UNUSED(aError) |
654 qDebug()<<"Inside SmfTransportManagerUtil::inflateResponse()"; |
|
655 |
521 // Read the response from the device |
656 // Read the response from the device |
522 SmfPluginManager::getInstance()->server()->writeLog("Encoded response content = "+QString(aResponse.toHex())); |
657 qDebug()<<"Encoded response content size = "<<aResponse.size(); |
523 SmfPluginManager::getInstance()->server()->writeLog("Encoded response content size = "+QString::number(aResponse.size(), 10)); |
658 |
|
659 if(aResponse.size() <= 0) |
|
660 { |
|
661 aError = SmfTMUnknownContentError; |
|
662 return NULL; |
|
663 } |
524 |
664 |
525 // Get the uncompressed size of the response (last 4 bytes of the compressed data as per GZIP format spec) |
665 // Get the uncompressed size of the response (last 4 bytes of the compressed data as per GZIP format spec) |
526 QByteArray sizeStr; |
666 QByteArray sizeStr; |
527 for(int count = 1 ; count <= 4 ; count++) |
667 for(int count = 1 ; count <= 4 ; count++) |
528 sizeStr.append(aResponse[aResponse.size()-count]); |
668 sizeStr.append(aResponse[aResponse.size()-count]); |
529 SmfPluginManager::getInstance()->server()->writeLog("Size string as a string = "+QString(sizeStr.toHex())); |
669 qDebug()<<"Size string as a string = "<<QString(sizeStr.toHex()); |
530 bool ok = false; |
670 bool ok = false; |
531 int uncomSize = sizeStr.toHex().toInt(&ok, 16); |
671 int uncomSize = sizeStr.toHex().toInt(&ok, 16); |
532 SmfPluginManager::getInstance()->server()->writeLog("Size of uncompressed data = "+QString::number(uncomSize, 10)); |
672 qDebug()<<"Size of uncompressed data = "<<uncomSize; |
533 |
673 |
534 // Initialize the data required for zlib method call |
674 // Initialize the data required for zlib method call |
535 z_stream stream; |
675 z_stream stream; |
536 unsigned char *out = new unsigned char[uncomSize]; |
676 unsigned char *out = new unsigned char[uncomSize]; |
537 if(out) |
677 if(out) |
538 SmfPluginManager::getInstance()->server()->writeLog("Memory allocated for output buffer"); |
678 qDebug()<<"Memory allocated for output buffer"; |
539 else |
679 else |
540 { |
680 { |
541 //Error |
681 //Error |
542 SmfPluginManager::getInstance()->server()->writeLog("Memory not allocated for output buffer!!!"); |
682 qDebug()<<"Memory not allocated for output buffer!!!"; |
|
683 aError = SmfMemoryAllocationFailure; |
543 return NULL; |
684 return NULL; |
544 } |
685 } |
545 stream.zalloc = Z_NULL; |
686 stream.zalloc = Z_NULL; |
546 stream.zfree = Z_NULL; |
687 stream.zfree = Z_NULL; |
547 stream.opaque = Z_NULL; |
688 stream.opaque = Z_NULL; |
548 stream.avail_in = 0; |
689 stream.avail_in = 0; |
549 stream.next_in = Z_NULL; |
690 stream.next_in = Z_NULL; |
550 |
691 |
551 int ret = inflateInit2(&stream, 16+MAX_WBITS); |
692 int ret = inflateInit2(&stream, 16+MAX_WBITS); |
552 SmfPluginManager::getInstance()->server()->writeLog("return value of inflateInit2() = "+QString::number(ret, 10)); |
693 qDebug()<<"return value of inflateInit2() = "<<ret; |
553 if(Z_OK != ret) |
694 if(Z_OK != ret) |
554 { |
695 { |
555 SmfPluginManager::getInstance()->server()->writeLog("Error in inflateInit2, returning..."); |
696 qDebug()<<"Error in inflateInit2, returning..."; |
556 delete[] out; |
697 delete[] out; |
|
698 if(Z_STREAM_ERROR == ret) |
|
699 aError = SmfTMGzipStreamError; |
|
700 else if(Z_MEM_ERROR == ret) |
|
701 aError = SmfTMGzipMemoryError; |
|
702 else if(Z_DATA_ERROR == ret) |
|
703 aError = SmfTMGzipDataError; |
|
704 else |
|
705 aError = SmfUnknownError; |
557 return NULL; |
706 return NULL; |
558 } |
707 } |
559 |
708 |
560 // Initialize the data required for inflate() method call |
709 // Initialize the data required for inflate() method call |
561 stream.avail_in = aResponse.size(); |
710 stream.avail_in = aResponse.size(); |
562 stream.next_in = (unsigned char *)aResponse.data(); |
711 stream.next_in = (unsigned char *)aResponse.data(); |
563 stream.avail_out = uncomSize; |
712 stream.avail_out = uncomSize; |
564 stream.next_out = out; |
713 stream.next_out = out; |
565 |
714 |
566 ret = inflate(&stream, Z_NO_FLUSH); |
715 ret = inflate(&stream, Z_NO_FLUSH); |
567 SmfPluginManager::getInstance()->server()->writeLog("return value of inflate() = "+QString::number(ret, 10)); |
716 qDebug()<<"return value of inflate() = "<<ret; |
568 |
717 |
569 switch (ret) |
718 switch (ret) |
570 { |
719 { |
571 // fall through |
720 // fall through |
572 case Z_NEED_DICT: |
721 case Z_NEED_DICT: |
573 case Z_DATA_ERROR: |
722 case Z_DATA_ERROR: |
574 case Z_MEM_ERROR: |
723 case Z_MEM_ERROR: |
575 { |
724 { |
576 (void)inflateEnd(&stream); |
725 (void)inflateEnd(&stream); |
577 delete[] out; |
726 delete[] out; |
|
727 aError = SmfTMGzipDataError; |
578 return NULL; |
728 return NULL; |
579 } |
729 } |
580 } |
730 } |
581 |
731 |
582 SmfPluginManager::getInstance()->server()->writeLog("total bytes read so far = "+QString::number(stream.total_in, 10)); |
732 qDebug()<<"total bytes read so far = "<<stream.total_in; |
583 SmfPluginManager::getInstance()->server()->writeLog("total bytes output so far = "+QString::number(stream.total_out, 10)); |
733 qDebug()<<"total bytes output so far = "<<stream.total_out; |
584 |
734 |
585 // Write the inflated data to a QByteArray |
735 // Write the inflated data to a QByteArray |
586 QByteArray *uncompressedData = new QByteArray((char *)out); |
736 QByteArray *uncompressedData = new QByteArray((char *)out, stream.total_out); |
587 delete[] out; |
737 delete[] out; |
588 |
738 |
589 // If there is some unwanted data at the end of uncompressed data, chop them |
739 // If there is some unwanted data at the end of uncompressed data, chop them |
590 int chopLength = uncompressedData->size() - uncomSize; |
740 int chopLength = uncompressedData->size() - uncomSize; |
591 SmfPluginManager::getInstance()->server()->writeLog("uncompressedData before chopping = "+QString(uncompressedData->toHex())); |
741 qDebug()<<"old size of uncompressed data = "<<uncompressedData->size(); |
592 SmfPluginManager::getInstance()->server()->writeLog("old size of uncompressed data = "+QString::number(uncompressedData->size(), 10)); |
|
593 uncompressedData->chop(chopLength); |
742 uncompressedData->chop(chopLength); |
594 SmfPluginManager::getInstance()->server()->writeLog("new size of uncompressed data = "+QString::number(uncompressedData->size(), 10)); |
743 qDebug()<<"new size of uncompressed data = "<<uncompressedData->size(); |
595 SmfPluginManager::getInstance()->server()->writeLog("uncompressedData after chopping = "+QString(uncompressedData->toHex())); |
|
596 |
|
597 // Write the uncompressed data to a file |
|
598 QFile file1("c:\\data\\uncompressedflickrresponse.txt"); |
|
599 if (!file1.open(QIODevice::WriteOnly)) |
|
600 SmfPluginManager::getInstance()->server()->writeLog("File to write the uncompressed response could not be opened"); |
|
601 file1.write(uncompressedData->data()); |
|
602 file1.close(); |
|
603 SmfPluginManager::getInstance()->server()->writeLog("uncompressed data written to c:\\data\\uncompressedflickrresponse.txt"); |
|
604 |
744 |
605 return uncompressedData; |
745 return uncompressedData; |
606 } |
746 } |
|
747 |
|
748 |
|
749 /** |
|
750 * Method to deflate a network request to gzip format. |
|
751 * @param aResponse The QByteArray that has to be gzipped |
|
752 * @param aError Argument indicating error |
|
753 * @return a QByteArray* containing the deflated data. If deflation fails, |
|
754 * NULL is returned |
|
755 */ |
|
756 QByteArray* SmfTransportManagerUtil::deflateRequest( QByteArray &aResponse, SmfError& aError ) |
|
757 { |
|
758 qDebug()<<"Inside SmfTransportManagerUtil::deflateRequest()"; |
|
759 |
|
760 if(aResponse.size() <= 0) |
|
761 { |
|
762 aError = SmfTMUnknownContentError; |
|
763 return NULL; |
|
764 } |
|
765 |
|
766 // Initialize the data required for zlib initialize method call |
|
767 z_stream stream; |
|
768 stream.zalloc = Z_NULL; |
|
769 stream.zfree = Z_NULL; |
|
770 stream.opaque = Z_NULL; |
|
771 stream.next_in = (unsigned char *)aResponse.data(); |
|
772 stream.avail_in = aResponse.size(); |
|
773 stream.total_out = 0; |
|
774 |
|
775 int level = Z_DEFAULT_COMPRESSION; |
|
776 int method = Z_DEFLATED; |
|
777 int windowBits = 16+MAX_WBITS; |
|
778 int mem_level = 8; |
|
779 int strategy = Z_DEFAULT_STRATEGY; |
|
780 |
|
781 // Call deflateInit2 for gzip compression initialization |
|
782 int initError = deflateInit2(&stream, level, method, windowBits, mem_level, strategy); |
|
783 qDebug()<<"Return value of deflateInit2() = "<<initError; |
|
784 qDebug()<<"Error msg if any = "<<QString(zError(initError)); |
|
785 |
|
786 if(Z_OK != initError) |
|
787 { |
|
788 qDebug()<<"deflateInit2() failed, returning error = "<<QString(zError(initError)); |
|
789 |
|
790 if(Z_STREAM_ERROR == initError) |
|
791 aError = SmfTMGzipStreamError; |
|
792 else if(Z_MEM_ERROR == initError) |
|
793 aError = SmfTMGzipMemoryError; |
|
794 else if(Z_DATA_ERROR == initError) |
|
795 aError = SmfTMGzipDataError; |
|
796 else |
|
797 aError = SmfUnknownError; |
|
798 return NULL; |
|
799 } |
|
800 |
|
801 // Initialize the data required for inflate() method call |
|
802 int out_size = (int)((aResponse.size()*1.01)+17); |
|
803 unsigned char *out = new unsigned char[out_size]; |
|
804 if(out) |
|
805 { |
|
806 qDebug()<<"Memory allocated for output buffer with size = "<<out_size; |
|
807 memset(out, 0, out_size); |
|
808 } |
|
809 else |
|
810 { |
|
811 //Error |
|
812 qDebug()<<"Memory not allocated for output buffer!!!"; |
|
813 |
|
814 deflateEnd(&stream); |
|
815 aError = SmfTMGzipDataError; |
|
816 return NULL; |
|
817 } |
|
818 |
|
819 stream.next_out = out; |
|
820 stream.avail_out = out_size; |
|
821 |
|
822 #ifdef DETAILEDDEBUGGING |
|
823 qDebug()<<"Before calling deflate()"; |
|
824 qDebug()<<"next_in = "<<(long)stream.next_in; |
|
825 qDebug()<<"avail_in = "<<stream.avail_in; |
|
826 qDebug()<<"next_out = "<<(long)stream.next_out; |
|
827 qDebug()<<"avail_out = "<<stream.avail_out; |
|
828 qDebug()<<"total_in = "<<stream.total_in; |
|
829 qDebug()<<"total_out = "<<stream.total_out; |
|
830 #endif |
|
831 |
|
832 int deflateStatus; |
|
833 do |
|
834 { |
|
835 stream.next_out = out + stream.total_out; |
|
836 stream.avail_out = out_size - stream.total_out; |
|
837 |
|
838 deflateStatus = deflate(&stream, Z_FINISH); |
|
839 qDebug()<<"Return value of deflate() is = "<<deflateStatus; |
|
840 qDebug()<<"Error msg if any = "<<QString(zError(deflateStatus)); |
|
841 |
|
842 #ifdef DETAILEDDEBUGGING |
|
843 qDebug()<<"avail_in = "<<stream.avail_in; |
|
844 qDebug()<<"avail_out = "<<stream.avail_out; |
|
845 qDebug()<<"total_in = "<<stream.total_in; |
|
846 qDebug()<<"total_out = "<<stream.total_out; |
|
847 #endif |
|
848 |
|
849 }while(Z_OK == deflateStatus); |
|
850 |
|
851 if (Z_STREAM_END != deflateStatus) |
|
852 { |
|
853 QString errorMsg; |
|
854 switch (deflateStatus) |
|
855 { |
|
856 case Z_ERRNO: |
|
857 errorMsg.append("Error occured while reading file."); |
|
858 aError = SmfUnknownError; |
|
859 break; |
|
860 case Z_STREAM_ERROR: |
|
861 errorMsg.append("The stream state was inconsistent (e.g., next_in or next_out was NULL)."); |
|
862 aError = SmfTMGzipStreamError; |
|
863 break; |
|
864 case Z_DATA_ERROR: |
|
865 errorMsg.append("The deflate data was invalid or incomplete."); |
|
866 aError = SmfTMGzipDataError; |
|
867 break; |
|
868 case Z_MEM_ERROR: |
|
869 errorMsg.append("Memory could not be allocated for processing."); |
|
870 aError = SmfTMGzipMemoryError; |
|
871 break; |
|
872 case Z_BUF_ERROR: |
|
873 errorMsg.append("Ran out of output buffer for writing compressed bytes."); |
|
874 aError = SmfTMGzipMemoryError; |
|
875 break; |
|
876 case Z_VERSION_ERROR: |
|
877 errorMsg.append("The version of zlib.h and the version of the library linked do not match."); |
|
878 aError = SmfUnknownError; |
|
879 break; |
|
880 default: |
|
881 errorMsg.append("Unknown error code."); |
|
882 aError = SmfUnknownError; |
|
883 } |
|
884 |
|
885 qDebug()<<"Error string for deflate() is = "<<errorMsg; |
|
886 |
|
887 // Free data structures that were dynamically created for the stream. |
|
888 deflateEnd(&stream); |
|
889 |
|
890 return NULL; |
|
891 } |
|
892 |
|
893 int retVal = deflateEnd(&stream); |
|
894 qDebug()<<"Return value of deflateEnd() = "<<retVal; |
|
895 qDebug()<<"Error msg if any = "<<QString(zError(retVal)); |
|
896 |
|
897 #ifdef DETAILEDDEBUGGING |
|
898 /*QByteArray byteArray; |
|
899 for (int i=0; i<stream.total_out;i++) |
|
900 { |
|
901 QString str(out[i]); |
|
902 byteArray.clear(); |
|
903 byteArray.append(str.toAscii()); |
|
904 qDebug()<<QString("out[%1] = '%2'").arg(i).arg(QString(byteArray.toHex())); |
|
905 }*/ |
|
906 #endif |
|
907 |
|
908 // Write the inflated data to a QByteArray |
|
909 QByteArray *compressedData = new QByteArray((char*)out, stream.total_out); |
|
910 delete[] out; |
|
911 qDebug()<<"Number of bytes of compressed data = "<<compressedData->size(); |
|
912 |
|
913 #ifdef DETAILEDDEBUGGING |
|
914 qDebug()<<"compressed data = "<<QString(compressedData->toHex()); |
|
915 #endif |
|
916 |
|
917 return compressedData; |
|
918 } |
|
919 |
|
920 |
607 |
921 |
608 /** |
922 /** |
609 * Method called when the QNetworkReply detects an error in processing. |
923 * Method called when the QNetworkReply detects an error in processing. |
610 * @param aError The QNetworkReply error code |
924 * @param aError The QNetworkReply error code |
611 */ |
925 */ |
612 void SmfTransportManagerUtil::networkReplyError ( QNetworkReply::NetworkError aError ) |
926 void SmfTransportManagerUtil::networkReplyError ( QNetworkReply::NetworkError aError ) |
613 { |
927 { |
|
928 qDebug()<<"Inside SmfTransportManagerUtil::networkReplyError()"; |
|
929 |
614 // indicate the error to the plugin manager |
930 // indicate the error to the plugin manager |
615 SmfTransportResult trResult; |
931 SmfTransportResult trResult; |
616 convertErrorType(aError, trResult); |
932 convertErrorType(aError, trResult); |
617 |
933 |
618 SmfPluginManager::getInstance()->responseAvailable ( trResult, NULL, NULL ); |
934 SmfPluginManager::getInstance()->responseAvailable ( trResult, NULL, NULL ); |