2019-10-20 01:46:36 +03:00
# include <GlobalConst.h>
# include <Mayaqua/Mayaqua.h>
2019-10-20 03:17:42 +03:00
static char http_404_str [ ] = " <!DOCTYPE HTML PUBLIC \" -//IETF//DTD HTML 2.0//EN \" > \r \n <HTML><HEAD> \r \n <TITLE>404 Not Found</TITLE> \r \n </HEAD><BODY> \r \n <H1>Not Found</H1> \r \n The requested URL $TARGET$ was not found on this server.<P> \r \n <HR> \r \n <ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS> \r \n </BODY></HTML> \r \n " ;
static char http_403_str [ ] = " <!DOCTYPE HTML PUBLIC \" -//IETF//DTD HTML 2.0//EN \" > \r \n <HTML><HEAD> \r \n <TITLE>403 Forbidden</TITLE> \r \n </HEAD><BODY> \r \n <H1>Forbidden</H1> \r \n You don't have permission to access $TARGET$ \r \n on this server.<P> \r \n <HR> \r \n <ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS> \r \n </BODY></HTML> \r \n " ;
static char http_500_str [ ] = " <!DOCTYPE HTML PUBLIC \" -//IETF//DTD HTML 2.0//EN \" > \r \n <HTML><HEAD> \r \n <TITLE>500 Server Error</TITLE> \r \n </HEAD><BODY> \r \n <H1>Server Error</H1> \r \n Server Error<P> \r \n <HR> \r \n <ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS> \r \n </BODY></HTML> \r \n " ;
static char http_501_str [ ] = " <!DOCTYPE HTML PUBLIC \" -//IETF//DTD HTML 2.0//EN \" > \r \n <HTML><HEAD> \r \n <TITLE>501 Method Not Implemented</TITLE> \r \n </HEAD><BODY> \r \n <H1>Method Not Implemented</H1> \r \n $METHOD$ to $TARGET$ not supported.<P> \r \n Invalid method in request $METHOD$ $TARGET$ $VERSION$<P> \r \n <HR> \r \n <ADDRESS>HTTP Server at $HOST$ Port $PORT$</ADDRESS> \r \n </BODY></HTML> \r \n " ;
2019-10-20 01:46:36 +03:00
// MIME list from https://www.freeformatter.com/mime-types-list.html
static const HTTP_MIME_TYPE http_mime_types [ ] =
{
{ " .x3d " , " application/vnd.hzn-3d-crossword " } ,
{ " .3gp " , " video/3gpp " } ,
{ " .3g2 " , " video/3gpp2 " } ,
{ " .mseq " , " application/vnd.mseq " } ,
{ " .pwn " , " application/vnd.3m.post-it-notes " } ,
{ " .plb " , " application/vnd.3gpp.pic-bw-large " } ,
{ " .psb " , " application/vnd.3gpp.pic-bw-small " } ,
{ " .pvb " , " application/vnd.3gpp.pic-bw-var " } ,
{ " .tcap " , " application/vnd.3gpp2.tcap " } ,
{ " .7z " , " application/x-7z-compressed " } ,
{ " .abw " , " application/x-abiword " } ,
{ " .ace " , " application/x-ace-compressed " } ,
{ " .acc " , " application/vnd.americandynamics.acc " } ,
{ " .acu " , " application/vnd.acucobol " } ,
{ " .atc " , " application/vnd.acucorp " } ,
{ " .adp " , " audio/adpcm " } ,
{ " .aab " , " application/x-authorware-bin " } ,
{ " .aam " , " application/x-authorware-map " } ,
{ " .aas " , " application/x-authorware-seg " } ,
{ " .air " , " application/vnd.adobe.air-application-installer-package+zip " } ,
{ " .swf " , " application/x-shockwave-flash " } ,
{ " .fxp " , " application/vnd.adobe.fxp " } ,
{ " .pdf " , " application/pdf " } ,
{ " .ppd " , " application/vnd.cups-ppd " } ,
{ " .dir " , " application/x-director " } ,
{ " .xdp " , " application/vnd.adobe.xdp+xml " } ,
{ " .xfdf " , " application/vnd.adobe.xfdf " } ,
{ " .aac " , " audio/x-aac " } ,
{ " .ahead " , " application/vnd.ahead.space " } ,
{ " .azf " , " application/vnd.airzip.filesecure.azf " } ,
{ " .azs " , " application/vnd.airzip.filesecure.azs " } ,
{ " .azw " , " application/vnd.amazon.ebook " } ,
{ " .ami " , " application/vnd.amiga.ami " } ,
{ " .apk " , " application/vnd.android.package-archive " } ,
{ " .cii " , " application/vnd.anser-web-certificate-issue-initiation " } ,
{ " .fti " , " application/vnd.anser-web-funds-transfer-initiation " } ,
{ " .atx " , " application/vnd.antix.game-component " } ,
{ " .dmg " , " application/x-apple-diskimage " } ,
{ " .mpkg " , " application/vnd.apple.installer+xml " } ,
{ " .aw " , " application/applixware " } ,
{ " .les " , " application/vnd.hhe.lesson-player " } ,
{ " .swi " , " application/vnd.aristanetworks.swi " } ,
{ " .s " , " text/x-asm " } ,
{ " .atomcat " , " application/atomcat+xml " } ,
{ " .atomsvc " , " application/atomsvc+xml " } ,
{ " .atom " , " application/atom+xml " } ,
{ " .ac " , " application/pkix-attr-cert " } ,
{ " .aif " , " audio/x-aiff " } ,
{ " .avi " , " video/x-msvideo " } ,
{ " .aep " , " application/vnd.audiograph " } ,
{ " .dxf " , " image/vnd.dxf " } ,
{ " .dwf " , " model/vnd.dwf " } ,
{ " .par " , " text/plain-bas " } ,
{ " .bcpio " , " application/x-bcpio " } ,
{ " .bin " , " application/octet-stream " } ,
{ " .bmp " , " image/bmp " } ,
{ " .torrent " , " application/x-bittorrent " } ,
{ " .cod " , " application/vnd.rim.cod " } ,
{ " .mpm " , " application/vnd.blueice.multipass " } ,
{ " .bmi " , " application/vnd.bmi " } ,
{ " .sh " , " application/x-sh " } ,
{ " .btif " , " image/prs.btif " } ,
{ " .rep " , " application/vnd.businessobjects " } ,
{ " .bz " , " application/x-bzip " } ,
{ " .bz2 " , " application/x-bzip2 " } ,
{ " .csh " , " application/x-csh " } ,
{ " .c " , " text/x-c " } ,
{ " .cdxml " , " application/vnd.chemdraw+xml " } ,
{ " .css " , " text/css " } ,
{ " .cdx " , " chemical/x-cdx " } ,
{ " .cml " , " chemical/x-cml " } ,
{ " .csml " , " chemical/x-csml " } ,
{ " .cdbcmsg " , " application/vnd.contact.cmsg " } ,
{ " .cla " , " application/vnd.claymore " } ,
{ " .c4g " , " application/vnd.clonk.c4group " } ,
{ " .sub " , " image/vnd.dvb.subtitle " } ,
{ " .cdmia " , " application/cdmi-capability " } ,
{ " .cdmic " , " application/cdmi-container " } ,
{ " .cdmid " , " application/cdmi-domain " } ,
{ " .cdmio " , " application/cdmi-object " } ,
{ " .cdmiq " , " application/cdmi-queue " } ,
{ " .c11amc " , " application/vnd.cluetrust.cartomobile-config " } ,
{ " .c11amz " , " application/vnd.cluetrust.cartomobile-config-pkg " } ,
{ " .ras " , " image/x-cmu-raster " } ,
{ " .dae " , " model/vnd.collada+xml " } ,
{ " .csv " , " text/csv " } ,
{ " .cpt " , " application/mac-compactpro " } ,
{ " .wmlc " , " application/vnd.wap.wmlc " } ,
{ " .cgm " , " image/cgm " } ,
{ " .ice " , " x-conference/x-cooltalk " } ,
{ " .cmx " , " image/x-cmx " } ,
{ " .xar " , " application/vnd.xara " } ,
{ " .cmc " , " application/vnd.cosmocaller " } ,
{ " .cpio " , " application/x-cpio " } ,
{ " .clkx " , " application/vnd.crick.clicker " } ,
{ " .clkk " , " application/vnd.crick.clicker.keyboard " } ,
{ " .clkp " , " application/vnd.crick.clicker.palette " } ,
{ " .clkt " , " application/vnd.crick.clicker.template " } ,
{ " .clkw " , " application/vnd.crick.clicker.wordbank " } ,
{ " .wbs " , " application/vnd.criticaltools.wbs+xml " } ,
{ " .cryptonote " , " application/vnd.rig.cryptonote " } ,
{ " .cif " , " chemical/x-cif " } ,
{ " .cmdf " , " chemical/x-cmdf " } ,
{ " .cu " , " application/cu-seeme " } ,
{ " .cww " , " application/prs.cww " } ,
{ " .curl " , " text/vnd.curl " } ,
{ " .dcurl " , " text/vnd.curl.dcurl " } ,
{ " .mcurl " , " text/vnd.curl.mcurl " } ,
{ " .scurl " , " text/vnd.curl.scurl " } ,
{ " .car " , " application/vnd.curl.car " } ,
{ " .pcurl " , " application/vnd.curl.pcurl " } ,
{ " .cmp " , " application/vnd.yellowriver-custom-menu " } ,
{ " .dssc " , " application/dssc+der " } ,
{ " .xdssc " , " application/dssc+xml " } ,
{ " .deb " , " application/x-debian-package " } ,
{ " .uva " , " audio/vnd.dece.audio " } ,
{ " .uvi " , " image/vnd.dece.graphic " } ,
{ " .uvh " , " video/vnd.dece.hd " } ,
{ " .uvm " , " video/vnd.dece.mobile " } ,
{ " .uvu " , " video/vnd.uvvu.mp4 " } ,
{ " .uvp " , " video/vnd.dece.pd " } ,
{ " .uvs " , " video/vnd.dece.sd " } ,
{ " .uvv " , " video/vnd.dece.video " } ,
{ " .dvi " , " application/x-dvi " } ,
{ " .seed " , " application/vnd.fdsn.seed " } ,
{ " .dtb " , " application/x-dtbook+xml " } ,
{ " .res " , " application/x-dtbresource+xml " } ,
{ " .ait " , " application/vnd.dvb.ait " } ,
{ " .svc " , " application/vnd.dvb.service " } ,
{ " .eol " , " audio/vnd.digital-winds " } ,
{ " .djvu " , " image/vnd.djvu " } ,
{ " .dtd " , " application/xml-dtd " } ,
{ " .mlp " , " application/vnd.dolby.mlp " } ,
{ " .wad " , " application/x-doom " } ,
{ " .dpg " , " application/vnd.dpgraph " } ,
{ " .dra " , " audio/vnd.dra " } ,
{ " .dfac " , " application/vnd.dreamfactory " } ,
{ " .dts " , " audio/vnd.dts " } ,
{ " .dtshd " , " audio/vnd.dts.hd " } ,
{ " .dwg " , " image/vnd.dwg " } ,
{ " .geo " , " application/vnd.dynageo " } ,
{ " .es " , " application/ecmascript " } ,
{ " .mag " , " application/vnd.ecowin.chart " } ,
{ " .mmr " , " image/vnd.fujixerox.edmics-mmr " } ,
{ " .rlc " , " image/vnd.fujixerox.edmics-rlc " } ,
{ " .exi " , " application/exi " } ,
{ " .mgz " , " application/vnd.proteus.magazine " } ,
{ " .epub " , " application/epub+zip " } ,
{ " .eml " , " message/rfc822 " } ,
{ " .nml " , " application/vnd.enliven " } ,
{ " .xpr " , " application/vnd.is-xpr " } ,
{ " .xif " , " image/vnd.xiff " } ,
{ " .xfdl " , " application/vnd.xfdl " } ,
{ " .emma " , " application/emma+xml " } ,
{ " .ez2 " , " application/vnd.ezpix-album " } ,
{ " .ez3 " , " application/vnd.ezpix-package " } ,
{ " .fst " , " image/vnd.fst " } ,
{ " .fvt " , " video/vnd.fvt " } ,
{ " .fbs " , " image/vnd.fastbidsheet " } ,
{ " .fe_launch " , " application/vnd.denovo.fcselayout-link " } ,
{ " .f4v " , " video/x-f4v " } ,
{ " .flv " , " video/x-flv " } ,
{ " .fpx " , " image/vnd.fpx " } ,
{ " .npx " , " image/vnd.net-fpx " } ,
{ " .flx " , " text/vnd.fmi.flexstor " } ,
{ " .fli " , " video/x-fli " } ,
{ " .ftc " , " application/vnd.fluxtime.clip " } ,
{ " .fdf " , " application/vnd.fdf " } ,
{ " .f " , " text/x-fortran " } ,
{ " .mif " , " application/vnd.mif " } ,
{ " .fm " , " application/vnd.framemaker " } ,
{ " .fh " , " image/x-freehand " } ,
{ " .fsc " , " application/vnd.fsc.weblaunch " } ,
{ " .fnc " , " application/vnd.frogans.fnc " } ,
{ " .ltf " , " application/vnd.frogans.ltf " } ,
{ " .ddd " , " application/vnd.fujixerox.ddd " } ,
{ " .xdw " , " application/vnd.fujixerox.docuworks " } ,
{ " .xbd " , " application/vnd.fujixerox.docuworks.binder " } ,
{ " .oas " , " application/vnd.fujitsu.oasys " } ,
{ " .oa2 " , " application/vnd.fujitsu.oasys2 " } ,
{ " .oa3 " , " application/vnd.fujitsu.oasys3 " } ,
{ " .fg5 " , " application/vnd.fujitsu.oasysgp " } ,
{ " .bh2 " , " application/vnd.fujitsu.oasysprs " } ,
{ " .spl " , " application/x-futuresplash " } ,
{ " .fzs " , " application/vnd.fuzzysheet " } ,
{ " .g3 " , " image/g3fax " } ,
{ " .gmx " , " application/vnd.gmx " } ,
{ " .gtw " , " model/vnd.gtw " } ,
{ " .txd " , " application/vnd.genomatix.tuxedo " } ,
{ " .ggb " , " application/vnd.geogebra.file " } ,
{ " .ggt " , " application/vnd.geogebra.tool " } ,
{ " .gdl " , " model/vnd.gdl " } ,
{ " .gex " , " application/vnd.geometry-explorer " } ,
{ " .gxt " , " application/vnd.geonext " } ,
{ " .g2w " , " application/vnd.geoplan " } ,
{ " .g3w " , " application/vnd.geospace " } ,
{ " .gsf " , " application/x-font-ghostscript " } ,
{ " .bdf " , " application/x-font-bdf " } ,
{ " .gtar " , " application/x-gtar " } ,
{ " .texinfo " , " application/x-texinfo " } ,
{ " .gnumeric " , " application/x-gnumeric " } ,
{ " .kml " , " application/vnd.google-earth.kml+xml " } ,
{ " .kmz " , " application/vnd.google-earth.kmz " } ,
{ " .gqf " , " application/vnd.grafeq " } ,
{ " .gif " , " image/gif " } ,
{ " .gv " , " text/vnd.graphviz " } ,
{ " .gac " , " application/vnd.groove-account " } ,
{ " .ghf " , " application/vnd.groove-help " } ,
{ " .gim " , " application/vnd.groove-identity-message " } ,
{ " .grv " , " application/vnd.groove-injector " } ,
{ " .gtm " , " application/vnd.groove-tool-message " } ,
{ " .tpl " , " application/vnd.groove-tool-template " } ,
{ " .vcg " , " application/vnd.groove-vcard " } ,
{ " .h261 " , " video/h261 " } ,
{ " .h263 " , " video/h263 " } ,
{ " .h264 " , " video/h264 " } ,
{ " .hpid " , " application/vnd.hp-hpid " } ,
{ " .hps " , " application/vnd.hp-hps " } ,
{ " .hdf " , " application/x-hdf " } ,
{ " .rip " , " audio/vnd.rip " } ,
{ " .hbci " , " application/vnd.hbci " } ,
{ " .jlt " , " application/vnd.hp-jlyt " } ,
{ " .pcl " , " application/vnd.hp-pcl " } ,
{ " .hpgl " , " application/vnd.hp-hpgl " } ,
{ " .hvs " , " application/vnd.yamaha.hv-script " } ,
{ " .hvd " , " application/vnd.yamaha.hv-dic " } ,
{ " .hvp " , " application/vnd.yamaha.hv-voice " } ,
{ " .sfd-hdstx " , " application/vnd.hydrostatix.sof-data " } ,
{ " .stk " , " application/hyperstudio " } ,
{ " .hal " , " application/vnd.hal+xml " } ,
{ " .htm " , " text/html; charset=utf-8 " } ,
{ " .html " , " text/html; charset=utf-8 " } ,
{ " .irm " , " application/vnd.ibm.rights-management " } ,
{ " .sc " , " application/vnd.ibm.secure-container " } ,
{ " .ics " , " text/calendar " } ,
{ " .icc " , " application/vnd.iccprofile " } ,
{ " .ico " , " image/x-icon " } ,
{ " .igl " , " application/vnd.igloader " } ,
{ " .ief " , " image/ief " } ,
{ " .ivp " , " application/vnd.immervision-ivp " } ,
{ " .ivu " , " application/vnd.immervision-ivu " } ,
{ " .rif " , " application/reginfo+xml " } ,
{ " .3dml " , " text/vnd.in3d.3dml " } ,
{ " .spot " , " text/vnd.in3d.spot " } ,
{ " .igs " , " model/iges " } ,
{ " .i2g " , " application/vnd.intergeo " } ,
{ " .cdy " , " application/vnd.cinderella " } ,
{ " .xpw " , " application/vnd.intercon.formnet " } ,
{ " .fcs " , " application/vnd.isac.fcs " } ,
{ " .ipfix " , " application/ipfix " } ,
{ " .cer " , " application/pkix-cert " } ,
{ " .pki " , " application/pkixcmp " } ,
{ " .crl " , " application/pkix-crl " } ,
{ " .pkipath " , " application/pkix-pkipath " } ,
{ " .igm " , " application/vnd.insors.igm " } ,
{ " .rcprofile " , " application/vnd.ipunplugged.rcprofile " } ,
{ " .irp " , " application/vnd.irepository.package+xml " } ,
{ " .jad " , " text/vnd.sun.j2me.app-descriptor " } ,
{ " .jar " , " application/java-archive " } ,
{ " .class " , " application/java-vm " } ,
{ " .jnlp " , " application/x-java-jnlp-file " } ,
{ " .ser " , " application/java-serialized-object " } ,
{ " .java " , " text/x-java-source " } ,
{ " .js " , " application/javascript " } ,
{ " .json " , " application/json " } ,
{ " .joda " , " application/vnd.joost.joda-archive " } ,
{ " .jpm " , " video/jpm " } ,
{ " .jpg " , " image/jpeg " } ,
{ " .jpeg " , " image/jpeg " } ,
{ " .pjpeg " , " image/pjpeg " } ,
{ " .jpgv " , " video/jpeg " } ,
{ " .ktz " , " application/vnd.kahootz " } ,
{ " .mmd " , " application/vnd.chipnuts.karaoke-mmd " } ,
{ " .karbon " , " application/vnd.kde.karbon " } ,
{ " .chrt " , " application/vnd.kde.kchart " } ,
{ " .kfo " , " application/vnd.kde.kformula " } ,
{ " .flw " , " application/vnd.kde.kivio " } ,
{ " .kon " , " application/vnd.kde.kontour " } ,
{ " .kpr " , " application/vnd.kde.kpresenter " } ,
{ " .ksp " , " application/vnd.kde.kspread " } ,
{ " .kwd " , " application/vnd.kde.kword " } ,
{ " .htke " , " application/vnd.kenameaapp " } ,
{ " .kia " , " application/vnd.kidspiration " } ,
{ " .kne " , " application/vnd.kinar " } ,
{ " .sse " , " application/vnd.kodak-descriptor " } ,
{ " .lasxml " , " application/vnd.las.las+xml " } ,
{ " .latex " , " application/x-latex " } ,
{ " .lbd " , " application/vnd.llamagraphics.life-balance.desktop " } ,
{ " .lbe " , " application/vnd.llamagraphics.life-balance.exchange+xml " } ,
{ " .jam " , " application/vnd.jam " } ,
{ " 0.123 " , " application/vnd.lotus-1-2-3 " } ,
{ " .apr " , " application/vnd.lotus-approach " } ,
{ " .pre " , " application/vnd.lotus-freelance " } ,
{ " .nsf " , " application/vnd.lotus-notes " } ,
{ " .org " , " application/vnd.lotus-organizer " } ,
{ " .scm " , " application/vnd.lotus-screencam " } ,
{ " .lwp " , " application/vnd.lotus-wordpro " } ,
{ " .lvp " , " audio/vnd.lucent.voice " } ,
{ " .m3u " , " audio/x-mpegurl " } ,
{ " .m4v " , " video/x-m4v " } ,
{ " .hqx " , " application/mac-binhex40 " } ,
{ " .portpkg " , " application/vnd.macports.portpkg " } ,
{ " .mgp " , " application/vnd.osgeo.mapguide.package " } ,
{ " .mrc " , " application/marc " } ,
{ " .mrcx " , " application/marcxml+xml " } ,
{ " .mxf " , " application/mxf " } ,
{ " .nbp " , " application/vnd.wolfram.player " } ,
{ " .ma " , " application/mathematica " } ,
{ " .mathml " , " application/mathml+xml " } ,
{ " .mbox " , " application/mbox " } ,
{ " .mc1 " , " application/vnd.medcalcdata " } ,
{ " .mscml " , " application/mediaservercontrol+xml " } ,
{ " .cdkey " , " application/vnd.mediastation.cdkey " } ,
{ " .mwf " , " application/vnd.mfer " } ,
{ " .mfm " , " application/vnd.mfmp " } ,
{ " .msh " , " model/mesh " } ,
{ " .mads " , " application/mads+xml " } ,
{ " .mets " , " application/mets+xml " } ,
{ " .mods " , " application/mods+xml " } ,
{ " .meta4 " , " application/metalink4+xml " } ,
{ " .mcd " , " application/vnd.mcd " } ,
{ " .flo " , " application/vnd.micrografx.flo " } ,
{ " .igx " , " application/vnd.micrografx.igx " } ,
{ " .es3 " , " application/vnd.eszigno3+xml " } ,
{ " .mdb " , " application/x-msaccess " } ,
{ " .asf " , " video/x-ms-asf " } ,
{ " .exe " , " application/x-msdownload " } ,
{ " .cil " , " application/vnd.ms-artgalry " } ,
{ " .cab " , " application/vnd.ms-cab-compressed " } ,
{ " .ims " , " application/vnd.ms-ims " } ,
{ " .application " , " application/x-ms-application " } ,
{ " .clp " , " application/x-msclip " } ,
{ " .mdi " , " image/vnd.ms-modi " } ,
{ " .eot " , " application/vnd.ms-fontobject " } ,
{ " .xls " , " application/vnd.ms-excel " } ,
{ " .xlam " , " application/vnd.ms-excel.addin.macroenabled.12 " } ,
{ " .xlsb " , " application/vnd.ms-excel.sheet.binary.macroenabled.12 " } ,
{ " .xltm " , " application/vnd.ms-excel.template.macroenabled.12 " } ,
{ " .xlsm " , " application/vnd.ms-excel.sheet.macroenabled.12 " } ,
{ " .chm " , " application/vnd.ms-htmlhelp " } ,
{ " .crd " , " application/x-mscardfile " } ,
{ " .lrm " , " application/vnd.ms-lrm " } ,
{ " .mvb " , " application/x-msmediaview " } ,
{ " .mny " , " application/x-msmoney " } ,
{ " .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 " } ,
{ " .xltx " , " application/vnd.openxmlformats-officedocument.spreadsheetml.template " } ,
{ " .docx " , " application/vnd.openxmlformats-officedocument.wordprocessingml.document " } ,
{ " .dotx " , " application/vnd.openxmlformats-officedocument.wordprocessingml.template " } ,
{ " .obd " , " application/x-msbinder " } ,
{ " .thmx " , " application/vnd.ms-officetheme " } ,
{ " .onetoc " , " application/onenote " } ,
{ " .pya " , " audio/vnd.ms-playready.media.pya " } ,
{ " .pyv " , " video/vnd.ms-playready.media.pyv " } ,
{ " .ppt " , " application/vnd.ms-powerpoint " } ,
{ " .ppam " , " application/vnd.ms-powerpoint.addin.macroenabled.12 " } ,
{ " .sldm " , " application/vnd.ms-powerpoint.slide.macroenabled.12 " } ,
{ " .pptm " , " application/vnd.ms-powerpoint.presentation.macroenabled.12 " } ,
{ " .ppsm " , " application/vnd.ms-powerpoint.slideshow.macroenabled.12 " } ,
{ " .potm " , " application/vnd.ms-powerpoint.template.macroenabled.12 " } ,
{ " .mpp " , " application/vnd.ms-project " } ,
{ " .pub " , " application/x-mspublisher " } ,
{ " .scd " , " application/x-msschedule " } ,
{ " .xap " , " application/x-silverlight-app " } ,
{ " .stl " , " application/vnd.ms-pki.stl " } ,
{ " .cat " , " application/vnd.ms-pki.seccat " } ,
{ " .vsd " , " application/vnd.visio " } ,
{ " .vsdx " , " application/vnd.visio2013 " } ,
{ " .wm " , " video/x-ms-wm " } ,
{ " .wma " , " audio/x-ms-wma " } ,
{ " .wax " , " audio/x-ms-wax " } ,
{ " .wmx " , " video/x-ms-wmx " } ,
{ " .wmd " , " application/x-ms-wmd " } ,
{ " .wpl " , " application/vnd.ms-wpl " } ,
{ " .wmz " , " application/x-ms-wmz " } ,
{ " .wmv " , " video/x-ms-wmv " } ,
{ " .wvx " , " video/x-ms-wvx " } ,
{ " .wmf " , " application/x-msmetafile " } ,
{ " .trm " , " application/x-msterminal " } ,
{ " .doc " , " application/msword " } ,
{ " .docm " , " application/vnd.ms-word.document.macroenabled.12 " } ,
{ " .dotm " , " application/vnd.ms-word.template.macroenabled.12 " } ,
{ " .wri " , " application/x-mswrite " } ,
{ " .wps " , " application/vnd.ms-works " } ,
{ " .xbap " , " application/x-ms-xbap " } ,
{ " .xps " , " application/vnd.ms-xpsdocument " } ,
{ " .mid " , " audio/midi " } ,
{ " .mpy " , " application/vnd.ibm.minipay " } ,
{ " .afp " , " application/vnd.ibm.modcap " } ,
{ " .rms " , " application/vnd.jcp.javame.midlet-rms " } ,
{ " .tmo " , " application/vnd.tmobile-livetv " } ,
{ " .prc " , " application/x-mobipocket-ebook " } ,
{ " .mbk " , " application/vnd.mobius.mbk " } ,
{ " .dis " , " application/vnd.mobius.dis " } ,
{ " .plc " , " application/vnd.mobius.plc " } ,
{ " .mqy " , " application/vnd.mobius.mqy " } ,
{ " .msl " , " application/vnd.mobius.msl " } ,
{ " .txf " , " application/vnd.mobius.txf " } ,
{ " .daf " , " application/vnd.mobius.daf " } ,
{ " .fly " , " text/vnd.fly " } ,
{ " .mpc " , " application/vnd.mophun.certificate " } ,
{ " .mpn " , " application/vnd.mophun.application " } ,
{ " .mj2 " , " video/mj2 " } ,
{ " .mpga " , " audio/mpeg " } ,
{ " .mxu " , " video/vnd.mpegurl " } ,
{ " .mpeg " , " video/mpeg " } ,
{ " .m21 " , " application/mp21 " } ,
{ " .mp4a " , " audio/mp4 " } ,
{ " .mp4 " , " video/mp4 " } ,
{ " .mp4 " , " application/mp4 " } ,
{ " .m3u8 " , " application/vnd.apple.mpegurl " } ,
{ " .mus " , " application/vnd.musician " } ,
{ " .msty " , " application/vnd.muvee.style " } ,
{ " .mxml " , " application/xv+xml " } ,
{ " .ngdat " , " application/vnd.nokia.n-gage.data " } ,
{ " .n-gage " , " application/vnd.nokia.n-gage.symbian.install " } ,
{ " .ncx " , " application/x-dtbncx+xml " } ,
{ " .nc " , " application/x-netcdf " } ,
{ " .nlu " , " application/vnd.neurolanguage.nlu " } ,
{ " .dna " , " application/vnd.dna " } ,
{ " .nnd " , " application/vnd.noblenet-directory " } ,
{ " .nns " , " application/vnd.noblenet-sealer " } ,
{ " .nnw " , " application/vnd.noblenet-web " } ,
{ " .rpst " , " application/vnd.nokia.radio-preset " } ,
{ " .rpss " , " application/vnd.nokia.radio-presets " } ,
{ " .n3 " , " text/n3 " } ,
{ " .edm " , " application/vnd.novadigm.edm " } ,
{ " .edx " , " application/vnd.novadigm.edx " } ,
{ " .ext " , " application/vnd.novadigm.ext " } ,
{ " .gph " , " application/vnd.flographit " } ,
{ " .ecelp4800 " , " audio/vnd.nuera.ecelp4800 " } ,
{ " .ecelp7470 " , " audio/vnd.nuera.ecelp7470 " } ,
{ " .ecelp9600 " , " audio/vnd.nuera.ecelp9600 " } ,
{ " .oda " , " application/oda " } ,
{ " .ogx " , " application/ogg " } ,
{ " .oga " , " audio/ogg " } ,
{ " .ogv " , " video/ogg " } ,
{ " .dd2 " , " application/vnd.oma.dd2+xml " } ,
{ " .oth " , " application/vnd.oasis.opendocument.text-web " } ,
{ " .opf " , " application/oebps-package+xml " } ,
{ " .qbo " , " application/vnd.intu.qbo " } ,
{ " .oxt " , " application/vnd.openofficeorg.extension " } ,
{ " .osf " , " application/vnd.yamaha.openscoreformat " } ,
{ " .weba " , " audio/webm " } ,
{ " .webm " , " video/webm " } ,
{ " .odc " , " application/vnd.oasis.opendocument.chart " } ,
{ " .otc " , " application/vnd.oasis.opendocument.chart-template " } ,
{ " .odb " , " application/vnd.oasis.opendocument.database " } ,
{ " .odf " , " application/vnd.oasis.opendocument.formula " } ,
{ " .odft " , " application/vnd.oasis.opendocument.formula-template " } ,
{ " .odg " , " application/vnd.oasis.opendocument.graphics " } ,
{ " .otg " , " application/vnd.oasis.opendocument.graphics-template " } ,
{ " .odi " , " application/vnd.oasis.opendocument.image " } ,
{ " .oti " , " application/vnd.oasis.opendocument.image-template " } ,
{ " .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 " } ,
{ " .odt " , " application/vnd.oasis.opendocument.text " } ,
{ " .odm " , " application/vnd.oasis.opendocument.text-master " } ,
{ " .ott " , " application/vnd.oasis.opendocument.text-template " } ,
{ " .ktx " , " image/ktx " } ,
{ " .sxc " , " application/vnd.sun.xml.calc " } ,
{ " .stc " , " application/vnd.sun.xml.calc.template " } ,
{ " .sxd " , " application/vnd.sun.xml.draw " } ,
{ " .std " , " application/vnd.sun.xml.draw.template " } ,
{ " .sxi " , " application/vnd.sun.xml.impress " } ,
{ " .sti " , " application/vnd.sun.xml.impress.template " } ,
{ " .sxm " , " application/vnd.sun.xml.math " } ,
{ " .sxw " , " application/vnd.sun.xml.writer " } ,
{ " .sxg " , " application/vnd.sun.xml.writer.global " } ,
{ " .stw " , " application/vnd.sun.xml.writer.template " } ,
{ " .otf " , " application/x-font-otf " } ,
{ " .osfpvg " , " application/vnd.yamaha.openscoreformat.osfpvg+xml " } ,
{ " .dp " , " application/vnd.osgi.dp " } ,
{ " .pdb " , " application/vnd.palm " } ,
{ " .p " , " text/x-pascal " } ,
{ " .paw " , " application/vnd.pawaafile " } ,
{ " .pclxl " , " application/vnd.hp-pclxl " } ,
{ " .efif " , " application/vnd.picsel " } ,
{ " .pcx " , " image/x-pcx " } ,
{ " .psd " , " image/vnd.adobe.photoshop " } ,
{ " .prf " , " application/pics-rules " } ,
{ " .pic " , " image/x-pict " } ,
{ " .chat " , " application/x-chat " } ,
{ " .p10 " , " application/pkcs10 " } ,
{ " .p12 " , " application/x-pkcs12 " } ,
{ " .p7m " , " application/pkcs7-mime " } ,
{ " .p7s " , " application/pkcs7-signature " } ,
{ " .p7r " , " application/x-pkcs7-certreqresp " } ,
{ " .p7b " , " application/x-pkcs7-certificates " } ,
{ " .p8 " , " application/pkcs8 " } ,
{ " .plf " , " application/vnd.pocketlearn " } ,
{ " .pnm " , " image/x-portable-anymap " } ,
{ " .pbm " , " image/x-portable-bitmap " } ,
{ " .pcf " , " application/x-font-pcf " } ,
{ " .pfr " , " application/font-tdpfr " } ,
{ " .pgn " , " application/x-chess-pgn " } ,
{ " .pgm " , " image/x-portable-graymap " } ,
{ " .png " , " image/png " } ,
{ " .png " , " image/x-citrix-png " } ,
{ " .png " , " image/x-png " } ,
{ " .ppm " , " image/x-portable-pixmap " } ,
{ " .pskcxml " , " application/pskc+xml " } ,
{ " .pml " , " application/vnd.ctc-posml " } ,
{ " .ai " , " application/postscript " } ,
{ " .pfa " , " application/x-font-type1 " } ,
{ " .pbd " , " application/vnd.powerbuilder6 " } ,
{ " .pgp " , " application/pgp-encrypted " } ,
{ " .pgp " , " application/pgp-signature " } ,
{ " .box " , " application/vnd.previewsystems.box " } ,
{ " .ptid " , " application/vnd.pvi.ptid1 " } ,
{ " .pls " , " application/pls+xml " } ,
{ " .str " , " application/vnd.pg.format " } ,
{ " .ei6 " , " application/vnd.pg.osasli " } ,
{ " .dsc " , " text/prs.lines.tag " } ,
{ " .psf " , " application/x-font-linux-psf " } ,
{ " .qps " , " application/vnd.publishare-delta-tree " } ,
{ " .wg " , " application/vnd.pmi.widget " } ,
{ " .qxd " , " application/vnd.quark.quarkxpress " } ,
{ " .esf " , " application/vnd.epson.esf " } ,
{ " .msf " , " application/vnd.epson.msf " } ,
{ " .ssf " , " application/vnd.epson.ssf " } ,
{ " .qam " , " application/vnd.epson.quickanime " } ,
{ " .qfx " , " application/vnd.intu.qfx " } ,
{ " .qt " , " video/quicktime " } ,
{ " .rar " , " application/x-rar-compressed " } ,
{ " .ram " , " audio/x-pn-realaudio " } ,
{ " .rmp " , " audio/x-pn-realaudio-plugin " } ,
{ " .rsd " , " application/rsd+xml " } ,
{ " .rm " , " application/vnd.rn-realmedia " } ,
{ " .bed " , " application/vnd.realvnc.bed " } ,
{ " .mxl " , " application/vnd.recordare.musicxml " } ,
{ " .musicxml " , " application/vnd.recordare.musicxml+xml " } ,
{ " .rnc " , " application/relax-ng-compact-syntax " } ,
{ " .rdz " , " application/vnd.data-vision.rdz " } ,
{ " .rdf " , " application/rdf+xml " } ,
{ " .rp9 " , " application/vnd.cloanto.rp9 " } ,
{ " .jisp " , " application/vnd.jisp " } ,
{ " .rtf " , " application/rtf " } ,
{ " .rtx " , " text/richtext " } ,
{ " .link66 " , " application/vnd.route66.link66+xml " } ,
{ " .rss " , " application/rss+xml " } ,
{ " .shf " , " application/shf+xml " } ,
{ " .st " , " application/vnd.sailingtracker.track " } ,
{ " .svg " , " image/svg+xml " } ,
{ " .sus " , " application/vnd.sus-calendar " } ,
{ " .sru " , " application/sru+xml " } ,
{ " .setpay " , " application/set-payment-initiation " } ,
{ " .setreg " , " application/set-registration-initiation " } ,
{ " .sema " , " application/vnd.sema " } ,
{ " .semd " , " application/vnd.semd " } ,
{ " .semf " , " application/vnd.semf " } ,
{ " .see " , " application/vnd.seemail " } ,
{ " .snf " , " application/x-font-snf " } ,
{ " .spq " , " application/scvp-vp-request " } ,
{ " .spp " , " application/scvp-vp-response " } ,
{ " .scq " , " application/scvp-cv-request " } ,
{ " .scs " , " application/scvp-cv-response " } ,
{ " .sdp " , " application/sdp " } ,
{ " .etx " , " text/x-setext " } ,
{ " .movie " , " video/x-sgi-movie " } ,
{ " .ifm " , " application/vnd.shana.informed.formdata " } ,
{ " .itp " , " application/vnd.shana.informed.formtemplate " } ,
{ " .iif " , " application/vnd.shana.informed.interchange " } ,
{ " .ipk " , " application/vnd.shana.informed.package " } ,
{ " .tfi " , " application/thraud+xml " } ,
{ " .shar " , " application/x-shar " } ,
{ " .rgb " , " image/x-rgb " } ,
{ " .slt " , " application/vnd.epson.salt " } ,
{ " .aso " , " application/vnd.accpac.simply.aso " } ,
{ " .imp " , " application/vnd.accpac.simply.imp " } ,
{ " .twd " , " application/vnd.simtech-mindmapper " } ,
{ " .csp " , " application/vnd.commonspace " } ,
{ " .saf " , " application/vnd.yamaha.smaf-audio " } ,
{ " .mmf " , " application/vnd.smaf " } ,
{ " .spf " , " application/vnd.yamaha.smaf-phrase " } ,
{ " .teacher " , " application/vnd.smart.teacher " } ,
{ " .svd " , " application/vnd.svd " } ,
{ " .rq " , " application/sparql-query " } ,
{ " .srx " , " application/sparql-results+xml " } ,
{ " .gram " , " application/srgs " } ,
{ " .grxml " , " application/srgs+xml " } ,
{ " .ssml " , " application/ssml+xml " } ,
{ " .skp " , " application/vnd.koan " } ,
{ " .sgml " , " text/sgml " } ,
{ " .sdc " , " application/vnd.stardivision.calc " } ,
{ " .sda " , " application/vnd.stardivision.draw " } ,
{ " .sdd " , " application/vnd.stardivision.impress " } ,
{ " .smf " , " application/vnd.stardivision.math " } ,
{ " .sdw " , " application/vnd.stardivision.writer " } ,
{ " .sgl " , " application/vnd.stardivision.writer-global " } ,
{ " .sm " , " application/vnd.stepmania.stepchart " } ,
{ " .sit " , " application/x-stuffit " } ,
{ " .sitx " , " application/x-stuffitx " } ,
{ " .sdkm " , " application/vnd.solent.sdkm+xml " } ,
{ " .xo " , " application/vnd.olpc-sugar " } ,
{ " .au " , " audio/basic " } ,
{ " .wqd " , " application/vnd.wqd " } ,
{ " .sis " , " application/vnd.symbian.install " } ,
{ " .smi " , " application/smil+xml " } ,
{ " .xsm " , " application/vnd.syncml+xml " } ,
{ " .bdm " , " application/vnd.syncml.dm+wbxml " } ,
{ " .xdm " , " application/vnd.syncml.dm+xml " } ,
{ " .sv4cpio " , " application/x-sv4cpio " } ,
{ " .sv4crc " , " application/x-sv4crc " } ,
{ " .sbml " , " application/sbml+xml " } ,
{ " .tsv " , " text/tab-separated-values " } ,
{ " .tiff " , " image/tiff " } ,
{ " .tao " , " application/vnd.tao.intent-module-archive " } ,
{ " .tar " , " application/x-tar " } ,
{ " .tcl " , " application/x-tcl " } ,
{ " .tex " , " application/x-tex " } ,
{ " .tfm " , " application/x-tex-tfm " } ,
{ " .tei " , " application/tei+xml " } ,
{ " .txt " , " text/plain; charset=utf-8 " } ,
{ " .md " , " text/markdown; charset=utf-8 " } ,
{ " .dxp " , " application/vnd.spotfire.dxp " } ,
{ " .sfs " , " application/vnd.spotfire.sfs " } ,
{ " .tsd " , " application/timestamped-data " } ,
{ " .tpt " , " application/vnd.trid.tpt " } ,
{ " .mxs " , " application/vnd.triscape.mxs " } ,
{ " .t " , " text/troff " } ,
{ " .tra " , " application/vnd.trueapp " } ,
{ " .ttf " , " application/x-font-ttf " } ,
{ " .ttl " , " text/turtle " } ,
{ " .umj " , " application/vnd.umajin " } ,
{ " .uoml " , " application/vnd.uoml+xml " } ,
{ " .unityweb " , " application/vnd.unity " } ,
{ " .ufd " , " application/vnd.ufdl " } ,
{ " .uri " , " text/uri-list " } ,
{ " .utz " , " application/vnd.uiq.theme " } ,
{ " .ustar " , " application/x-ustar " } ,
{ " .uu " , " text/x-uuencode " } ,
{ " .vcs " , " text/x-vcalendar " } ,
{ " .vcf " , " text/x-vcard " } ,
{ " .vcd " , " application/x-cdlink " } ,
{ " .vsf " , " application/vnd.vsf " } ,
{ " .wrl " , " model/vrml " } ,
{ " .vcx " , " application/vnd.vcx " } ,
{ " .mts " , " model/vnd.mts " } ,
{ " .vtu " , " model/vnd.vtu " } ,
{ " .vis " , " application/vnd.visionary " } ,
{ " .viv " , " video/vnd.vivo " } ,
{ " .ccxml " , " application/ccxml+xml " } ,
{ " .vxml " , " application/voicexml+xml " } ,
{ " .src " , " application/x-wais-source " } ,
{ " .wbxml " , " application/vnd.wap.wbxml " } ,
{ " .wbmp " , " image/vnd.wap.wbmp " } ,
{ " .wav " , " audio/x-wav " } ,
{ " .davmount " , " application/davmount+xml " } ,
{ " .woff " , " application/x-font-woff " } ,
{ " .wspolicy " , " application/wspolicy+xml " } ,
{ " .webp " , " image/webp " } ,
{ " .wtb " , " application/vnd.webturbo " } ,
{ " .wgt " , " application/widget " } ,
{ " .hlp " , " application/winhlp " } ,
{ " .wml " , " text/vnd.wap.wml " } ,
{ " .wmls " , " text/vnd.wap.wmlscript " } ,
{ " .wmlsc " , " application/vnd.wap.wmlscriptc " } ,
{ " .wpd " , " application/vnd.wordperfect " } ,
{ " .stf " , " application/vnd.wt.stf " } ,
{ " .wsdl " , " application/wsdl+xml " } ,
{ " .xbm " , " image/x-xbitmap " } ,
{ " .xpm " , " image/x-xpixmap " } ,
{ " .xwd " , " image/x-xwindowdump " } ,
{ " .der " , " application/x-x509-ca-cert " } ,
{ " .fig " , " application/x-xfig " } ,
{ " .xhtml " , " application/xhtml+xml " } ,
{ " .xml " , " application/xml " } ,
{ " .xdf " , " application/xcap-diff+xml " } ,
{ " .xenc " , " application/xenc+xml " } ,
{ " .xer " , " application/patch-ops-error+xml " } ,
{ " .rl " , " application/resource-lists+xml " } ,
{ " .rs " , " application/rls-services+xml " } ,
{ " .rld " , " application/resource-lists-diff+xml " } ,
{ " .xslt " , " application/xslt+xml " } ,
{ " .xop " , " application/xop+xml " } ,
{ " .xpi " , " application/x-xpinstall " } ,
{ " .xspf " , " application/xspf+xml " } ,
{ " .xul " , " application/vnd.mozilla.xul+xml " } ,
{ " .xyz " , " chemical/x-xyz " } ,
{ " .yaml " , " text/yaml " } ,
{ " .yang " , " application/yang " } ,
{ " .yin " , " application/yin+xml " } ,
{ " .zir " , " application/vnd.zul " } ,
{ " .zip " , " application/zip " } ,
{ " .zmm " , " application/vnd.handheld-entertainment+xml " } ,
{ " .zaz " , " application/vnd.zzazz.deck+xml " } ,
} ;
// Detect HTTP MIME type from filename
char * GetMimeTypeFromFileName ( char * filename )
{
UINT i ;
const UINT num = sizeof ( http_mime_types ) / sizeof ( HTTP_MIME_TYPE ) ;
if ( filename = = NULL )
{
return NULL ;
}
for ( i = 0 ; i < num ; + + i )
{
const HTTP_MIME_TYPE * a = & http_mime_types [ i ] ;
if ( EndWith ( filename , a - > Extension ) )
{
return a - > MimeType ;
}
}
return NULL ;
}
2019-10-20 03:17:42 +03:00
// Generate the date and time string for the HTTP header
void GetHttpDateStr ( char * str , UINT size , UINT64 t )
{
SYSTEMTIME s ;
static char * wday [ ] =
{
" Sun " , " Mon " , " Tue " , " Wed " , " Thu " , " Fri " , " Sat " ,
} ;
static char * month [ ] =
{
" Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " , " Jul " , " Aug " , " Sep " , " Oct " ,
" Nov " , " Dec " ,
} ;
// Validate arguments
if ( str = = NULL )
{
return ;
}
UINT64ToSystem ( & s , t ) ;
Format ( str , size , " %s, %02u %s %04u %02u:%02u:%02u GMT " ,
wday [ s . wDayOfWeek ] , s . wDay , month [ s . wMonth - 1 ] , s . wYear ,
s . wHour , s . wMinute , s . wSecond ) ;
}
// Replace unsafe characters in target
void ReplaceUnsafeCharInHttpTarget ( char * target )
{
UINT i ;
for ( i = 0 ; target [ i ] ; i + + ) {
if ( target [ i ] = = ' < ' )
target [ i ] = ' ( ' ;
else if ( target [ i ] = = ' > ' )
target [ i ] = ' ) ' ;
}
}
// Create an HTTP header
HTTP_HEADER * NewHttpHeader ( char * method , char * target , char * version )
{
return NewHttpHeaderEx ( method , target , version , false ) ;
}
HTTP_HEADER * NewHttpHeaderEx ( char * method , char * target , char * version , bool no_sort )
{
HTTP_HEADER * header ;
// Validate arguments
if ( method = = NULL | | target = = NULL | | version = = NULL )
{
return NULL ;
}
header = ZeroMalloc ( sizeof ( HTTP_HEADER ) ) ;
header - > Method = CopyStr ( method ) ;
header - > Target = CopyStr ( target ) ;
header - > Version = CopyStr ( version ) ;
header - > ValueList = NewListFast ( no_sort ? NULL : CompareHttpValue ) ;
return header ;
}
// Release the HTTP header
void FreeHttpHeader ( HTTP_HEADER * header )
{
UINT i ;
HTTP_VALUE * * values ;
// Validate arguments
if ( header = = NULL )
{
return ;
}
Free ( header - > Method ) ;
Free ( header - > Target ) ;
Free ( header - > Version ) ;
values = ToArray ( header - > ValueList ) ;
for ( i = 0 ; i < LIST_NUM ( header - > ValueList ) ; i + + )
{
FreeHttpValue ( values [ i ] ) ;
}
Free ( values ) ;
ReleaseList ( header - > ValueList ) ;
Free ( header ) ;
}
// Create a new HTTP value
HTTP_VALUE * NewHttpValue ( char * name , char * data )
{
HTTP_VALUE * v ;
// Validate arguments
if ( name = = NULL | | data = = NULL )
{
return NULL ;
}
v = ZeroMalloc ( sizeof ( HTTP_VALUE ) ) ;
v - > Name = CopyStr ( name ) ;
v - > Data = CopyStr ( data ) ;
Trim ( v - > Name ) ;
Trim ( v - > Data ) ;
return v ;
}
// Release the HTTP value
void FreeHttpValue ( HTTP_VALUE * value )
{
// Validate arguments
if ( value = = NULL )
{
return ;
}
Free ( value - > Data ) ;
Free ( value - > Name ) ;
Free ( value ) ;
}
// Comparison function of the HTTP value
int CompareHttpValue ( void * p1 , void * p2 )
{
HTTP_VALUE * v1 , * v2 ;
if ( p1 = = NULL | | p2 = = NULL )
{
return 0 ;
}
v1 = * ( HTTP_VALUE * * ) p1 ;
v2 = * ( HTTP_VALUE * * ) p2 ;
if ( v1 = = NULL | | v2 = = NULL )
{
return 0 ;
}
return StrCmpi ( v1 - > Name , v2 - > Name ) ;
}
// Look for an HTTP value in an HTTP header
HTTP_VALUE * GetHttpValue ( HTTP_HEADER * header , char * name )
{
HTTP_VALUE * v , t ;
// Validate arguments
if ( header = = NULL | | name = = NULL )
{
return NULL ;
}
t . Name = name ;
v = Search ( header - > ValueList , & t ) ;
if ( v = = NULL )
{
return NULL ;
}
return v ;
}
// Add an HTTP value to the HTTP header
void AddHttpValue ( HTTP_HEADER * header , HTTP_VALUE * value )
{
// Validate arguments
if ( header = = NULL | | value = = NULL )
{
return ;
}
if ( LIST_NUM ( header - > ValueList ) < HTTP_HEADER_MAX_LINES )
{
Insert ( header - > ValueList , value ) ;
}
else
{
FreeHttpValue ( value ) ;
}
}
// Adds the HTTP value contained in the string to the HTTP header
bool AddHttpValueStr ( HTTP_HEADER * header , char * string )
{
HTTP_VALUE * value = NULL ;
UINT pos = 0 ;
char * value_name = NULL ;
char * value_data = NULL ;
// Validate arguments
if ( header = = NULL | | IsEmptyStr ( string ) )
{
return false ;
}
// Sanitize string
EnSafeHttpHeaderValueStr ( string , ' ' ) ;
// Get the position of the colon
pos = SearchStr ( string , " : " , 0 ) ;
if ( pos = = INFINITE )
{
// The colon does not exist
return false ;
}
if ( ( pos + 1 ) > = StrLen ( string ) )
{
// There is no data
return false ;
}
// Divide into the name and the data
value_name = Malloc ( pos + 1 ) ;
Copy ( value_name , string , pos ) ;
value_name [ pos ] = 0 ;
value_data = & string [ pos + 1 ] ;
value = NewHttpValue ( value_name , value_data ) ;
if ( value = = NULL )
{
Free ( value_name ) ;
return false ;
}
Free ( value_name ) ;
AddHttpValue ( header , value ) ;
return true ;
}
// Get the Content-Length value from the HTTP header
UINT GetContentLength ( HTTP_HEADER * header )
{
UINT ret ;
HTTP_VALUE * v ;
// Validate arguments
if ( header = = NULL )
{
return 0 ;
}
v = GetHttpValue ( header , " Content-Length " ) ;
if ( v = = NULL )
{
return 0 ;
}
ret = ToInt ( v - > Data ) ;
return ret ;
}
// Send HTTP data
bool PostHttp ( SOCK * s , HTTP_HEADER * header , void * post_data , UINT post_size )
{
char * header_str ;
BUF * b ;
bool ret ;
// Validate arguments
if ( s = = NULL | | header = = NULL | | ( post_size ! = 0 & & post_data = = NULL ) )
{
return false ;
}
// Check whether the Content-Length exists?
if ( GetHttpValue ( header , " Content-Length " ) = = NULL )
{
char tmp [ MAX_SIZE ] ;
// Add because it does not exist
ToStr ( tmp , post_size ) ;
AddHttpValue ( header , NewHttpValue ( " Content-Length " , tmp ) ) ;
}
// Convert the header to string
header_str = HttpHeaderToStr ( header ) ;
if ( header_str = = NULL )
{
return false ;
}
b = NewBuf ( ) ;
WriteBuf ( b , header_str , StrLen ( header_str ) ) ;
Free ( header_str ) ;
// Append the data
WriteBuf ( b , post_data , post_size ) ;
// Send
ret = SendAll ( s , b - > Buf , b - > Size , s - > SecureMode ) ;
FreeBuf ( b ) ;
return ret ;
}
// Convert an HTTP header to a string
char * HttpHeaderToStr ( HTTP_HEADER * header )
{
BUF * b ;
char * tmp ;
UINT i ;
char * s ;
// Validate arguments
if ( header = = NULL )
{
return NULL ;
}
tmp = Malloc ( HTTP_HEADER_LINE_MAX_SIZE ) ;
b = NewBuf ( ) ;
// Header
Format ( tmp , HTTP_HEADER_LINE_MAX_SIZE ,
" %s %s %s \r \n " , header - > Method , header - > Target , header - > Version ) ;
WriteBuf ( b , tmp , StrLen ( tmp ) ) ;
// Value
for ( i = 0 ; i < LIST_NUM ( header - > ValueList ) ; i + + )
{
HTTP_VALUE * v = ( HTTP_VALUE * ) LIST_DATA ( header - > ValueList , i ) ;
Format ( tmp , HTTP_HEADER_LINE_MAX_SIZE ,
" %s: %s \r \n " , v - > Name , v - > Data ) ;
WriteBuf ( b , tmp , StrLen ( tmp ) ) ;
}
// Trailing newline
WriteBuf ( b , " \r \n " , 2 ) ;
s = Malloc ( b - > Size + 1 ) ;
Copy ( s , b - > Buf , b - > Size ) ;
s [ b - > Size ] = 0 ;
FreeBuf ( b ) ;
Free ( tmp ) ;
return s ;
}
// Send the HTTP header
bool SendHttpHeader ( SOCK * s , HTTP_HEADER * header )
{
char * str ;
bool ret ;
// Validate arguments
if ( s = = NULL | | header = = NULL )
{
return false ;
}
// Convert to string
str = HttpHeaderToStr ( header ) ;
// Transmission
ret = SendAll ( s , str , StrLen ( str ) , s - > SecureMode ) ;
Free ( str ) ;
return ret ;
}
// Receive an HTTP header
HTTP_HEADER * RecvHttpHeader ( SOCK * s )
{
TOKEN_LIST * token = NULL ;
char * str = NULL ;
HTTP_HEADER * header = NULL ;
// Validate arguments
if ( s = = NULL )
{
return NULL ;
}
// Get the first line
str = RecvLine ( s , HTTP_HEADER_LINE_MAX_SIZE ) ;
if ( str = = NULL )
{
return NULL ;
}
// Split into tokens
token = ParseToken ( str , " " ) ;
FreeSafe ( PTR_TO_PTR ( str ) ) ;
if ( token - > NumTokens < 3 )
{
FreeToken ( token ) ;
return NULL ;
}
// Creating a header object
header = NewHttpHeader ( token - > Token [ 0 ] , token - > Token [ 1 ] , token - > Token [ 2 ] ) ;
FreeToken ( token ) ;
if ( StrCmpi ( header - > Version , " HTTP/0.9 " ) = = 0 )
{
// The header ends with this line
return header ;
}
// Get the subsequent lines
while ( true )
{
str = RecvLine ( s , HTTP_HEADER_LINE_MAX_SIZE ) ;
Trim ( str ) ;
if ( IsEmptyStr ( str ) )
{
// End of header
FreeSafe ( PTR_TO_PTR ( str ) ) ;
break ;
}
if ( AddHttpValueStr ( header , str ) = = false )
{
FreeSafe ( PTR_TO_PTR ( str ) ) ;
FreeHttpHeader ( header ) ;
header = NULL ;
break ;
}
FreeSafe ( PTR_TO_PTR ( str ) ) ;
}
return header ;
}
// Send a PACK to the server
bool HttpClientSend ( SOCK * s , PACK * p )
{
BUF * b ;
bool ret ;
HTTP_HEADER * h ;
char date_str [ MAX_SIZE ] ;
char ip_str [ MAX_SIZE ] ;
// Validate arguments
if ( s = = NULL | | p = = NULL )
{
return false ;
}
IPToStr ( ip_str , sizeof ( ip_str ) , & s - > RemoteIP ) ;
CreateDummyValue ( p ) ;
b = PackToBuf ( p ) ;
if ( b = = NULL )
{
return false ;
}
h = NewHttpHeader ( " POST " , HTTP_VPN_TARGET , " HTTP/1.1 " ) ;
GetHttpDateStr ( date_str , sizeof ( date_str ) , SystemTime64 ( ) ) ;
AddHttpValue ( h , NewHttpValue ( " Date " , date_str ) ) ;
AddHttpValue ( h , NewHttpValue ( " Host " , ip_str ) ) ;
AddHttpValue ( h , NewHttpValue ( " Keep-Alive " , HTTP_KEEP_ALIVE ) ) ;
AddHttpValue ( h , NewHttpValue ( " Connection " , " Keep-Alive " ) ) ;
AddHttpValue ( h , NewHttpValue ( " Content-Type " , HTTP_CONTENT_TYPE2 ) ) ;
ret = PostHttp ( s , h , b - > Buf , b - > Size ) ;
FreeHttpHeader ( h ) ;
FreeBuf ( b ) ;
return ret ;
}
// Receive a PACK from the server
PACK * HttpClientRecv ( SOCK * s )
{
BUF * b ;
PACK * p ;
HTTP_HEADER * h ;
UINT size ;
UCHAR * tmp ;
HTTP_VALUE * v ;
// Validate arguments
if ( s = = NULL )
{
return NULL ;
}
h = RecvHttpHeader ( s ) ;
if ( h = = NULL )
{
return NULL ;
}
if ( StrCmpi ( h - > Method , " HTTP/1.1 " ) ! = 0 | |
StrCmpi ( h - > Target , " 200 " ) ! = 0 )
{
FreeHttpHeader ( h ) ;
return NULL ;
}
v = GetHttpValue ( h , " Content-Type " ) ;
if ( v = = NULL | | StrCmpi ( v - > Data , HTTP_CONTENT_TYPE2 ) ! = 0 )
{
FreeHttpHeader ( h ) ;
return NULL ;
}
size = GetContentLength ( h ) ;
if ( size = = 0 | | size > MAX_PACK_SIZE )
{
FreeHttpHeader ( h ) ;
return NULL ;
}
tmp = MallocEx ( size , true ) ;
if ( RecvAll ( s , tmp , size , s - > SecureMode ) = = false )
{
Free ( tmp ) ;
FreeHttpHeader ( h ) ;
return NULL ;
}
b = NewBuf ( ) ;
WriteBuf ( b , tmp , size ) ;
Free ( tmp ) ;
FreeHttpHeader ( h ) ;
SeekBuf ( b , 0 , 0 ) ;
p = BufToPack ( b ) ;
FreeBuf ( b ) ;
return p ;
}
// Send a PACK to the client
bool HttpServerSend ( SOCK * s , PACK * p )
{
BUF * b ;
bool ret ;
HTTP_HEADER * h ;
char date_str [ MAX_SIZE ] ;
// Validate arguments
if ( s = = NULL | | p = = NULL )
{
return false ;
}
CreateDummyValue ( p ) ;
b = PackToBuf ( p ) ;
if ( b = = NULL )
{
return false ;
}
h = NewHttpHeader ( " HTTP/1.1 " , " 200 " , " OK " ) ;
GetHttpDateStr ( date_str , sizeof ( date_str ) , SystemTime64 ( ) ) ;
AddHttpValue ( h , NewHttpValue ( " Date " , date_str ) ) ;
AddHttpValue ( h , NewHttpValue ( " Keep-Alive " , HTTP_KEEP_ALIVE ) ) ;
AddHttpValue ( h , NewHttpValue ( " Connection " , " Keep-Alive " ) ) ;
AddHttpValue ( h , NewHttpValue ( " Content-Type " , HTTP_CONTENT_TYPE2 ) ) ;
ret = PostHttp ( s , h , b - > Buf , b - > Size ) ;
FreeHttpHeader ( h ) ;
FreeBuf ( b ) ;
return ret ;
}
// Receive a PACK from the client
PACK * HttpServerRecv ( SOCK * s )
{
return HttpServerRecvEx ( s , 0 ) ;
}
PACK * HttpServerRecvEx ( SOCK * s , UINT max_data_size )
{
BUF * b ;
PACK * p ;
HTTP_HEADER * h ;
UINT size ;
UCHAR * tmp ;
HTTP_VALUE * v ;
UINT num_noop = 0 ;
if ( max_data_size = = 0 ) max_data_size = HTTP_PACK_MAX_SIZE ;
// Validate arguments
if ( s = = NULL )
{
return NULL ;
}
START :
h = RecvHttpHeader ( s ) ;
if ( h = = NULL )
{
goto BAD_REQUEST ;
}
if ( StrCmpi ( h - > Method , " POST " ) ! = 0 | |
StrCmpi ( h - > Target , HTTP_VPN_TARGET ) ! = 0 | |
StrCmpi ( h - > Version , " HTTP/1.1 " ) ! = 0 )
{
FreeHttpHeader ( h ) ;
goto BAD_REQUEST ;
}
v = GetHttpValue ( h , " Content-Type " ) ;
if ( v = = NULL | | StrCmpi ( v - > Data , HTTP_CONTENT_TYPE2 ) ! = 0 )
{
FreeHttpHeader ( h ) ;
goto BAD_REQUEST ;
}
size = GetContentLength ( h ) ;
if ( size = = 0 | | ( size > max_data_size ) )
{
FreeHttpHeader ( h ) ;
goto BAD_REQUEST ;
}
tmp = MallocEx ( size , true ) ;
if ( RecvAll ( s , tmp , size , s - > SecureMode ) = = false )
{
Free ( tmp ) ;
FreeHttpHeader ( h ) ;
return NULL ;
}
b = NewBuf ( ) ;
WriteBuf ( b , tmp , size ) ;
Free ( tmp ) ;
FreeHttpHeader ( h ) ;
SeekBuf ( b , 0 , 0 ) ;
p = BufToPack ( b ) ;
FreeBuf ( b ) ;
// Determine whether it's a NOOP
if ( PackGetInt ( p , " noop " ) ! = 0 )
{
Debug ( " recv: noop \n " ) ;
FreePack ( p ) ;
p = PackError ( 0 ) ;
PackAddInt ( p , " noop " , 1 ) ;
if ( HttpServerSend ( s , p ) = = false )
{
FreePack ( p ) ;
return NULL ;
}
FreePack ( p ) ;
num_noop + + ;
if ( num_noop > MAX_NOOP_PER_SESSION )
{
return NULL ;
}
goto START ;
}
return p ;
BAD_REQUEST :
// Return an error
return NULL ;
}
// Send "403 Forbidden" error
bool HttpSendForbidden ( SOCK * s , char * target , char * server_id )
{
HTTP_HEADER * h ;
char date_str [ MAX_SIZE ] ;
char * str ;
UINT str_size ;
char port_str [ MAX_SIZE ] ;
bool ret ;
char host [ MAX_SIZE ] ;
UINT port ;
// Validate arguments
if ( s = = NULL | | target = = NULL )
{
return false ;
}
// Get the host name
//GetMachineName(host, MAX_SIZE);
Zero ( host , sizeof ( host ) ) ;
IPToStr ( host , sizeof ( host ) , & s - > LocalIP ) ;
// Get the port number
port = s - > LocalPort ;
// Creating a header
GetHttpDateStr ( date_str , sizeof ( date_str ) , SystemTime64 ( ) ) ;
h = NewHttpHeader ( " HTTP/1.1 " , " 403 " , " Forbidden " ) ;
AddHttpValue ( h , NewHttpValue ( " Date " , date_str ) ) ;
AddHttpValue ( h , NewHttpValue ( " Keep-Alive " , HTTP_KEEP_ALIVE ) ) ;
AddHttpValue ( h , NewHttpValue ( " Connection " , " Keep-Alive " ) ) ;
AddHttpValue ( h , NewHttpValue ( " Content-Type " , HTTP_CONTENT_TYPE ) ) ;
// Creating a Data
str_size = sizeof ( http_403_str ) * 2 + StrLen ( target ) + StrLen ( host ) ;
str = Malloc ( str_size ) ;
StrCpy ( str , str_size , http_403_str ) ;
// TARGET
ReplaceUnsafeCharInHttpTarget ( target ) ;
ReplaceStri ( str , str_size , str , " $TARGET$ " , target ) ;
// HOST
ReplaceStri ( str , str_size , str , " $HOST$ " , host ) ;
// PORT
ToStr ( port_str , port ) ;
ReplaceStri ( str , str_size , str , " $PORT$ " , port_str ) ;
// Transmission
ret = PostHttp ( s , h , str , StrLen ( str ) ) ;
FreeHttpHeader ( h ) ;
Free ( str ) ;
return ret ;
}
// Send "404 Not Found" error
bool HttpSendNotFound ( SOCK * s , char * target )
{
HTTP_HEADER * h ;
char date_str [ MAX_SIZE ] ;
char * str ;
UINT str_size ;
char port_str [ MAX_SIZE ] ;
bool ret ;
char host [ MAX_SIZE ] ;
UINT port ;
// Validate arguments
if ( s = = NULL | | target = = NULL )
{
return false ;
}
// Get the host name
//GetMachineName(host, MAX_SIZE);
Zero ( host , sizeof ( host ) ) ;
IPToStr ( host , sizeof ( host ) , & s - > LocalIP ) ;
// Get the port number
port = s - > LocalPort ;
// Creating a header
GetHttpDateStr ( date_str , sizeof ( date_str ) , SystemTime64 ( ) ) ;
h = NewHttpHeader ( " HTTP/1.1 " , " 404 " , " Not Found " ) ;
AddHttpValue ( h , NewHttpValue ( " Date " , date_str ) ) ;
AddHttpValue ( h , NewHttpValue ( " Keep-Alive " , HTTP_KEEP_ALIVE ) ) ;
AddHttpValue ( h , NewHttpValue ( " Connection " , " Keep-Alive " ) ) ;
AddHttpValue ( h , NewHttpValue ( " Content-Type " , HTTP_CONTENT_TYPE ) ) ;
// Creating a Data
str_size = sizeof ( http_404_str ) * 2 + StrLen ( target ) + StrLen ( host ) ;
str = Malloc ( str_size ) ;
StrCpy ( str , str_size , http_404_str ) ;
// TARGET
ReplaceUnsafeCharInHttpTarget ( target ) ;
ReplaceStri ( str , str_size , str , " $TARGET$ " , target ) ;
// HOST
ReplaceStri ( str , str_size , str , " $HOST$ " , host ) ;
// PORT
ToStr ( port_str , port ) ;
ReplaceStri ( str , str_size , str , " $PORT$ " , port_str ) ;
// Transmission
ret = PostHttp ( s , h , str , StrLen ( str ) ) ;
FreeHttpHeader ( h ) ;
Free ( str ) ;
return ret ;
}
// Send "501 Not Implemented" error
bool HttpSendNotImplemented ( SOCK * s , char * method , char * target , char * version )
{
HTTP_HEADER * h ;
char date_str [ MAX_SIZE ] ;
char * str ;
UINT str_size ;
char port_str [ MAX_SIZE ] ;
bool ret ;
char host [ MAX_SIZE ] ;
UINT port ;
// Validate arguments
if ( s = = NULL | | target = = NULL )
{
return false ;
}
// Get the host name
//GetMachineName(host, MAX_SIZE);
Zero ( host , sizeof ( host ) ) ;
IPToStr ( host , sizeof ( host ) , & s - > LocalIP ) ;
// Get the port number
port = s - > LocalPort ;
// Creating a header
GetHttpDateStr ( date_str , sizeof ( date_str ) , SystemTime64 ( ) ) ;
h = NewHttpHeader ( " HTTP/1.1 " , " 501 " , " Method Not Implemented " ) ;
AddHttpValue ( h , NewHttpValue ( " Date " , date_str ) ) ;
AddHttpValue ( h , NewHttpValue ( " Keep-Alive " , HTTP_KEEP_ALIVE ) ) ;
AddHttpValue ( h , NewHttpValue ( " Connection " , " Keep-Alive " ) ) ;
AddHttpValue ( h , NewHttpValue ( " Content-Type " , HTTP_CONTENT_TYPE ) ) ;
// Creating a Data
str_size = sizeof ( http_501_str ) * 2 + StrLen ( target ) + StrLen ( host ) + StrLen ( method ) + StrLen ( version ) ;
str = Malloc ( str_size ) ;
StrCpy ( str , str_size , http_501_str ) ;
// TARGET
ReplaceUnsafeCharInHttpTarget ( target ) ;
ReplaceStri ( str , str_size , str , " $TARGET$ " , target ) ;
// HOST
ReplaceStri ( str , str_size , str , " $HOST$ " , host ) ;
// PORT
ToStr ( port_str , port ) ;
ReplaceStri ( str , str_size , str , " $PORT$ " , port_str ) ;
// METHOD
ReplaceStri ( str , str_size , str , " $METHOD$ " , method ) ;
// VERSION
ReplaceStri ( str , str_size , str , " $VERSION$ " , version ) ;
// Transmission
ret = PostHttp ( s , h , str , StrLen ( str ) ) ;
FreeHttpHeader ( h ) ;
Free ( str ) ;
return ret ;
}