// Copyright 2017-2020 David Romanski(Socke). All Rights Reserved. #include "WebCommunicationBPLibrary.h" UWebCommunicationBPLibrary* UWebCommunicationBPLibrary::webcom; UWebCommunicationBPLibrary::UWebCommunicationBPLibrary(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { webcom = this; //Delegates example onhttpRequestCompleteDelegate.AddDynamic(this, &UWebCommunicationBPLibrary::httpRequestCompleteDelegate); //onhttpFileDownloadDelegate.AddDynamic(this, &UWebCommunicationBPLibrary::httpFileDownloadDelegate); //onhttpFileUploadDelegate.AddDynamic(this, &UWebCommunicationBPLibrary::httpFileUploadDelegate); struct ExtensionToMimeMapping { char const* extension; char const* mimeType; }; //found in /etc/mime.types on my linux server ExtensionToMimeMapping mappings[] = { {"ez", "application/andrew-inset"}, {"anx", "application/annodex"}, {"atom", "application/atom+xml"}, {"atomcat", "application/atomcat+xml"}, {"atomsrv", "application/atomserv+xml"}, {"lin", "application/bbolin"}, {"cu", "application/cu-seeme"}, {"davmount", "application/davmount+xml"}, {"dcm", "application/dicom"}, {"tsp", "application/dsptype"}, {"es", "application/ecmascript"}, {"spl", "application/futuresplash"}, {"hta", "application/hta"}, {"jar", "application/java-archive"}, {"ser", "application/java-serialized-object"}, {"class", "application/java-vm"}, {"js", "application/javascript"}, {"json", "application/json"}, {"m3g", "application/m3g"}, {"hqx", "application/mac-binhex40"}, {"cpt", "application/mac-compactpro"}, {"nb", "application/mathematica"}, {"nbp", "application/mathematica"}, {"mbox", "application/mbox"}, {"mdb", "application/msaccess"}, {"doc", "application/msword"}, {"dot", "application/msword"}, {"mxf", "application/mxf"}, {"bin", "application/octet-stream"}, {"oda", "application/oda"}, {"ogx", "application/ogg"}, {"one", "application/onenote"}, {"onetoc2", "application/onenote"}, {"onetmp", "application/onenote"}, {"onepkg", "application/onenote"}, {"pdf", "application/pdf"}, {"pgp", "application/pgp-encrypted"}, {"key", "application/pgp-keys"}, {"sig", "application/pgp-signature"}, {"prf", "application/pics-rules"}, {"ps", "application/postscript"}, {"ai", "application/postscript"}, {"eps", "application/postscript"}, {"epsi", "application/postscript"}, {"epsf", "application/postscript"}, {"eps2", "application/postscript"}, {"eps3", "application/postscript"}, {"rar", "application/rar"}, {"rdf", "application/rdf+xml"}, {"rtf", "application/rtf"}, {"stl", "application/sla"}, {"smi", "application/smil"}, {"smil", "application/smil"}, {"xhtml", "application/xhtml+xml"}, {"xht", "application/xhtml+xml"}, {"xml", "application/xml"}, {"xsl", "application/xml"}, {"xsd", "application/xml"}, {"xspf", "application/xspf+xml"}, {"zip", "application/zip"}, {"xlam", "application/vnd.ms-excel.addin.macroEnabled.12"}, {"xlsb", "application/vnd.ms-excel.sheet.binary.macroEnabled.12"}, {"xlsm", "application/vnd.ms-excel.sheet.macroEnabled.12"}, {"xltm", "application/vnd.ms-excel.template.macroEnabled.12"}, {"ppam", "application/vnd.ms-powerpoint.addin.macroEnabled.12"}, {"pptm", "application/vnd.ms-powerpoint.presentation.macroEnabled.12"}, {"sldm", "application/vnd.ms-powerpoint.slide.macroEnabled.12"}, {"ppsm", "application/vnd.ms-powerpoint.slideshow.macroEnabled.12"}, {"potm", "application/vnd.ms-powerpoint.template.macroEnabled.12"}, {"docm", "application/vnd.ms-word.document.macroEnabled.12"}, {"dotm", "application/vnd.ms-word.template.macroEnabled.12"}, {"odc", "application/vnd.oasis.opendocument.chart"}, {"odb", "application/vnd.oasis.opendocument.database"}, {"odf", "application/vnd.oasis.opendocument.formula"}, {"odg", "application/vnd.oasis.opendocument.graphics"}, {"otg", "application/vnd.oasis.opendocument.graphics-template"}, {"odi", "application/vnd.oasis.opendocument.image"}, {"odp", "application/vnd.oasis.opendocument.presentation"}, {"otp", "application/vnd.oasis.opendocument.presentation-template"}, {"ods", "application/vnd.oasis.opendocument.spreadsheet"}, {"ots", "application/vnd.oasis.opendocument.spreadsheet-template"}, {"odm", "application/vnd.oasis.opendocument.text-master"}, {"ott", "application/vnd.oasis.opendocument.text-template"}, {"oth", "application/vnd.oasis.opendocument.text-web"}, {"pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"}, {"sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide"}, {"ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"}, {"potx", "application/vnd.openxmlformats-officedocument.presentationml.template"}, {"xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, {"xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, {"xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"}, {"xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"}, {"docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, {"dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"}, {"sgl", "application/vnd.stardivision.writer-global"}, {"sti", "application/vnd.sun.xml.impress.template"}, {"wk", "application/x-123"}, {"7z", "application/x-7z-compressed"}, {"abw", "application/x-abiword"}, {"dmg", "application/x-apple-diskimage"}, {"bcpio", "application/x-bcpio"}, {"torrent", "application/x-bittorrent"}, {"cab", "application/x-cab"}, {"cbr", "application/x-cbr"}, {"cbz", "application/x-cbz"}, {"cdf", "application/x-cdf"}, {"cda", "application/x-cdf"}, {"vcd", "application/x-cdlink"}, {"pgn", "application/x-chess-pgn"}, {"mph", "application/x-comsol"}, {"cpio", "application/x-cpio"}, {"csh", "application/x-csh"}, {"deb", "application/x-debian-package"}, {"udeb", "application/x-debian-package"}, {"dcr", "application/x-director"}, {"dir", "application/x-director"}, {"dxr", "application/x-director"}, {"dms", "application/x-dms"}, {"wad", "application/x-doom"}, {"dvi", "application/x-dvi"}, {"pfa", "application/x-font"}, {"pfb", "application/x-font"}, {"gsf", "application/x-font"}, {"pcf", "application/x-font"}, {"pcf.Z", "application/x-font"}, {"woff", "application/x-font-woff"}, {"mm", "application/x-freemind"}, {"spl", "application/x-futuresplash"}, {"gan", "application/x-ganttproject"}, {"gnumeric", "application/x-gnumeric"}, {"sgf", "application/x-go-sgf"}, {"gcf", "application/x-graphing-calculator"}, {"gtar", "application/x-gtar"}, {"tgz", "application/x-gtar-compressed"}, {"taz", "application/x-gtar-compressed"}, {"hdf", "application/x-hdf"}, {"rhtml", "#application/x-httpd-eruby"}, {"phtml", "#application/x-httpd-php"}, {"pht", "#application/x-httpd-php"}, {"php", "#application/x-httpd-php"}, {"phps", "#application/x-httpd-php-source"}, {"php3", "#application/x-httpd-php3"}, {"php3p", "#application/x-httpd-php3-preprocessed"}, {"php4", "#application/x-httpd-php4"}, {"php5", "#application/x-httpd-php5"}, {"hwp", "application/x-hwp"}, {"ica", "application/x-ica"}, {"info", "application/x-info"}, {"ins", "application/x-internet-signup"}, {"isp", "application/x-internet-signup"}, {"iii", "application/x-iphone"}, {"iso", "application/x-iso9660-image"}, {"jam", "application/x-jam"}, {"jnlp", "application/x-java-jnlp-file"}, {"jmz", "application/x-jmol"}, {"chrt", "application/x-kchart"}, {"kil", "application/x-killustrator"}, {"skp", "application/x-koan"}, {"skd", "application/x-koan"}, {"skt", "application/x-koan"}, {"skm", "application/x-koan"}, {"kpr", "application/x-kpresenter"}, {"kpt", "application/x-kpresenter"}, {"ksp", "application/x-kspread"}, {"kwd", "application/x-kword"}, {"kwt", "application/x-kword"}, {"latex", "application/x-latex"}, {"lha", "application/x-lha"}, {"lyx", "application/x-lyx"}, {"lzh", "application/x-lzh"}, {"lzx", "application/x-lzx"}, {"frm", "application/x-maker"}, {"maker", "application/x-maker"}, {"frame", "application/x-maker"}, {"fm", "application/x-maker"}, {"fb", "application/x-maker"}, {"book", "application/x-maker"}, {"fbdoc", "application/x-maker"}, {"md5", "application/x-md5"}, {"mif", "application/x-mif"}, {"m3u8", "application/x-mpegURL"}, {"wmd", "application/x-ms-wmd"}, {"wmz", "application/x-ms-wmz"}, {"com", "application/x-msdos-program"}, {"exe", "application/x-msdos-program"}, {"bat", "application/x-msdos-program"}, {"dll", "application/x-msdos-program"}, {"msi", "application/x-msi"}, {"nc", "application/x-netcdf"}, {"pac", "application/x-ns-proxy-autoconfig"}, {"dat", "application/x-ns-proxy-autoconfig"}, {"nwc", "application/x-nwc"}, {"o", "application/x-object"}, {"oza", "application/x-oz-application"}, {"p7r", "application/x-pkcs7-certreqresp"}, {"crl", "application/x-pkcs7-crl"}, {"pyc", "application/x-python-code"}, {"pyo", "application/x-python-code"}, {"qgs", "application/x-qgis"}, {"shp", "application/x-qgis"}, {"shx", "application/x-qgis"}, {"qtl", "application/x-quicktimeplayer"}, {"rdp", "application/x-rdp"}, {"rpm", "application/x-redhat-package-manager"}, {"rss", "application/x-rss+xml"}, {"rb", "application/x-ruby"}, {"sci", "application/x-scilab"}, {"sce", "application/x-scilab"}, {"xcos", "application/x-scilab-xcos"}, {"sh", "application/x-sh"}, {"sha1", "application/x-sha1"}, {"shar", "application/x-shar"}, {"swf", "application/x-shockwave-flash"}, {"swfl", "application/x-shockwave-flash"}, {"scr", "application/x-silverlight"}, {"sql", "application/x-sql"}, {"sit", "application/x-stuffit"}, {"sitx", "application/x-stuffit"}, {"sv4cpio", "application/x-sv4cpio"}, {"sv4crc", "application/x-sv4crc"}, {"tar", "application/x-tar"}, {"tcl", "application/x-tcl"}, {"gf", "application/x-tex-gf"}, {"pk", "application/x-tex-pk"}, {"texinfo", "application/x-texinfo"}, {"texi", "application/x-texinfo"}, {"~", "application/x-trash"}, {"%", "application/x-trash"}, {"bak", "application/x-trash"}, {"old", "application/x-trash"}, {"sik", "application/x-trash"}, {"t", "application/x-troff"}, {"tr", "application/x-troff"}, {"roff", "application/x-troff"}, {"man", "application/x-troff-man"}, {"me", "application/x-troff-me"}, {"ms", "application/x-troff-ms"}, {"ustar", "application/x-ustar"}, {"src", "application/x-wais-source"}, {"wz", "application/x-wingz"}, {"crt", "application/x-x509-ca-cert"}, {"xcf", "application/x-xcf"}, {"fig", "application/x-xfig"}, {"xpi", "application/x-xpinstall"}, {"amr", "audio/amr"}, {"awb", "audio/amr-wb"}, {"amr", "audio/amr"}, {"awb", "audio/amr-wb"}, {"axa", "audio/annodex"}, {"au", "audio/basic"}, {"snd", "audio/basic"}, {"csd", "audio/csound"}, {"orc", "audio/csound"}, {"sco", "audio/csound"}, {"flac", "audio/flac"}, {"mid", "audio/midi"}, {"midi", "audio/midi"}, {"kar", "audio/midi"}, {"mpga", "audio/mpeg"}, {"mpega", "audio/mpeg"}, {"mp2", "audio/mpeg"}, {"mp3", "audio/mpeg"}, {"m4a", "audio/mpeg"}, {"m3u", "audio/mpegurl"}, {"oga", "audio/ogg"}, {"ogg", "audio/ogg"}, {"spx", "audio/ogg"}, {"sid", "audio/prs.sid"}, {"aif", "audio/x-aiff"}, {"aiff", "audio/x-aiff"}, {"aifc", "audio/x-aiff"}, {"gsm", "audio/x-gsm"}, {"m3u", "audio/x-mpegurl"}, {"wma", "audio/x-ms-wma"}, {"wax", "audio/x-ms-wax"}, {"ra", "audio/x-pn-realaudio"}, {"rm", "audio/x-pn-realaudio"}, {"ram", "audio/x-pn-realaudio"}, {"ra", "audio/x-realaudio"}, {"pls", "audio/x-scpls"}, {"sd2", "audio/x-sd2"}, {"wav", "audio/x-wav"}, {"alc", "chemical/x-alchemy"}, {"cac", "chemical/x-cache"}, {"cache", "chemical/x-cache"}, {"csf", "chemical/x-cache-csf"}, {"cbin", "chemical/x-cactvs-binary"}, {"cascii", "chemical/x-cactvs-binary"}, {"ctab", "chemical/x-cactvs-binary"}, {"cdx", "chemical/x-cdx"}, {"cer", "chemical/x-cerius"}, {"c3d", "chemical/x-chem3d"}, {"chm", "chemical/x-chemdraw"}, {"cif", "chemical/x-cif"}, {"cmdf", "chemical/x-cmdf"}, {"cml", "chemical/x-cml"}, {"cpa", "chemical/x-compass"}, {"bsd", "chemical/x-crossfire"}, {"csml", "chemical/x-csml"}, {"csm", "chemical/x-csml"}, {"ctx", "chemical/x-ctx"}, {"cxf", "chemical/x-cxf"}, {"cef", "chemical/x-cxf"}, {"smi", "#chemical/x-daylight-smiles"}, {"emb", "chemical/x-embl-dl-nucleotide"}, {"embl", "chemical/x-embl-dl-nucleotide"}, {"spc", "chemical/x-galactic-spc"}, {"inp", "chemical/x-gamess-input"}, {"gam", "chemical/x-gamess-input"}, {"gamin", "chemical/x-gamess-input"}, {"fch", "chemical/x-gaussian-checkpoint"}, {"fchk", "chemical/x-gaussian-checkpoint"}, {"cub", "chemical/x-gaussian-cube"}, {"gau", "chemical/x-gaussian-input"}, {"gjc", "chemical/x-gaussian-input"}, {"gjf", "chemical/x-gaussian-input"}, {"gal", "chemical/x-gaussian-log"}, {"gcg", "chemical/x-gcg8-sequence"}, {"gen", "chemical/x-genbank"}, {"hin", "chemical/x-hin"}, {"istr", "chemical/x-isostar"}, {"ist", "chemical/x-isostar"}, {"jdx", "chemical/x-jcamp-dx"}, {"dx", "chemical/x-jcamp-dx"}, {"kin", "chemical/x-kinemage"}, {"mcm", "chemical/x-macmolecule"}, {"mmd", "chemical/x-macromodel-input"}, {"mmod", "chemical/x-macromodel-input"}, {"mol", "chemical/x-mdl-molfile"}, {"rd", "chemical/x-mdl-rdfile"}, {"rxn", "chemical/x-mdl-rxnfile"}, {"sd", "chemical/x-mdl-sdfile"}, {"sdf", "chemical/x-mdl-sdfile"}, {"tgf", "chemical/x-mdl-tgf"}, {"mif", "#chemical/x-mif"}, {"mcif", "chemical/x-mmcif"}, {"mol2", "chemical/x-mol2"}, {"b", "chemical/x-molconn-Z"}, {"gpt", "chemical/x-mopac-graph"}, {"mop", "chemical/x-mopac-input"}, {"mopcrt", "chemical/x-mopac-input"}, {"mpc", "chemical/x-mopac-input"}, {"zmt", "chemical/x-mopac-input"}, {"moo", "chemical/x-mopac-out"}, {"mvb", "chemical/x-mopac-vib"}, {"asn", "chemical/x-ncbi-asn1"}, {"prt", "chemical/x-ncbi-asn1-ascii"}, {"ent", "chemical/x-ncbi-asn1-ascii"}, {"val", "chemical/x-ncbi-asn1-binary"}, {"aso", "chemical/x-ncbi-asn1-binary"}, {"asn", "chemical/x-ncbi-asn1-spec"}, {"pdb", "chemical/x-pdb"}, {"ent", "chemical/x-pdb"}, {"ros", "chemical/x-rosdal"}, {"sw", "chemical/x-swissprot"}, {"vms", "chemical/x-vamas-iso14976"}, {"vmd", "chemical/x-vmd"}, {"xtel", "chemical/x-xtel"}, {"xyz", "chemical/x-xyz"}, {"gif", "image/gif"}, {"ief", "image/ief"}, {"jpeg", "image/jpeg"}, {"jpg", "image/jpeg"}, {"jpe", "image/jpeg"}, {"pcx", "image/pcx"}, {"png", "image/png"}, {"svg", "image/svg+xml"}, {"svgz", "image/svg+xml"}, {"tiff", "image/tiff"}, {"tif", "image/tiff"}, {"djvu", "image/vnd.djvu"}, {"djv", "image/vnd.djvu"}, {"ico", "image/vnd.microsoft.icon"}, {"wbmp", "image/vnd.wap.wbmp"}, {"cr2", "image/x-canon-cr2"}, {"crw", "image/x-canon-crw"}, {"ras", "image/x-cmu-raster"}, {"cdr", "image/x-coreldraw"}, {"pat", "image/x-coreldrawpattern"}, {"cdt", "image/x-coreldrawtemplate"}, {"cpt", "image/x-corelphotopaint"}, {"erf", "image/x-epson-erf"}, {"art", "image/x-jg"}, {"jng", "image/x-jng"}, {"bmp", "image/x-ms-bmp"}, {"nef", "image/x-nikon-nef"}, {"orf", "image/x-olympus-orf"}, {"psd", "image/x-photoshop"}, {"pnm", "image/x-portable-anymap"}, {"pbm", "image/x-portable-bitmap"}, {"pgm", "image/x-portable-graymap"}, {"ppm", "image/x-portable-pixmap"}, {"rgb", "image/x-rgb"}, {"xbm", "image/x-xbitmap"}, {"xpm", "image/x-xpixmap"}, {"xwd", "image/x-xwindowdump"}, {"eml", "message/rfc822"}, {"igs", "model/iges"}, {"iges", "model/iges"}, {"msh", "model/mesh"}, {"mesh", "model/mesh"}, {"silo", "model/mesh"}, {"wrl", "model/vrml"}, {"vrml", "model/vrml"}, {"x3dv", "model/x3d+vrml"}, {"x3d", "model/x3d+xml"}, {"x3db", "model/x3d+binary"}, {"appcache", "text/cache-manifest"}, {"ics", "text/calendar"}, {"icz", "text/calendar"}, {"css", "text/css"}, {"csv", "text/csv"}, {"323", "text/h323"}, {"html", "text/html"}, {"htm", "text/html"}, {"shtml", "text/html"}, {"uls", "text/iuls"}, {"mml", "text/mathml"}, {"asc", "text/plain"}, {"txt", "text/plain"}, {"text", "text/plain"}, {"pot", "text/plain"}, {"brf", "text/plain"}, {"srt", "text/plain"}, {"rtx", "text/richtext"}, {"sct", "text/scriptlet"}, {"wsc", "text/scriptlet"}, {"tm", "text/texmacs"}, {"tsv", "text/tab-separated-values"}, {"jad", "text/vnd.sun.j2me.app-descriptor"}, {"wml", "text/vnd.wap.wml"}, {"wmls", "text/vnd.wap.wmlscript"}, {"bib", "text/x-bibtex"}, {"boo", "text/x-boo"}, {"h++", "text/x-c++hdr"}, {"hpp", "text/x-c++hdr"}, {"hxx", "text/x-c++hdr"}, {"hh", "text/x-c++hdr"}, {"c++", "text/x-c++src"}, {"cpp", "text/x-c++src"}, {"cxx", "text/x-c++src"}, {"cc", "text/x-c++src"}, {"h", "text/x-chdr"}, {"htc", "text/x-component"}, {"csh", "text/x-csh"}, {"c", "text/x-csrc"}, {"d", "text/x-dsrc"}, {"diff", "text/x-diff"}, {"patch", "text/x-diff"}, {"hs", "text/x-haskell"}, {"java", "text/x-java"}, {"ly", "text/x-lilypond"}, {"lhs", "text/x-literate-haskell"}, {"moc", "text/x-moc"}, {"p", "text/x-pascal"}, {"pas", "text/x-pascal"}, {"gcd", "text/x-pcs-gcd"}, {"pl", "text/x-perl"}, {"pm", "text/x-perl"}, {"py", "text/x-python"}, {"scala", "text/x-scala"}, {"etx", "text/x-setext"}, {"sfv", "text/x-sfv"}, {"sh", "text/x-sh"}, {"tcl", "text/x-tcl"}, {"tk", "text/x-tcl"}, {"tex", "text/x-tex"}, {"ltx", "text/x-tex"}, {"sty", "text/x-tex"}, {"cls", "text/x-tex"}, {"vcs", "text/x-vcalendar"}, {"vcf", "text/x-vcard"}, {"3gp", "video/3gpp"}, {"axv", "video/annodex"}, {"dl", "video/dl"}, {"dif", "video/dv"}, {"dv", "video/dv"}, {"fli", "video/fli"}, {"gl", "video/gl"}, {"mpeg", "video/mpeg"}, {"mpg", "video/mpeg"}, {"mpe", "video/mpeg"}, {"ts", "video/MP2T"}, {"mp4", "video/mp4"}, {"qt", "video/quicktime"}, {"mov", "video/quicktime"}, {"ogv", "video/ogg"}, {"webm", "video/webm"}, {"mxu", "video/vnd.mpegurl"}, {"flv", "video/x-flv"}, {"lsf", "video/x-la-asf"}, {"lsx", "video/x-la-asf"}, {"mng", "video/x-mng"}, {"asf", "video/x-ms-asf"}, {"asx", "video/x-ms-asf"}, {"wm", "video/x-ms-wm"}, {"wmv", "video/x-ms-wmv"}, {"wmx", "video/x-ms-wmx"}, {"wvx", "video/x-ms-wvx"}, {"avi", "video/x-msvideo"}, {"movie", "video/x-sgi-movie"}, {"mpv", "video/x-matroska"}, {"mkv", "video/x-matroska"}, {"ice", "x-conference/x-cooltalk"}, {"sisx", "x-epoc/x-sisx-app"}, {"vrm", "x-world/x-vrml"}, {"vrml", "x-world/x-vrml"}, {"wrl", "x-world/x-vrml"} }; for (auto const& m : mappings) { mimeTypes.Add(m.extension, m.mimeType); } } UWebCommunicationBPLibrary::~UWebCommunicationBPLibrary() {} /*Delegate functions*/ void UWebCommunicationBPLibrary::httpRequestCompleteDelegate(const FString dataString, const TArray& dataArray, const TArray& header, const int32 statusCode, const TArray& byteData, const FString requestID) { toCancelRequests.Remove(requestID); startedRequests.Remove(requestID); } void UWebCommunicationBPLibrary::httpRequestCompleteGoogleInfoDelegate(const FString fileName, const int64 fileSizeInBytes, const int32 statusCode, const FString downloadID, const FString requestID){} //void UWebCommunicationBPLibrary::httpFileProgressDelegate(const float size, const int32 bytesSent, const float percentUpload, const int32 bytesReceived, const float percentDownload) {} void UWebCommunicationBPLibrary::httpFileDownloadDelegate(const float size, const float megaBytesReceived, const float percentDownload, const float megaBit, const FString requestID) {} void UWebCommunicationBPLibrary::httpFileUploadDelegate(const float size, const int32 bytesSent, const float percentUpload, const FString requestID) {} void UWebCommunicationBPLibrary::httpServerSendEventDelegate(const FString response, const FString requestID){} //UWebCommunicationBPLibrary* UWebCommunicationBPLibrary::getTarget() { // return webcom; //} UWebCommunicationBPLibrary* UWebCommunicationBPLibrary::getWebCommunicationTarget() { return webcom; } void UWebCommunicationBPLibrary::cancelRequest(FString requestID) { UWebCommunicationBPLibrary::getWebCommunicationTarget()->toCancelRequests.Add(requestID, requestID); if (UWebCommunicationBPLibrary::getWebCommunicationTarget()->startedRequests.Find(requestID) != nullptr) { (*UWebCommunicationBPLibrary::getWebCommunicationTarget()->startedRequests.Find(requestID))->CancelRequest(); } } int32 UWebCommunicationBPLibrary::megabyteToByte(int32 mb) { return (mb * 1024 * 1024); } float UWebCommunicationBPLibrary::byteToMegabyte(int32 byte) { return ((float)byte / 1024 / 1024); } void UWebCommunicationBPLibrary::searchUploadLeftovers(EHTTPWebComFileUpload DirectoryType, FString filePath, bool& foundLeftovers, int64& originalFileSize) { foundLeftovers = false; originalFileSize = 0; FString dir; if (DirectoryType == EHTTPWebComFileUpload::E_ad) { dir = FPaths::ConvertRelativePathToFull(filePath); } else { FString gameDir = FPaths::ProjectDir(); dir = FPaths::ConvertRelativePathToFull(gameDir + filePath); } FArchive* reader = IFileManager::Get().CreateFileReader(*dir); if (reader == nullptr) { return; } if (reader->TotalSize() < 37) { reader->Close(); delete reader; return; } TArray data; for (int32 i = 0; i < 20; i++) { reader->Seek(reader->TotalSize() - 37-i); data.AddUninitialized(37+i); reader->Serialize(data.GetData(), 37+i); if (data[0] == '-' && data[1] == '-' && data[2] == '-' && data[3] == '-' && data[4] == '-' && data[5] == '-') { break; } else { data.Empty(); if (reader->TotalSize() < 37 + i) { break; } } } reader->Close(); delete reader; if (data.Num() < 35) { return; } data.Add(0x00);// null-terminator FString httpUploadfooter = UTF8_TO_TCHAR(data.GetData()); httpUploadfooter = httpUploadfooter.TrimEnd(); if (httpUploadfooter.StartsWith("------UE4WebCommunicationPlugin_") == false || httpUploadfooter.EndsWith("--") == false) { return; } httpUploadfooter.RemoveFromStart("------UE4WebCommunicationPlugin_"); httpUploadfooter.RemoveFromEnd("--"); if (httpUploadfooter.Len() < 1 || httpUploadfooter.IsNumeric() == false) { return; } //int64 originalFileLength = FCString::Atoi64(*httpUploadfooter); originalFileSize = FCString::Atoi64(*httpUploadfooter); if (originalFileSize > 0) { foundLeftovers = true; } return; } bool UWebCommunicationBPLibrary::repairFileAfterUpload(EHTTPWebComFileUpload DirectoryType, FString filePath) { bool foundLeftovers = false; int64 originalFileSize = 0; searchUploadLeftovers(DirectoryType, filePath, foundLeftovers, originalFileSize); if (foundLeftovers == false || originalFileSize == 0) { return false; } FString dir; if (DirectoryType == EHTTPWebComFileUpload::E_ad) { dir = FPaths::ConvertRelativePathToFull(filePath); } else { FString gameDir = FPaths::ProjectDir(); dir = FPaths::ConvertRelativePathToFull(gameDir + filePath); } if (FPlatformFileManager::Get().GetPlatformFile().FileSize(*dir) < originalFileSize) { return false; } IFileHandle* f = FPlatformFileManager::Get().GetPlatformFile().OpenWrite(*dir, true, true); if (f != nullptr) { bool truncate = f->Truncate(originalFileSize); f->Flush(); if (truncate) { UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: truncate okay: %s"), *dir); } else { UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary: truncate fail: %s"), *dir); } delete f; } return false; } void UWebCommunicationBPLibrary::getMimeTypeByFile(EHTTPWebComFileUpload DirectoryType, FString filePath, FString& mimeType, bool& success){ mimeType.Empty(); FString dir; if (DirectoryType == EHTTPWebComFileUpload::E_ad) { dir = FPaths::ConvertRelativePathToFull(filePath); } else { FString gameDir = FPaths::ProjectDir(); dir = FPaths::ConvertRelativePathToFull(gameDir + filePath); } if (FPaths::FileExists(*dir) == false) { success = false; return; } FString extension = FPaths::GetExtension(dir); if (UWebCommunicationBPLibrary::webcom->mimeTypes.Find(extension) == nullptr) { success = false; return; } mimeType = *UWebCommunicationBPLibrary::webcom->mimeTypes.Find(extension); success = true; } TMap UWebCommunicationBPLibrary::getMimeTypeMap(){ return UWebCommunicationBPLibrary::webcom->mimeTypes; } void UWebCommunicationBPLibrary::addRequestToTruncateThread(FhttpRequest& httpRequest) { if (truncateUploadedFileThread == nullptr) { truncateUploadedFileThread = new FWebComTruncateUploadedFileThread(); } truncateUploadedFileThread->addRequest(httpRequest); } bool UWebCommunicationBPLibrary::isFileBlocked(FString filePath) { if (truncateUploadedFileThread == nullptr) { return false; } return truncateUploadedFileThread->blockedFiles.Contains(filePath); } void UWebCommunicationBPLibrary::executeHttpRequests(TArray httpRequests, UWebCommunicationBPLibrary*& WebCommunicationTarget) { UWebCommunicationBPLibrary::webcom->startRequests(httpRequests); WebCommunicationTarget = UWebCommunicationBPLibrary::webcom; } int32 UWebCommunicationBPLibrary::CreateHttpRequestGET(TArray otherHttpRequests, FString url, TMap header, FString optionalRequestID, bool bindServerSendEvent, TArray& httpRequests, FString& requestID) { //webcom->runRequestProgress = true; requestID = optionalRequestID; if (requestID.IsEmpty()) requestID = FGuid::NewGuid().ToString(); if (url.Len() < 3) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : URL to short.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } FhttpRequest httpRequest; httpRequest.requestType = EHTTPWebComRequestType::GET; httpRequest.url = url; httpRequest.header = header; httpRequest.bindServerSendEvent = bindServerSendEvent; UWebCommunicationRequestCompleteObject* requestObject = NewObject(UWebCommunicationRequestCompleteObject::StaticClass()); requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget()); httpRequest.request = requestObject; otherHttpRequests.Add(httpRequest); httpRequests = otherHttpRequests; return 0; } int32 UWebCommunicationBPLibrary::CreateHttpRequestGETDownload(TArray& httpRequests, FString& requestID, TArray otherHttpRequests, FString url, TMap header, EHTTPWebComFileDownloadResumeType actionIfFileExists, EHTTPWebComFileUpload DirectoryType, FString filePath, FString optionalRequestID) { if (filePath.IsEmpty()) { UE_LOG(LogTemp, Error, TEXT("CreateHttpRequestGETDownload: FilePath not set.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } FString dir; if (DirectoryType == EHTTPWebComFileUpload::E_ad) { dir = FPaths::ConvertRelativePathToFull(filePath); } else { FString gameDir = FPaths::ProjectDir(); dir = FPaths::ConvertRelativePathToFull(gameDir + filePath); } if (FPaths::DirectoryExists(FPaths::GetPath(dir)) == false) { UE_LOG(LogTemp, Error, TEXT("CreateHttpRequestGETDownload: Directory does not exist.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } requestID = optionalRequestID; if (requestID.IsEmpty()) requestID = FGuid::NewGuid().ToString(); if (url.Len() < 3) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : URL to short.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } FhttpRequest httpRequest; httpRequest.requestType = EHTTPWebComRequestType::GET; httpRequest.url = url; UWebCommunicationRequestCompleteObject* requestObject = NewObject(UWebCommunicationRequestCompleteObject::StaticClass()); requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget()); requestObject->setFileCancelResumeDownloadDir(dir); switch (actionIfFileExists) { case EHTTPWebComFileDownloadResumeType::E_NOT_OVERWRITE: if (FPaths::FileExists(dir)) { UE_LOG(LogTemp, Warning, TEXT("CreateHttpRequestGETDownload: File exist. Cancel download.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } break; case EHTTPWebComFileDownloadResumeType::E_OVERWRITE: FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*dir); break; case EHTTPWebComFileDownloadResumeType::E_RESUME: requestObject->setFileCancelResumeDownloadByteStart(FPlatformFileManager::Get().GetPlatformFile().FileSize(*dir)); break; } httpRequest.request = requestObject; otherHttpRequests.Add(httpRequest); httpRequests = otherHttpRequests; return 0; } int32 UWebCommunicationBPLibrary::CreateHttpRequestGETLowRamDownload(TArray& httpRequests, FString& requestID, TArray otherHttpRequests, FString url, TMap header, EHTTPWebComFileDownloadResumeType actionIfFileExists, EHTTPWebComFileUpload DirectoryType, FString filePath, int32 fileSize, FString optionalRequestID) { if (filePath.IsEmpty()) { UE_LOG(LogTemp, Error, TEXT("CreateHttpRequestGETLowRamDownload: FilePath not set.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } FString dir; if (DirectoryType == EHTTPWebComFileUpload::E_ad) { dir = FPaths::ConvertRelativePathToFull(filePath); } else { FString gameDir = FPaths::ProjectDir(); dir = FPaths::ConvertRelativePathToFull(gameDir + filePath); } if (FPaths::DirectoryExists(FPaths::GetPath(dir)) == false) { UE_LOG(LogTemp, Error, TEXT("CreateHttpRequestGETLowRamDownload: Directory does not exist.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } requestID = optionalRequestID; if (requestID.IsEmpty()) requestID = FGuid::NewGuid().ToString(); if (url.Len() < 3) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : URL to short.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } FhttpRequest httpRequest; httpRequest.requestType = EHTTPWebComRequestType::GETLowRamDownload; httpRequest.url = url; httpRequest.header = header; UWebCommunicationRequestCompleteObject* requestObject = NewObject(UWebCommunicationRequestCompleteObject::StaticClass()); requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget()); requestObject->setFileCancelResumeDownloadBytePartSize(fileSize); requestObject->setFileCancelResumeDownloadDir(dir); switch (actionIfFileExists) { case EHTTPWebComFileDownloadResumeType::E_NOT_OVERWRITE: if (FPaths::FileExists(dir)) { UE_LOG(LogTemp, Warning, TEXT("CreateHttpRequestGETLowRamDownload: File exist. Cancel download.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } break; case EHTTPWebComFileDownloadResumeType::E_OVERWRITE: FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*dir); break; case EHTTPWebComFileDownloadResumeType::E_RESUME: requestObject->setFileCancelResumeDownloadByteStart(FPlatformFileManager::Get().GetPlatformFile().FileSize(*dir)); break; } httpRequest.request = requestObject; otherHttpRequests.Add(httpRequest); httpRequests = otherHttpRequests; return 0; } int32 UWebCommunicationBPLibrary::CreateHttpRequestGoogleDrive(TArray otherHttpRequests, FString downloadID, FString optionalRequestID, int64 optionalFileSizeInByte, TArray& httpRequests, FString& requestID) { if (downloadID.IsEmpty()) { UE_LOG(LogTemp, Error, TEXT("No downloadId in CreateHttpRequestGoogleDrive.")); webcom->onhttpRequestCompleteGoogleInfoDelegate.Broadcast("", 0,400, downloadID,requestID); return 400; } requestID = optionalRequestID; if (requestID.IsEmpty()) requestID = FGuid::NewGuid().ToString(); FString url = "https://drive.google.com/uc?id=" + downloadID + "&export=download"; FhttpRequest httpRequest; httpRequest.requestType = EHTTPWebComRequestType::GET; httpRequest.url = url; UWebCommunicationRequestCompleteObject* requestObject = NewObject(UWebCommunicationRequestCompleteObject::StaticClass()); requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget()); requestObject->setDownloadID(downloadID); requestObject->setMultiStepDownload(1); requestObject->setMultiStepDownloadType(EMultiStepType::GOOGLE); requestObject->setHTMLFileSize(optionalFileSizeInByte); httpRequest.request = requestObject; otherHttpRequests.Add(httpRequest); httpRequests = otherHttpRequests; return 0; } int32 UWebCommunicationBPLibrary::CreateHttpRequestGoogleDriveFileInfo(TArray otherHttpRequests, FString downloadID, FString optionalRequestID, TArray& httpRequests, FString& requestID) { if (downloadID.IsEmpty()) { UE_LOG(LogTemp, Error, TEXT("No downloadId in CreateHttpRequestGoogleDriveFileInfo.")); webcom->onhttpRequestCompleteGoogleInfoDelegate.Broadcast("", 0, 400, downloadID, requestID); return 400; } requestID = optionalRequestID; if (requestID.IsEmpty()) requestID = FGuid::NewGuid().ToString(); FString url = "https://drive.google.com/file/d/" + downloadID + "/view"; FhttpRequest httpRequest; httpRequest.requestType = EHTTPWebComRequestType::GET; httpRequest.url = url; UWebCommunicationRequestCompleteObject* requestObject = NewObject(UWebCommunicationRequestCompleteObject::StaticClass()); requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget()); requestObject->setDownloadID(downloadID); requestObject->setMultiStepDownloadType(EMultiStepType::GOOGLE_INFO); httpRequest.request = requestObject; otherHttpRequests.Add(httpRequest); httpRequests = otherHttpRequests; return 0; } int32 UWebCommunicationBPLibrary::CreateHttpRequestAnonfiles(TArray otherHttpRequests, FString url, FString optionalRequestID, TArray& httpRequests, FString& requestID) { requestID = optionalRequestID; if (requestID.IsEmpty()) requestID = FGuid::NewGuid().ToString(); if (url.Len() < 3) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : URL to short.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } FhttpRequest httpRequest; httpRequest.requestType = EHTTPWebComRequestType::GET; httpRequest.url = url; UWebCommunicationRequestCompleteObject* requestObject = NewObject(UWebCommunicationRequestCompleteObject::StaticClass()); requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget()); requestObject->setMultiStepDownload(1); requestObject->setMultiStepDownloadType(EMultiStepType::ANONFILE); httpRequest.request = requestObject; otherHttpRequests.Add(httpRequest); httpRequests = otherHttpRequests; return 0; } int32 UWebCommunicationBPLibrary::CreateHttpRequestPOST(TArray otherHttpRequests, FString url, TMap header, TMap POSTData, FString optionalRequestID, bool bindServerSendEvent, TArray& httpRequests, FString& requestID) { requestID = optionalRequestID; if (requestID.IsEmpty()) requestID = FGuid::NewGuid().ToString(); if (url.Len() < 3) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : URL to short.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } FhttpRequest httpRequest; httpRequest.requestType = EHTTPWebComRequestType::POST; httpRequest.url = url; httpRequest.header = header; httpRequest.POSTData = POSTData; httpRequest.bindServerSendEvent = bindServerSendEvent; UWebCommunicationRequestCompleteObject* requestObject = NewObject(UWebCommunicationRequestCompleteObject::StaticClass()); requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget()); httpRequest.request = requestObject; otherHttpRequests.Add(httpRequest); httpRequests = otherHttpRequests; return 0; } void UWebCommunicationBPLibrary::CreateHttpRequestIndividual(TArray otherHttpRequests, FString url, TMap header, FString verb, EHTTPWebComIndividualType contentBodyType, FString contentBody,TArray binaryContent, FString optionalRequestID, TArray& httpRequests, FString& requestID, bool addContentLengthHeader, bool bindDownloadProgressEvent, bool bindUploadProgressEvent, bool bindServerSendEvent) { UAsyncNodeWebCom* asyncNodeHttpRequest = webcom->getUAsyncNodeHttpRequest(requestID); if (header.Num() == 0) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : You have not specified a header. An HTTP request does not work without a header. Add headers like user-agent,Content-Type,Content-Length")); fireErrorMessageInGameThread(asyncNodeHttpRequest, 400, requestID); return; } if (header.Find("Content-Type") == nullptr) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : The Content-Type header is missing. This can cause a crash in some UE versions. Therefore the request is not executed. Please also pay attention to upper and lower case.")); fireErrorMessageInGameThread(asyncNodeHttpRequest, 400, requestID); return; } if (url.Len() < 3) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : URL to short.")); fireErrorMessageInGameThread(asyncNodeHttpRequest, 400, requestID); return; } verb = verb.ToUpper(); if (!verb.Equals("GET") && !verb.Equals("HEAD") && !verb.Equals("POST") && !verb.Equals("PUT") && !verb.Equals("DELETE") && !verb.Equals("TRACE") && !verb.Equals("OPTIONS") && !verb.Equals("CONNECT") && !verb.Equals("PATCH")) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : Wrong verb. Possible values:GET,HEAD,POST,PUT,DELETE,TRACE,OPTIONS,CONNECT,PATCH")); fireErrorMessageInGameThread(asyncNodeHttpRequest, 400, requestID); return; } if (addContentLengthHeader == true) { if (verb.Equals("GET")) { UE_LOG(LogTemp, Warning, TEXT("WebCom Plugin: Setting a Content-Length header for a GET request can lead to an error on the server. ")); } if (contentBody.IsEmpty()) { UE_LOG(LogTemp, Warning, TEXT("WebCom Plugin: Setting a Content-Length header with the value 0 can lead to an error on the server. ")); } FTCHARToUTF8 Convert(*contentBody); header.Add("Content-Length", FString::FromInt(Convert.Length())); } requestID = optionalRequestID; if (requestID.IsEmpty()) requestID = FGuid::NewGuid().ToString(); FhttpRequest httpRequest; switch (contentBodyType) { case EHTTPWebComIndividualType::E_STRING: httpRequest.requestType = EHTTPWebComRequestType::INDIVIDUAL; break; case EHTTPWebComIndividualType::E_STREAM: httpRequest.requestType = EHTTPWebComRequestType::INDIVIDUAL_STREAM; break; case EHTTPWebComIndividualType::E_BYTES: httpRequest.requestType = EHTTPWebComRequestType::INDIVIDUAL_BYTES; break; } httpRequest.url = url; httpRequest.header = header; httpRequest.verb = verb; httpRequest.content = contentBody; httpRequest.binaryContent = binaryContent; httpRequest.bindDownloadProgressEvent = bindDownloadProgressEvent; httpRequest.bindUploadProgressEvent = bindUploadProgressEvent; httpRequest.bindServerSendEvent = bindServerSendEvent; UWebCommunicationRequestCompleteObject* requestObject = NewObject(UWebCommunicationRequestCompleteObject::StaticClass()); requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget()); httpRequest.request = requestObject; otherHttpRequests.Add(httpRequest); httpRequests = otherHttpRequests; } int32 UWebCommunicationBPLibrary::CreateHttpRequestFileUploadPOST(TArray otherHttpRequests, FString url, TMap header, EHTTPWebComFileUpload DirectoryType, FString filePath, FString fileID, TMap POSTData, FString optionalRequestID, TArray& httpRequests, FString& requestID) { TArray filePaths; filePaths.Add(filePath); TArray fileIDs; fileIDs.Add(fileID); return CreateHttpRequestFileMultiUploadPOST(otherHttpRequests, url, header, DirectoryType, filePaths, fileIDs, POSTData, optionalRequestID, httpRequests, requestID); } int32 UWebCommunicationBPLibrary::CreateHttpRequestFileMultiUploadPOST(TArray otherHttpRequests, FString url, TMap header, EHTTPWebComFileUpload DirectoryType, TArray filePaths, TArray fileIDs, TMap POSTData, FString optionalRequestID, TArray& httpRequests, FString& requestID){ requestID = optionalRequestID; if (requestID.IsEmpty()) requestID = FGuid::NewGuid().ToString(); if (url.Len() < 3) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : URL to short.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } if (fileIDs.Num() == 0) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : File ID is missing")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } FhttpRequest httpRequest; httpRequest.requestType = EHTTPWebComRequestType::POST_UPLOAD; httpRequest.url = url; httpRequest.header = header; httpRequest.POSTData = POSTData; httpRequest.DirectoryType = DirectoryType; httpRequest.filePaths = filePaths; httpRequest.fileID = fileIDs[0]; httpRequest.fileIDs = fileIDs; UWebCommunicationRequestCompleteObject* requestObject = NewObject(UWebCommunicationRequestCompleteObject::StaticClass()); requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget()); httpRequest.request = requestObject; otherHttpRequests.Add(httpRequest); httpRequests = otherHttpRequests; return 0; } int32 UWebCommunicationBPLibrary::CreateHttpRequestFileUploadPUT(TArray otherHttpRequests, FString url, TMap header, EHTTPWebComFileUpload DirectoryType, FString filePath, FString fileID, EHTTPWebComFileUploadType uploadType, FString optionalRequestID, TArray& httpRequests, FString& requestID) { requestID = optionalRequestID; if (requestID.IsEmpty()) requestID = FGuid::NewGuid().ToString(); if (url.Len() < 3) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : URL to short.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } FhttpRequest httpRequest; switch (uploadType) { case EHTTPWebComFileUploadType::PUT_STREAM_MP: httpRequest.requestType = EHTTPWebComRequestType::PUT_STREAM_MP; break; case EHTTPWebComFileUploadType::PUT_STREAM_BLANK: httpRequest.requestType = EHTTPWebComRequestType::PUT_STREAM_BLANK; break; case EHTTPWebComFileUploadType::PUT_STREAM_COPY: httpRequest.requestType = EHTTPWebComRequestType::PUT_STREAM_COPY; break; default: httpRequest.requestType = EHTTPWebComRequestType::PUT; break; } httpRequest.url = url; httpRequest.header = header; httpRequest.DirectoryType = DirectoryType; httpRequest.filePath = filePath; httpRequest.fileID = fileID; UWebCommunicationRequestCompleteObject* requestObject = NewObject(UWebCommunicationRequestCompleteObject::StaticClass()); requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget()); httpRequest.request = requestObject; otherHttpRequests.Add(httpRequest); httpRequests = otherHttpRequests; return 0; } int32 UWebCommunicationBPLibrary::CreateHttpRequestFileMultiUploadPUT(TArray otherHttpRequests, FString url, TMap header, EHTTPWebComFileUpload DirectoryType, TArray filePaths, TArray fileIDs, FString optionalRequestID, TArray& httpRequests, FString& requestID) { requestID = optionalRequestID; if (requestID.IsEmpty()) requestID = FGuid::NewGuid().ToString(); if (url.Len() < 3) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : URL to short.")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } if (fileIDs.Num() == 0) { UE_LOG(LogTemp, Error, TEXT("Cancel Request : File ID is missing")); webcom->onhttpRequestCompleteDelegate.Broadcast("", TArray(), TArray(), 400, TArray(), requestID); return 400; } FhttpRequest httpRequest; httpRequest.requestType = EHTTPWebComRequestType::PUT; httpRequest.url = url; httpRequest.header = header; httpRequest.DirectoryType = DirectoryType; httpRequest.filePaths = filePaths; httpRequest.fileID = fileIDs[0]; httpRequest.fileIDs = fileIDs; UWebCommunicationRequestCompleteObject* requestObject = NewObject(UWebCommunicationRequestCompleteObject::StaticClass()); requestObject->setRequestID(requestID, httpRequest, UWebCommunicationBPLibrary::getWebCommunicationTarget()); httpRequest.request = requestObject; otherHttpRequests.Add(httpRequest); httpRequests = otherHttpRequests; return 0; } void UWebCommunicationBPLibrary::byteDataToFile(EHTTPWebComFileBytesToFileActionType fileAction, TArray byteData, EHTTPWebComFileUpload DirectoryType, FString filePath) { FfileToByteStruct fileToByteStruct; fileToByteStruct.fileAction = fileAction; fileToByteStruct.byteData = byteData; fileToByteStruct.DirectoryType = DirectoryType; fileToByteStruct.filePath = filePath; UWebCommunicationBPLibrary::getWebCommunicationTarget()->getByteToFileThread()->saveFile(fileToByteStruct); } void UWebCommunicationBPLibrary::addPersistentHTTPRequestHeader(FString id, FString value) { if (id.IsEmpty()) { UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary (addPersistentHTTPRequestHeader): Id not set.")); return; } if (value.IsEmpty()) { UE_LOG(LogTemp, Display, TEXT("UWebCommunicationBPLibrary (addPersistentHTTPRequestHeader): Value not set. id=%s"), *id); return; } webcom->additionalHeader.Add(id, value); } void UWebCommunicationBPLibrary::removePersistentHTTPRequestHeader(FString id) { if (id.IsEmpty()) { UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary (removePersistentHTTPRequestHeader): Id not set.")); return; } webcom->additionalHeader.Remove(id); } FString UWebCommunicationBPLibrary::getMimeTypeInternal(FString fileType) { //fileType = fileType.Replace(TEXT("."), TEXT("")); if (mimeTypes.Find(fileType) == nullptr) { return "application/octet-stream"; } FString mimeType = *mimeTypes.Find(fileType); if (mimeType.IsEmpty()) { mimeType = "application/octet-stream"; } return mimeType; } FByteToFileThread* UWebCommunicationBPLibrary::getByteToFileThread(){ if (byteToFileThread == nullptr) { byteToFileThread = new FByteToFileThread(); } return byteToFileThread; } void UWebCommunicationBPLibrary::startRequests(TArray& httpRequests){ for (int32 i = 0; i < httpRequests.Num(); i++) { UWebCommunicationRequestCompleteObject* requestObject = httpRequests[i].request; FString url = httpRequests[i].url; TMap POSTData = httpRequests[i].POSTData; EHTTPWebComRequestType requestType = httpRequests[i].requestType; if (requestObject == nullptr) { UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Missing Object instance (153).")); continue; } toCancelRequests.Remove(requestObject->getRequestID()); requestObject->initWebCom(); //requestObject->setWebComHttpRequest(httpRequests[i]); TSharedRef request = FHttpModule::Get().CreateRequest(); request->SetHeader("User-Agent", "UE4 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36"); switch (requestType) { case EHTTPWebComRequestType::GET: fillRequestGET(httpRequests[i], request); fillHeader(httpRequests[i], request); if (requestObject->getMultiStepDownload() > 0) { request->OnProcessRequestComplete().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestMultiStepComplete); #if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4 request->OnRequestProgress64().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestMultiStepDownload); #else request->OnRequestProgress().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestMultiStepDownload); #endif request->ProcessRequest(); continue; } if ((requestObject->getFileCancelResumeDownloadByteStart() > 0)) { request->SetHeader("Range", "bytes=" + UWebCommunicationBPLibrary::Int64ToFString(requestObject->getFileCancelResumeDownloadByteStart()) + "-"); } #if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4 request->OnRequestProgress64().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressDownload); #else request->OnRequestProgress().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressDownload); #endif break; case EHTTPWebComRequestType::GETLowRamDownload: fillRequestGET(httpRequests[i], request); request->OnProcessRequestComplete().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestCompleteLowRam); #if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4 request->OnRequestProgress64().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressDownloadLowRam); #else request->OnRequestProgress().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressDownloadLowRam); #endif if (requestObject->getFileCancelResumeDownloadByteFullSize() == 0) { //first request is send to ge the file size request->SetHeader("Range", "bytes=0-0"); } else { if ((requestObject->getFileCancelResumeDownloadByteStart() + requestObject->getFileCancelResumeDownloadBytePartSize()) > requestObject->getFileCancelResumeDownloadByteFullSize()) { request->SetHeader("Range", "bytes=" + UWebCommunicationBPLibrary::Int64ToFString(requestObject->getFileCancelResumeDownloadByteStart()) + "-"); } else { request->SetHeader("Range", "bytes=" + UWebCommunicationBPLibrary::Int64ToFString(requestObject->getFileCancelResumeDownloadByteStart()) + "-" + UWebCommunicationBPLibrary::Int64ToFString(requestObject->getFileCancelResumeDownloadByteStart() + requestObject->getFileCancelResumeDownloadBytePartSize())); } } fillHeader(httpRequests[i], request); //UE_LOG(LogTemp, Error, TEXT("Head: %s"), *request->GetHeader("Range")); request->ProcessRequest(); continue; break; case EHTTPWebComRequestType::PUT: case EHTTPWebComRequestType::PUT_STREAM_MP: case EHTTPWebComRequestType::PUT_STREAM_BLANK: case EHTTPWebComRequestType::PUT_STREAM_COPY: case EHTTPWebComRequestType::POST_UPLOAD: fillHeader(httpRequests[i], request); if (!fillRequestUPLOAD(httpRequests[i], request)) { continue; } #if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4 request->OnRequestProgress64().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressUpload); #else request->OnRequestProgress().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressUpload); #endif break; case EHTTPWebComRequestType::POST: fillRequestPOST(httpRequests[i], request); #if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4 request->OnRequestProgress64().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressDownload); #else request->OnRequestProgress().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressDownload); #endif fillHeader(httpRequests[i], request); break; case EHTTPWebComRequestType::INDIVIDUAL: case EHTTPWebComRequestType::INDIVIDUAL_STREAM: case EHTTPWebComRequestType::INDIVIDUAL_BYTES: request->SetVerb(httpRequests[i].verb); request->SetURL(url); switch (requestType) { case EHTTPWebComRequestType::INDIVIDUAL: request->SetContentAsString(httpRequests[i].content); break; case EHTTPWebComRequestType::INDIVIDUAL_STREAM: request->SetContentAsStreamedFile(httpRequests[i].content); break; case EHTTPWebComRequestType::INDIVIDUAL_BYTES: request->SetContent(httpRequests[i].binaryContent); break; } fillHeader(httpRequests[i], request); #if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4 if (httpRequests[i].bindDownloadProgressEvent) { request->OnRequestProgress64().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressDownload); } if (httpRequests[i].bindUploadProgressEvent) { request->OnRequestProgress64().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressUpload); } #else if (httpRequests[i].bindDownloadProgressEvent) { request->OnRequestProgress().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressDownload); } if (httpRequests[i].bindUploadProgressEvent) { request->OnRequestProgress().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressUpload); } #endif break; } #if ENGINE_MAJOR_VERSION >= 5 & ENGINE_MINOR_VERSION >= 4 if (httpRequests[i].bindServerSendEvent) { request->OnRequestProgress64().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressServerSendEvent); } #else if (httpRequests[i].bindServerSendEvent) { request->OnRequestProgress().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestProgressServerSendEvent); } #endif request->OnProcessRequestComplete().BindUObject(requestObject, &UWebCommunicationRequestCompleteObject::requestComplete); request->ProcessRequest(); startedRequests.Add(requestObject->getRequestID(), request); } httpRequests.Empty(); } void UWebCommunicationBPLibrary::registerUAsyncNodeHttpRequest(FString requestIDP, UAsyncNodeWebCom* asyncNodeHttpRequest){ //UE_LOG(LogTemp, Error, TEXT("registerUAsyncNodeHttpRequest: %s"), *requestIDP); asyncNodeHttpRequests.Add(requestIDP, asyncNodeHttpRequest); } void UWebCommunicationBPLibrary::unregisterUAsyncNodeHttpRequest(FString requestIDP){ //UE_LOG(LogTemp, Error, TEXT("unregisterUAsyncNodeHttpRequest: %s"), *requestIDP); asyncNodeHttpRequests.Remove(requestIDP); } UAsyncNodeWebCom* UWebCommunicationBPLibrary::getUAsyncNodeHttpRequest(FString requestIDP){ //UE_LOG(LogTemp, Error, TEXT("getUAsyncNodeHttpRequest: %s"), *requestIDP); if (asyncNodeHttpRequests.Find(requestIDP) == nullptr) { return nullptr; } return *asyncNodeHttpRequests.Find(requestIDP); } void UWebCommunicationBPLibrary::fireErrorMessageInGameThread(UAsyncNodeWebCom* asyncNodeHttpRequest, int32 errorCode, FString requestID){ AsyncTask(ENamedThreads::GameThread, [asyncNodeHttpRequest, errorCode, requestID]() { TArray byteArray; TArray dataArray; if (asyncNodeHttpRequest != nullptr) { asyncNodeHttpRequest->httpRequestComplete("", dataArray, dataArray, 400, byteArray, requestID); } else { webcom->onhttpRequestCompleteDelegate.Broadcast("", dataArray, dataArray, 400, byteArray, requestID); } }); } void UWebCommunicationBPLibrary::fillRequestGET(FhttpRequest& requestStruct, TSharedRef request){ request->SetHeader("Content-Type", "application/x-www-form-urlencoded"); request->SetVerb("GET"); request->SetURL(requestStruct.url); } void UWebCommunicationBPLibrary::fillRequestPOST(FhttpRequest& requestStruct, TSharedRef request){ request->SetHeader("Content-Type", "application/x-www-form-urlencoded"); request->SetVerb("POST"); request->SetURL(requestStruct.url); FString JoinedStr = postMapToString(requestStruct.POSTData); request->SetContentAsString(JoinedStr); FTCHARToUTF8 Convert(*JoinedStr); request->SetHeader("Content-Length", FString::FromInt(Convert.Length())); } void UWebCommunicationBPLibrary::fillHeader(FhttpRequest& requestStruct, TSharedRef request) { //persistent header if (UWebCommunicationBPLibrary::webcom->additionalHeader.Num() > 0) { for (auto& element : UWebCommunicationBPLibrary::webcom->additionalHeader) { request->SetHeader(element.Key, element.Value); } } //custom header if (requestStruct.header.Num() > 0) { for (auto& element : requestStruct.header) { request->SetHeader(element.Key, element.Value); } } } bool UWebCommunicationBPLibrary::fillRequestUPLOAD(FhttpRequest& requestStruct, TSharedRef request){ if (requestStruct.requestType == EHTTPWebComRequestType::POST_UPLOAD) { request->SetVerb("POST"); } else { request->SetVerb("PUT"); } request->SetURL(requestStruct.url); if (requestStruct.requestType == EHTTPWebComRequestType::POST_UPLOAD || requestStruct.requestType == EHTTPWebComRequestType::PUT) { FString boundary = "UE4WebCommunicationPlugin_" + FString::FromInt(FDateTime::Now().GetTicks()); request->SetHeader("Content-Type", "multipart/form-data; boundary=----" + boundary); if (requestStruct.filePath.IsEmpty() == false) { requestStruct.filePaths.Add(requestStruct.filePath); } TArray dataToSend; for (int32 i = 0; i < requestStruct.filePaths.Num(); i++){ FString dir; if (requestStruct.DirectoryType == EHTTPWebComFileUpload::E_ad) { dir = FPaths::ConvertRelativePathToFull(requestStruct.filePaths[i]); } else { FString gameDir = FPaths::ProjectDir(); dir = FPaths::ConvertRelativePathToFull(gameDir + requestStruct.filePaths[i]); } if (!FPaths::FileExists(dir)) { UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: File not found: %s"), *dir); return false; } FString fileName = FPaths::GetCleanFilename(dir); FString fileFormat = FPaths::GetExtension(fileName, false); FString mimeType = UWebCommunicationBPLibrary::getWebCommunicationTarget()->getMimeTypeInternal(fileFormat); TArray fileData; if (!FFileHelper::LoadFileToArray(fileData, *dir)) { UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Can't read File: %s"), *dir); return false; } FString fileID = requestStruct.fileID; if (requestStruct.fileIDs.Num() > i) { fileID = requestStruct.fileIDs[i]; } //add File TArray fileHeaderArray = fstringToByteArray("\r\n------" + boundary + "\r\nContent-Disposition: form-data; name=\"" + fileID + "\"; filename=\"" + fileName + "\"\r\n" + "Content-Type: " + mimeType + "\r\n\r\n"); dataToSend.Append(fileHeaderArray); dataToSend.Append(fileData); fileData.Empty(); } //add Post Data if (requestStruct.POSTData.Num() > 0) { TArray keys; requestStruct.POSTData.GetKeys(keys); for (int i = 0; i < keys.Num(); i++) { if (requestStruct.POSTData.Find(keys[i]) == nullptr) { UE_LOG(LogTemp, Warning, TEXT("UWebCommunicationBPLibrary: Parameter %s has no value."), *keys[i]); continue; } FString postVal = "\r\n------" + boundary + "\r\nContent-Disposition: form-data; name=\"" + keys[i] + "\"\r\n\r\n" + *requestStruct.POSTData.Find(keys[i]); dataToSend.Append(fstringToByteArray(postVal)); } } //fill head after file data TArray bottomArray = fstringToByteArray("\r\n------" + boundary + "--\r\n"); dataToSend.Append(bottomArray); request->SetHeader("Content-Length", FString::FromInt(dataToSend.Num())); request->SetContent(dataToSend); //FFileHelper::SaveArrayToFile(dataToSend, *FString("d:/testuploadDebug.txt")); return true; } if (requestStruct.requestType == EHTTPWebComRequestType::PUT_STREAM_MP || requestStruct.requestType == EHTTPWebComRequestType::PUT_STREAM_COPY){ FString dir; if (requestStruct.DirectoryType == EHTTPWebComFileUpload::E_ad) { dir = FPaths::ConvertRelativePathToFull(requestStruct.filePath); } else { FString gameDir = FPaths::ProjectDir(); dir = FPaths::ConvertRelativePathToFull(gameDir + requestStruct.filePath); } if (!FPaths::FileExists(dir)) { UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: File not found: %s"), *dir); return false; } FString fileName = FPaths::GetCleanFilename(dir); FString fileFormat = FPaths::GetExtension(fileName, false); FString mimeType = UWebCommunicationBPLibrary::getWebCommunicationTarget()->getMimeTypeInternal(fileFormat); if (requestStruct.requestType == EHTTPWebComRequestType::PUT_STREAM_COPY) { FString copy = dir.Replace(*FPaths::GetCleanFilename(dir), *(FPaths::GetBaseFilename(dir)+ "_UEUploadCopy_" + FGuid::NewGuid().ToString() + "." + FPaths::GetExtension(dir))); FPlatformFileManager::Get().GetPlatformFile().CopyFile(*copy,*dir); dir = copy; } if (isFileBlocked(dir)) { UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Can't read File. If you tried to upload the same file a few seconds ago, it may still be open. Please wait a few seconds until the file is closed. %s"), *dir); return false; } FArchive* writer = IFileManager::Get().CreateFileWriter(*dir, FILEWRITE_Append); if (writer == nullptr) { UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: Can't read File. If you tried to upload the same file a few seconds ago, it may still be open. Please wait a few seconds until the file is closed. %s"), *dir); return false; } FString fileSize = FString::FromInt(writer->TotalSize()); requestStruct.filePath = dir; requestStruct.originalFileSize = writer->TotalSize(); requestStruct.request->setRequestStruct(requestStruct); FString boundary = "UE4WebCommunicationPlugin_" + fileSize; request->SetHeader("Content-Type", "multipart/form-data; boundary=----" + boundary); FString bodyHeaderFake = "\r\n\r\n------" + boundary + "\r\nContent-Disposition: form-data; name=\"" + requestStruct.fileID + "\"; filename=\"" + fileName + "\"\r\n" + mimeType; FString bottom = "\r\n------" + boundary + "--\r\n"; //request->SetHeader("Content-Length", FString::FromInt(FPlatformFileManager::Get().GetPlatformFile().FileSize(*dir))); request->SetHeader("Content-Length", FString::FromInt(writer->TotalSize() +bodyHeaderFake.Len()+ bottom.Len())+bodyHeaderFake); FTCHARToUTF8 Convert(*bottom); writer->Serialize((uint8*)Convert.Get(), Convert.Length()); writer->Close(); delete writer; request->SetContentAsStreamedFile(dir); return true; } if (requestStruct.requestType == EHTTPWebComRequestType::PUT_STREAM_BLANK) { FString dir; if (requestStruct.DirectoryType == EHTTPWebComFileUpload::E_ad) { dir = FPaths::ConvertRelativePathToFull(requestStruct.filePath); } else { FString gameDir = FPaths::ProjectDir(); dir = FPaths::ConvertRelativePathToFull(gameDir + requestStruct.filePath); } if (!FPaths::FileExists(dir)) { UE_LOG(LogTemp, Error, TEXT("UWebCommunicationBPLibrary: File not found: %s"), *dir); return false; } FString fileName = FPaths::GetCleanFilename(dir); FString fileFormat = FPaths::GetExtension(fileName, false); FString mimeType = UWebCommunicationBPLibrary::getWebCommunicationTarget()->getMimeTypeInternal(fileFormat); request->SetHeader("fileid", requestStruct.fileID); request->SetHeader("filename", fileName); request->SetHeader("fileformat", fileFormat); request->SetHeader("mimetype", mimeType); request->SetContentAsStreamedFile(dir); return true; } return false; } TArray UWebCommunicationBPLibrary::fstringToByteArray(FString data){ TArray byteArray; FTCHARToUTF8 Convert(*data); byteArray.Append((uint8*)((ANSICHAR*)Convert.Get()), Convert.Length()); return byteArray; } FString UWebCommunicationBPLibrary::postMapToString(TMap POSTData){ FString JoinedStr; TArray keys; POSTData.GetKeys(keys); for (int j = 0; j < keys.Num(); j++) { FString* val = POSTData.Find(keys[j]); FString param; if (val != nullptr) { param = keys[j] + "=" + *val; } if (JoinedStr.IsEmpty()) { JoinedStr = param; } else { JoinedStr += "&" + param; } } return JoinedStr; } FString UWebCommunicationBPLibrary::urlEncode(FString urlParameter) { return FGenericPlatformHttp::UrlEncode(urlParameter); } FString UWebCommunicationBPLibrary::urlEncodePure(FString urlParameter) { return FGenericPlatformHttp::UrlEncode(urlParameter); } FString UWebCommunicationBPLibrary::Int64ToFString(int64 Num){ FString string = FString(); const TCHAR* DigitToChar = TEXT("9876543210123456789"); constexpr int64 ZeroDigitIndex = 9; bool bIsNumberNegative = Num < 0; const int64 TempBufferSize = 16; TCHAR TempNum[TempBufferSize]; int64 TempAt = TempBufferSize; // fill the temp string from the top down. // Convert to string assuming base ten. do { TempNum[--TempAt] = DigitToChar[ZeroDigitIndex + (Num % 10)]; Num /= 10; } while (Num); if (bIsNumberNegative) { TempNum[--TempAt] = TEXT('-'); } const TCHAR* CharPtr = TempNum + TempAt; const int64 NumChars = TempBufferSize - TempAt; string.Append(CharPtr, NumChars); return string; }