diff --git a/.gitignore b/.gitignore index 75c54e9f..d83558cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ EIFGENs tests/temp/ +.svn/ diff --git a/doc/wiki b/doc/wiki index 2b112da4..d14e65fd 160000 --- a/doc/wiki +++ b/doc/wiki @@ -1 +1 @@ -Subproject commit 2b112da43de3cbd7e659e2768460998ebd260b7f +Subproject commit d14e65fdc09686fd15b37f6ce23eb7c8e92fb6bf diff --git a/examples/hello_routed_world/hello-safe.ecf b/examples/hello_routed_world/hello-safe.ecf index ec8e1532..99eb92e6 100644 --- a/examples/hello_routed_world/hello-safe.ecf +++ b/examples/hello_routed_world/hello-safe.ecf @@ -1,5 +1,5 @@ - + @@ -8,14 +8,14 @@ /\.svn$ - + - + diff --git a/examples/hello_routed_world/hello_routed_world.rc b/examples/hello_routed_world/hello_routed_world.rc new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/examples/hello_routed_world/hello_routed_world.rc @@ -0,0 +1 @@ + diff --git a/examples/hello_routed_world/htdocs/dft/index.html b/examples/hello_routed_world/htdocs/dft/index.html new file mode 100644 index 00000000..865e3d2d --- /dev/null +++ b/examples/hello_routed_world/htdocs/dft/index.html @@ -0,0 +1,9 @@ + + + Hello Eiffel::default + + + +

Hello Eiffel Default World

+ + diff --git a/examples/hello_routed_world/htdocs/home.html b/examples/hello_routed_world/htdocs/home.html new file mode 100644 index 00000000..9263a4ab --- /dev/null +++ b/examples/hello_routed_world/htdocs/home.html @@ -0,0 +1,9 @@ + + + Hello Eiffel + + + +

Hello Eiffel World :D

+ + diff --git a/examples/hello_routed_world/htdocs/htdocs.zip b/examples/hello_routed_world/htdocs/htdocs.zip new file mode 100644 index 00000000..0adb386e Binary files /dev/null and b/examples/hello_routed_world/htdocs/htdocs.zip differ diff --git a/examples/hello_routed_world/htdocs/style.css b/examples/hello_routed_world/htdocs/style.css new file mode 100644 index 00000000..e4a5eedd --- /dev/null +++ b/examples/hello_routed_world/htdocs/style.css @@ -0,0 +1 @@ +h1 { border: solid 1px #00f; margin: 5px; padding: 5px; } diff --git a/examples/hello_routed_world/mime.types b/examples/hello_routed_world/mime.types new file mode 100644 index 00000000..6a90929c --- /dev/null +++ b/examples/hello_routed_world/mime.types @@ -0,0 +1,1479 @@ +# This file maps Internet media types to unique file extension(s). +# Although created for httpd, this file is used by many software systems +# and has been placed in the public domain for unlimited redisribution. +# +# The table below contains both registered and (common) unregistered types. +# A type that has no unique extension can be ignored -- they are listed +# here to guide configurations toward known types and to make it easier to +# identify "new" types. File extensions are also commonly used to indicate +# content languages and encodings, so choose them carefully. +# +# Internet media types should be registered as described in RFC 4288. +# The registry is at . +# +# MIME type (lowercased) Extensions +# ============================================ ========== +# application/1d-interleaved-parityfec +# application/3gpp-ims+xml +# application/activemessage +application/andrew-inset ez +# application/applefile +application/applixware aw +application/atom+xml atom +application/atomcat+xml atomcat +# application/atomicmail +application/atomsvc+xml atomsvc +# application/auth-policy+xml +# application/batch-smtp +# application/beep+xml +# application/cals-1840 +application/ccxml+xml ccxml +application/cdmi-capability cdmia +application/cdmi-container cdmic +application/cdmi-domain cdmid +application/cdmi-object cdmio +application/cdmi-queue cdmiq +# application/cea-2018+xml +# application/cellml+xml +# application/cfw +# application/cnrp+xml +# application/commonground +# application/conference-info+xml +# application/cpl+xml +# application/csta+xml +# application/cstadata+xml +application/cu-seeme cu +# application/cybercash +application/davmount+xml davmount +# application/dca-rft +# application/dec-dx +# application/dialog-info+xml +# application/dicom +# application/dns +# application/dskpp+xml +application/dssc+der dssc +application/dssc+xml xdssc +# application/dvcs +application/ecmascript ecma +# application/edi-consent +# application/edi-x12 +# application/edifact +application/emma+xml emma +# application/epp+xml +application/epub+zip epub +# application/eshop +# application/example +application/exi exi +# application/fastinfoset +# application/fastsoap +# application/fits +application/font-tdpfr pfr +# application/framework-attributes+xml +# application/h224 +# application/held+xml +# application/http +application/hyperstudio stk +# application/ibe-key-request+xml +# application/ibe-pkg-reply+xml +# application/ibe-pp-data +# application/iges +# application/im-iscomposing+xml +# application/index +# application/index.cmd +# application/index.obj +# application/index.response +# application/index.vnd +# application/iotp +application/ipfix ipfix +# application/ipp +# application/isup +application/java-archive jar +application/java-serialized-object ser +application/java-vm class +application/javascript js +application/json json +# application/kpml-request+xml +# application/kpml-response+xml +application/lost+xml lostxml +application/mac-binhex40 hqx +application/mac-compactpro cpt +# application/macwriteii +application/mads+xml mads +application/marc mrc +application/marcxml+xml mrcx +application/mathematica ma nb mb +# application/mathml-content+xml +# application/mathml-presentation+xml +application/mathml+xml mathml +# application/mbms-associated-procedure-description+xml +# application/mbms-deregister+xml +# application/mbms-envelope+xml +# application/mbms-msk+xml +# application/mbms-msk-response+xml +# application/mbms-protection-description+xml +# application/mbms-reception-report+xml +# application/mbms-register+xml +# application/mbms-register-response+xml +# application/mbms-user-service-description+xml +application/mbox mbox +# application/media_control+xml +application/mediaservercontrol+xml mscml +application/metalink4+xml meta4 +application/mets+xml mets +# application/mikey +application/mods+xml mods +# application/moss-keys +# application/moss-signature +# application/mosskey-data +# application/mosskey-request +application/mp21 m21 mp21 +application/mp4 mp4s +# application/mpeg4-generic +# application/mpeg4-iod +# application/mpeg4-iod-xmt +# application/msc-ivr+xml +# application/msc-mixer+xml +application/msword doc dot +application/mxf mxf +# application/nasdata +# application/news-checkgroups +# application/news-groupinfo +# application/news-transmission +# application/nss +# application/ocsp-request +# application/ocsp-response +application/octet-stream bin dms lha lrf lzh so iso dmg dist distz pkg bpk dump elc deploy +application/oda oda +application/oebps-package+xml opf +application/ogg ogx +application/onenote onetoc onetoc2 onetmp onepkg +# application/parityfec +application/patch-ops-error+xml xer +application/pdf pdf +application/pgp-encrypted pgp +# application/pgp-keys +application/pgp-signature asc sig +application/pics-rules prf +# application/pidf+xml +# application/pidf-diff+xml +application/pkcs10 p10 +application/pkcs7-mime p7m p7c +application/pkcs7-signature p7s +application/pkcs8 p8 +application/pkix-attr-cert ac +application/pkix-cert cer +application/pkix-crl crl +application/pkix-pkipath pkipath +application/pkixcmp pki +application/pls+xml pls +# application/poc-settings+xml +application/postscript ai eps ps +# application/prs.alvestrand.titrax-sheet +application/prs.cww cww +# application/prs.nprend +# application/prs.plucker +# application/prs.rdf-xml-crypt +# application/prs.xsf+xml +application/pskc+xml pskcxml +# application/qsig +application/rdf+xml rdf +application/reginfo+xml rif +application/relax-ng-compact-syntax rnc +# application/remote-printing +application/resource-lists+xml rl +application/resource-lists-diff+xml rld +# application/riscos +# application/rlmi+xml +application/rls-services+xml rs +application/rsd+xml rsd +application/rss+xml rss +application/rtf rtf +# application/rtx +# application/samlassertion+xml +# application/samlmetadata+xml +application/sbml+xml sbml +application/scvp-cv-request scq +application/scvp-cv-response scs +application/scvp-vp-request spq +application/scvp-vp-response spp +application/sdp sdp +# application/set-payment +application/set-payment-initiation setpay +# application/set-registration +application/set-registration-initiation setreg +# application/sgml +# application/sgml-open-catalog +application/shf+xml shf +# application/sieve +# application/simple-filter+xml +# application/simple-message-summary +# application/simplesymbolcontainer +# application/slate +# application/smil +application/smil+xml smi smil +# application/soap+fastinfoset +# application/soap+xml +application/sparql-query rq +application/sparql-results+xml srx +# application/spirits-event+xml +application/srgs gram +application/srgs+xml grxml +application/sru+xml sru +application/ssml+xml ssml +# application/tamp-apex-update +# application/tamp-apex-update-confirm +# application/tamp-community-update +# application/tamp-community-update-confirm +# application/tamp-error +# application/tamp-sequence-adjust +# application/tamp-sequence-adjust-confirm +# application/tamp-status-query +# application/tamp-status-response +# application/tamp-update +# application/tamp-update-confirm +application/tei+xml tei teicorpus +application/thraud+xml tfi +# application/timestamp-query +# application/timestamp-reply +application/timestamped-data tsd +# application/tve-trigger +# application/ulpfec +# application/vemmi +# application/vividence.scriptfile +# application/vnd.3gpp.bsf+xml +application/vnd.3gpp.pic-bw-large plb +application/vnd.3gpp.pic-bw-small psb +application/vnd.3gpp.pic-bw-var pvb +# application/vnd.3gpp.sms +# application/vnd.3gpp2.bcmcsinfo+xml +# application/vnd.3gpp2.sms +application/vnd.3gpp2.tcap tcap +application/vnd.3m.post-it-notes pwn +application/vnd.accpac.simply.aso aso +application/vnd.accpac.simply.imp imp +application/vnd.acucobol acu +application/vnd.acucorp atc acutc +application/vnd.adobe.air-application-installer-package+zip air +application/vnd.adobe.fxp fxp fxpl +# application/vnd.adobe.partial-upload +application/vnd.adobe.xdp+xml xdp +application/vnd.adobe.xfdf xfdf +# application/vnd.aether.imp +# application/vnd.ah-barcode +application/vnd.ahead.space ahead +application/vnd.airzip.filesecure.azf azf +application/vnd.airzip.filesecure.azs azs +application/vnd.amazon.ebook azw +application/vnd.americandynamics.acc acc +application/vnd.amiga.ami ami +# application/vnd.amundsen.maze+xml +application/vnd.android.package-archive apk +application/vnd.anser-web-certificate-issue-initiation cii +application/vnd.anser-web-funds-transfer-initiation fti +application/vnd.antix.game-component atx +application/vnd.apple.installer+xml mpkg +application/vnd.apple.mpegurl m3u8 +# application/vnd.arastra.swi +application/vnd.aristanetworks.swi swi +application/vnd.audiograph aep +# application/vnd.autopackage +# application/vnd.avistar+xml +application/vnd.blueice.multipass mpm +# application/vnd.bluetooth.ep.oob +application/vnd.bmi bmi +application/vnd.businessobjects rep +# application/vnd.cab-jscript +# application/vnd.canon-cpdl +# application/vnd.canon-lips +# application/vnd.cendio.thinlinc.clientconf +application/vnd.chemdraw+xml cdxml +application/vnd.chipnuts.karaoke-mmd mmd +application/vnd.cinderella cdy +# application/vnd.cirpack.isdn-ext +application/vnd.claymore cla +application/vnd.cloanto.rp9 rp9 +application/vnd.clonk.c4group c4g c4d c4f c4p c4u +application/vnd.cluetrust.cartomobile-config c11amc +application/vnd.cluetrust.cartomobile-config-pkg c11amz +# application/vnd.commerce-battelle +application/vnd.commonspace csp +application/vnd.contact.cmsg cdbcmsg +application/vnd.cosmocaller cmc +application/vnd.crick.clicker clkx +application/vnd.crick.clicker.keyboard clkk +application/vnd.crick.clicker.palette clkp +application/vnd.crick.clicker.template clkt +application/vnd.crick.clicker.wordbank clkw +application/vnd.criticaltools.wbs+xml wbs +application/vnd.ctc-posml pml +# application/vnd.ctct.ws+xml +# application/vnd.cups-pdf +# application/vnd.cups-postscript +application/vnd.cups-ppd ppd +# application/vnd.cups-raster +# application/vnd.cups-raw +application/vnd.curl.car car +application/vnd.curl.pcurl pcurl +# application/vnd.cybank +application/vnd.data-vision.rdz rdz +application/vnd.dece.data uvf uvvf uvd uvvd +application/vnd.dece.ttml+xml uvt uvvt +application/vnd.dece.unspecified uvx uvvx +application/vnd.denovo.fcselayout-link fe_launch +# application/vnd.dir-bi.plate-dl-nosuffix +application/vnd.dna dna +application/vnd.dolby.mlp mlp +# application/vnd.dolby.mobile.1 +# application/vnd.dolby.mobile.2 +application/vnd.dpgraph dpg +application/vnd.dreamfactory dfac +application/vnd.dvb.ait ait +# application/vnd.dvb.dvbj +# application/vnd.dvb.esgcontainer +# application/vnd.dvb.ipdcdftnotifaccess +# application/vnd.dvb.ipdcesgaccess +# application/vnd.dvb.ipdcesgaccess2 +# application/vnd.dvb.ipdcesgpdd +# application/vnd.dvb.ipdcroaming +# application/vnd.dvb.iptv.alfec-base +# application/vnd.dvb.iptv.alfec-enhancement +# application/vnd.dvb.notif-aggregate-root+xml +# application/vnd.dvb.notif-container+xml +# application/vnd.dvb.notif-generic+xml +# application/vnd.dvb.notif-ia-msglist+xml +# application/vnd.dvb.notif-ia-registration-request+xml +# application/vnd.dvb.notif-ia-registration-response+xml +# application/vnd.dvb.notif-init+xml +# application/vnd.dvb.pfr +application/vnd.dvb.service svc +# application/vnd.dxr +application/vnd.dynageo geo +# application/vnd.easykaraoke.cdgdownload +# application/vnd.ecdis-update +application/vnd.ecowin.chart mag +# application/vnd.ecowin.filerequest +# application/vnd.ecowin.fileupdate +# application/vnd.ecowin.series +# application/vnd.ecowin.seriesrequest +# application/vnd.ecowin.seriesupdate +# application/vnd.emclient.accessrequest+xml +application/vnd.enliven nml +application/vnd.epson.esf esf +application/vnd.epson.msf msf +application/vnd.epson.quickanime qam +application/vnd.epson.salt slt +application/vnd.epson.ssf ssf +# application/vnd.ericsson.quickcall +application/vnd.eszigno3+xml es3 et3 +# application/vnd.etsi.aoc+xml +# application/vnd.etsi.cug+xml +# application/vnd.etsi.iptvcommand+xml +# application/vnd.etsi.iptvdiscovery+xml +# application/vnd.etsi.iptvprofile+xml +# application/vnd.etsi.iptvsad-bc+xml +# application/vnd.etsi.iptvsad-cod+xml +# application/vnd.etsi.iptvsad-npvr+xml +# application/vnd.etsi.iptvservice+xml +# application/vnd.etsi.iptvsync+xml +# application/vnd.etsi.iptvueprofile+xml +# application/vnd.etsi.mcid+xml +# application/vnd.etsi.overload-control-policy-dataset+xml +# application/vnd.etsi.sci+xml +# application/vnd.etsi.simservs+xml +# application/vnd.etsi.tsl+xml +# application/vnd.etsi.tsl.der +# application/vnd.eudora.data +application/vnd.ezpix-album ez2 +application/vnd.ezpix-package ez3 +# application/vnd.f-secure.mobile +application/vnd.fdf fdf +application/vnd.fdsn.mseed mseed +application/vnd.fdsn.seed seed dataless +# application/vnd.ffsns +# application/vnd.fints +application/vnd.flographit gph +application/vnd.fluxtime.clip ftc +# application/vnd.font-fontforge-sfd +application/vnd.framemaker fm frame maker book +application/vnd.frogans.fnc fnc +application/vnd.frogans.ltf ltf +application/vnd.fsc.weblaunch fsc +application/vnd.fujitsu.oasys oas +application/vnd.fujitsu.oasys2 oa2 +application/vnd.fujitsu.oasys3 oa3 +application/vnd.fujitsu.oasysgp fg5 +application/vnd.fujitsu.oasysprs bh2 +# application/vnd.fujixerox.art-ex +# application/vnd.fujixerox.art4 +# application/vnd.fujixerox.hbpl +application/vnd.fujixerox.ddd ddd +application/vnd.fujixerox.docuworks xdw +application/vnd.fujixerox.docuworks.binder xbd +# application/vnd.fut-misnet +application/vnd.fuzzysheet fzs +application/vnd.genomatix.tuxedo txd +# application/vnd.geocube+xml +application/vnd.geogebra.file ggb +application/vnd.geogebra.tool ggt +application/vnd.geometry-explorer gex gre +application/vnd.geonext gxt +application/vnd.geoplan g2w +application/vnd.geospace g3w +# application/vnd.globalplatform.card-content-mgt +# application/vnd.globalplatform.card-content-mgt-response +application/vnd.gmx gmx +application/vnd.google-earth.kml+xml kml +application/vnd.google-earth.kmz kmz +application/vnd.grafeq gqf gqs +# application/vnd.gridmp +application/vnd.groove-account gac +application/vnd.groove-help ghf +application/vnd.groove-identity-message gim +application/vnd.groove-injector grv +application/vnd.groove-tool-message gtm +application/vnd.groove-tool-template tpl +application/vnd.groove-vcard vcg +application/vnd.hal+xml hal +application/vnd.handheld-entertainment+xml zmm +application/vnd.hbci hbci +# application/vnd.hcl-bireports +application/vnd.hhe.lesson-player les +application/vnd.hp-hpgl hpgl +application/vnd.hp-hpid hpid +application/vnd.hp-hps hps +application/vnd.hp-jlyt jlt +application/vnd.hp-pcl pcl +application/vnd.hp-pclxl pclxl +# application/vnd.httphone +application/vnd.hydrostatix.sof-data sfd-hdstx +application/vnd.hzn-3d-crossword x3d +# application/vnd.ibm.afplinedata +# application/vnd.ibm.electronic-media +application/vnd.ibm.minipay mpy +application/vnd.ibm.modcap afp listafp list3820 +application/vnd.ibm.rights-management irm +application/vnd.ibm.secure-container sc +application/vnd.iccprofile icc icm +application/vnd.igloader igl +application/vnd.immervision-ivp ivp +application/vnd.immervision-ivu ivu +# application/vnd.informedcontrol.rms+xml +# application/vnd.informix-visionary +# application/vnd.infotech.project +# application/vnd.infotech.project+xml +application/vnd.insors.igm igm +application/vnd.intercon.formnet xpw xpx +application/vnd.intergeo i2g +# application/vnd.intertrust.digibox +# application/vnd.intertrust.nncp +application/vnd.intu.qbo qbo +application/vnd.intu.qfx qfx +# application/vnd.iptc.g2.conceptitem+xml +# application/vnd.iptc.g2.knowledgeitem+xml +# application/vnd.iptc.g2.newsitem+xml +# application/vnd.iptc.g2.packageitem+xml +application/vnd.ipunplugged.rcprofile rcprofile +application/vnd.irepository.package+xml irp +application/vnd.is-xpr xpr +application/vnd.isac.fcs fcs +application/vnd.jam jam +# application/vnd.japannet-directory-service +# application/vnd.japannet-jpnstore-wakeup +# application/vnd.japannet-payment-wakeup +# application/vnd.japannet-registration +# application/vnd.japannet-registration-wakeup +# application/vnd.japannet-setstore-wakeup +# application/vnd.japannet-verification +# application/vnd.japannet-verification-wakeup +application/vnd.jcp.javame.midlet-rms rms +application/vnd.jisp jisp +application/vnd.joost.joda-archive joda +application/vnd.kahootz ktz ktr +application/vnd.kde.karbon karbon +application/vnd.kde.kchart chrt +application/vnd.kde.kformula kfo +application/vnd.kde.kivio flw +application/vnd.kde.kontour kon +application/vnd.kde.kpresenter kpr kpt +application/vnd.kde.kspread ksp +application/vnd.kde.kword kwd kwt +application/vnd.kenameaapp htke +application/vnd.kidspiration kia +application/vnd.kinar kne knp +application/vnd.koan skp skd skt skm +application/vnd.kodak-descriptor sse +application/vnd.las.las+xml lasxml +# application/vnd.liberty-request+xml +application/vnd.llamagraphics.life-balance.desktop lbd +application/vnd.llamagraphics.life-balance.exchange+xml lbe +application/vnd.lotus-1-2-3 123 +application/vnd.lotus-approach apr +application/vnd.lotus-freelance pre +application/vnd.lotus-notes nsf +application/vnd.lotus-organizer org +application/vnd.lotus-screencam scm +application/vnd.lotus-wordpro lwp +application/vnd.macports.portpkg portpkg +# application/vnd.marlin.drm.actiontoken+xml +# application/vnd.marlin.drm.conftoken+xml +# application/vnd.marlin.drm.license+xml +# application/vnd.marlin.drm.mdcf +application/vnd.mcd mcd +application/vnd.medcalcdata mc1 +application/vnd.mediastation.cdkey cdkey +# application/vnd.meridian-slingshot +application/vnd.mfer mwf +application/vnd.mfmp mfm +application/vnd.micrografx.flo flo +application/vnd.micrografx.igx igx +application/vnd.mif mif +# application/vnd.minisoft-hp3000-save +# application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.mobius.daf daf +application/vnd.mobius.dis dis +application/vnd.mobius.mbk mbk +application/vnd.mobius.mqy mqy +application/vnd.mobius.msl msl +application/vnd.mobius.plc plc +application/vnd.mobius.txf txf +application/vnd.mophun.application mpn +application/vnd.mophun.certificate mpc +# application/vnd.motorola.flexsuite +# application/vnd.motorola.flexsuite.adsi +# application/vnd.motorola.flexsuite.fis +# application/vnd.motorola.flexsuite.gotap +# application/vnd.motorola.flexsuite.kmr +# application/vnd.motorola.flexsuite.ttc +# application/vnd.motorola.flexsuite.wem +# application/vnd.motorola.iprm +application/vnd.mozilla.xul+xml xul +application/vnd.ms-artgalry cil +# application/vnd.ms-asf +application/vnd.ms-cab-compressed cab +application/vnd.ms-excel xls xlm xla xlc xlt xlw +application/vnd.ms-excel.addin.macroenabled.12 xlam +application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb +application/vnd.ms-excel.sheet.macroenabled.12 xlsm +application/vnd.ms-excel.template.macroenabled.12 xltm +application/vnd.ms-fontobject eot +application/vnd.ms-htmlhelp chm +application/vnd.ms-ims ims +application/vnd.ms-lrm lrm +# application/vnd.ms-office.activex+xml +application/vnd.ms-officetheme thmx +application/vnd.ms-pki.seccat cat +application/vnd.ms-pki.stl stl +# application/vnd.ms-playready.initiator+xml +application/vnd.ms-powerpoint ppt pps pot +application/vnd.ms-powerpoint.addin.macroenabled.12 ppam +application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm +application/vnd.ms-powerpoint.slide.macroenabled.12 sldm +application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm +application/vnd.ms-powerpoint.template.macroenabled.12 potm +application/vnd.ms-project mpp mpt +# application/vnd.ms-tnef +# application/vnd.ms-wmdrm.lic-chlg-req +# application/vnd.ms-wmdrm.lic-resp +# application/vnd.ms-wmdrm.meter-chlg-req +# application/vnd.ms-wmdrm.meter-resp +application/vnd.ms-word.document.macroenabled.12 docm +application/vnd.ms-word.template.macroenabled.12 dotm +application/vnd.ms-works wps wks wcm wdb +application/vnd.ms-wpl wpl +application/vnd.ms-xpsdocument xps +application/vnd.mseq mseq +# application/vnd.msign +# application/vnd.multiad.creator +# application/vnd.multiad.creator.cif +# application/vnd.music-niff +application/vnd.musician mus +application/vnd.muvee.style msty +# application/vnd.ncd.control +# application/vnd.ncd.reference +# application/vnd.nervana +# application/vnd.netfpx +application/vnd.neurolanguage.nlu nlu +application/vnd.noblenet-directory nnd +application/vnd.noblenet-sealer nns +application/vnd.noblenet-web nnw +# application/vnd.nokia.catalogs +# application/vnd.nokia.conml+wbxml +# application/vnd.nokia.conml+xml +# application/vnd.nokia.isds-radio-presets +# application/vnd.nokia.iptv.config+xml +# application/vnd.nokia.landmark+wbxml +# application/vnd.nokia.landmark+xml +# application/vnd.nokia.landmarkcollection+xml +# application/vnd.nokia.n-gage.ac+xml +application/vnd.nokia.n-gage.data ngdat +application/vnd.nokia.n-gage.symbian.install n-gage +# application/vnd.nokia.ncd +# application/vnd.nokia.pcd+wbxml +# application/vnd.nokia.pcd+xml +application/vnd.nokia.radio-preset rpst +application/vnd.nokia.radio-presets rpss +application/vnd.novadigm.edm edm +application/vnd.novadigm.edx edx +application/vnd.novadigm.ext ext +# application/vnd.ntt-local.file-transfer +# application/vnd.ntt-local.sip-ta_remote +# application/vnd.ntt-local.sip-ta_tcp_stream +application/vnd.oasis.opendocument.chart odc +application/vnd.oasis.opendocument.chart-template otc +application/vnd.oasis.opendocument.database odb +application/vnd.oasis.opendocument.formula odf +application/vnd.oasis.opendocument.formula-template odft +application/vnd.oasis.opendocument.graphics odg +application/vnd.oasis.opendocument.graphics-template otg +application/vnd.oasis.opendocument.image odi +application/vnd.oasis.opendocument.image-template oti +application/vnd.oasis.opendocument.presentation odp +application/vnd.oasis.opendocument.presentation-template otp +application/vnd.oasis.opendocument.spreadsheet ods +application/vnd.oasis.opendocument.spreadsheet-template ots +application/vnd.oasis.opendocument.text odt +application/vnd.oasis.opendocument.text-master odm +application/vnd.oasis.opendocument.text-template ott +application/vnd.oasis.opendocument.text-web oth +# application/vnd.obn +# application/vnd.oipf.contentaccessdownload+xml +# application/vnd.oipf.contentaccessstreaming+xml +# application/vnd.oipf.cspg-hexbinary +# application/vnd.oipf.dae.svg+xml +# application/vnd.oipf.dae.xhtml+xml +# application/vnd.oipf.mippvcontrolmessage+xml +# application/vnd.oipf.pae.gem +# application/vnd.oipf.spdiscovery+xml +# application/vnd.oipf.spdlist+xml +# application/vnd.oipf.ueprofile+xml +# application/vnd.oipf.userprofile+xml +application/vnd.olpc-sugar xo +# application/vnd.oma-scws-config +# application/vnd.oma-scws-http-request +# application/vnd.oma-scws-http-response +# application/vnd.oma.bcast.associated-procedure-parameter+xml +# application/vnd.oma.bcast.drm-trigger+xml +# application/vnd.oma.bcast.imd+xml +# application/vnd.oma.bcast.ltkm +# application/vnd.oma.bcast.notification+xml +# application/vnd.oma.bcast.provisioningtrigger +# application/vnd.oma.bcast.sgboot +# application/vnd.oma.bcast.sgdd+xml +# application/vnd.oma.bcast.sgdu +# application/vnd.oma.bcast.simple-symbol-container +# application/vnd.oma.bcast.smartcard-trigger+xml +# application/vnd.oma.bcast.sprov+xml +# application/vnd.oma.bcast.stkm +# application/vnd.oma.cab-address-book+xml +# application/vnd.oma.cab-pcc+xml +# application/vnd.oma.dcd +# application/vnd.oma.dcdc +application/vnd.oma.dd2+xml dd2 +# application/vnd.oma.drm.risd+xml +# application/vnd.oma.group-usage-list+xml +# application/vnd.oma.poc.detailed-progress-report+xml +# application/vnd.oma.poc.final-report+xml +# application/vnd.oma.poc.groups+xml +# application/vnd.oma.poc.invocation-descriptor+xml +# application/vnd.oma.poc.optimized-progress-report+xml +# application/vnd.oma.push +# application/vnd.oma.scidm.messages+xml +# application/vnd.oma.xcap-directory+xml +# application/vnd.omads-email+xml +# application/vnd.omads-file+xml +# application/vnd.omads-folder+xml +# application/vnd.omaloc-supl-init +application/vnd.openofficeorg.extension oxt +# application/vnd.openxmlformats-officedocument.custom-properties+xml +# application/vnd.openxmlformats-officedocument.customxmlproperties+xml +# application/vnd.openxmlformats-officedocument.drawing+xml +# application/vnd.openxmlformats-officedocument.drawingml.chart+xml +# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml +# application/vnd.openxmlformats-officedocument.extended-properties+xml +# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml +# application/vnd.openxmlformats-officedocument.presentationml.comments+xml +# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml +application/vnd.openxmlformats-officedocument.presentationml.presentation pptx +# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml +application/vnd.openxmlformats-officedocument.presentationml.slide sldx +# application/vnd.openxmlformats-officedocument.presentationml.slide+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml +application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx +# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml +# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml +# application/vnd.openxmlformats-officedocument.presentationml.tags+xml +application/vnd.openxmlformats-officedocument.presentationml.template potx +# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx +# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml +# application/vnd.openxmlformats-officedocument.theme+xml +# application/vnd.openxmlformats-officedocument.themeoverride+xml +# application/vnd.openxmlformats-officedocument.vmldrawing +# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.document docx +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx +# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml +# application/vnd.openxmlformats-package.core-properties+xml +# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml +# application/vnd.openxmlformats-package.relationships+xml +# application/vnd.quobject-quoxdocument +# application/vnd.osa.netdeploy +application/vnd.osgeo.mapguide.package mgp +# application/vnd.osgi.bundle +application/vnd.osgi.dp dp +# application/vnd.otps.ct-kip+xml +application/vnd.palm pdb pqa oprc +# application/vnd.paos.xml +application/vnd.pawaafile paw +application/vnd.pg.format str +application/vnd.pg.osasli ei6 +# application/vnd.piaccess.application-licence +application/vnd.picsel efif +application/vnd.pmi.widget wg +# application/vnd.poc.group-advertisement+xml +application/vnd.pocketlearn plf +application/vnd.powerbuilder6 pbd +# application/vnd.powerbuilder6-s +# application/vnd.powerbuilder7 +# application/vnd.powerbuilder7-s +# application/vnd.powerbuilder75 +# application/vnd.powerbuilder75-s +# application/vnd.preminet +application/vnd.previewsystems.box box +application/vnd.proteus.magazine mgz +application/vnd.publishare-delta-tree qps +application/vnd.pvi.ptid1 ptid +# application/vnd.pwg-multiplexed +# application/vnd.pwg-xhtml-print+xml +# application/vnd.qualcomm.brew-app-res +application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb +# application/vnd.radisys.moml+xml +# application/vnd.radisys.msml+xml +# application/vnd.radisys.msml-audit+xml +# application/vnd.radisys.msml-audit-conf+xml +# application/vnd.radisys.msml-audit-conn+xml +# application/vnd.radisys.msml-audit-dialog+xml +# application/vnd.radisys.msml-audit-stream+xml +# application/vnd.radisys.msml-conf+xml +# application/vnd.radisys.msml-dialog+xml +# application/vnd.radisys.msml-dialog-base+xml +# application/vnd.radisys.msml-dialog-fax-detect+xml +# application/vnd.radisys.msml-dialog-fax-sendrecv+xml +# application/vnd.radisys.msml-dialog-group+xml +# application/vnd.radisys.msml-dialog-speech+xml +# application/vnd.radisys.msml-dialog-transform+xml +# application/vnd.rainstor.data +# application/vnd.rapid +application/vnd.realvnc.bed bed +application/vnd.recordare.musicxml mxl +application/vnd.recordare.musicxml+xml musicxml +# application/vnd.renlearn.rlprint +application/vnd.rig.cryptonote cryptonote +application/vnd.rim.cod cod +application/vnd.rn-realmedia rm +application/vnd.route66.link66+xml link66 +# application/vnd.ruckus.download +# application/vnd.s3sms +application/vnd.sailingtracker.track st +# application/vnd.sbm.cid +# application/vnd.sbm.mid2 +# application/vnd.scribus +# application/vnd.sealed.3df +# application/vnd.sealed.csf +# application/vnd.sealed.doc +# application/vnd.sealed.eml +# application/vnd.sealed.mht +# application/vnd.sealed.net +# application/vnd.sealed.ppt +# application/vnd.sealed.tiff +# application/vnd.sealed.xls +# application/vnd.sealedmedia.softseal.html +# application/vnd.sealedmedia.softseal.pdf +application/vnd.seemail see +application/vnd.sema sema +application/vnd.semd semd +application/vnd.semf semf +application/vnd.shana.informed.formdata ifm +application/vnd.shana.informed.formtemplate itp +application/vnd.shana.informed.interchange iif +application/vnd.shana.informed.package ipk +application/vnd.simtech-mindmapper twd twds +application/vnd.smaf mmf +# application/vnd.smart.notebook +application/vnd.smart.teacher teacher +# application/vnd.software602.filler.form+xml +# application/vnd.software602.filler.form-xml-zip +application/vnd.solent.sdkm+xml sdkm sdkd +application/vnd.spotfire.dxp dxp +application/vnd.spotfire.sfs sfs +# application/vnd.sss-cod +# application/vnd.sss-dtf +# application/vnd.sss-ntf +application/vnd.stardivision.calc sdc +application/vnd.stardivision.draw sda +application/vnd.stardivision.impress sdd +application/vnd.stardivision.math smf +application/vnd.stardivision.writer sdw vor +application/vnd.stardivision.writer-global sgl +application/vnd.stepmania.stepchart sm +# application/vnd.street-stream +application/vnd.sun.xml.calc sxc +application/vnd.sun.xml.calc.template stc +application/vnd.sun.xml.draw sxd +application/vnd.sun.xml.draw.template std +application/vnd.sun.xml.impress sxi +application/vnd.sun.xml.impress.template sti +application/vnd.sun.xml.math sxm +application/vnd.sun.xml.writer sxw +application/vnd.sun.xml.writer.global sxg +application/vnd.sun.xml.writer.template stw +# application/vnd.sun.wadl+xml +application/vnd.sus-calendar sus susp +application/vnd.svd svd +# application/vnd.swiftview-ics +application/vnd.symbian.install sis sisx +application/vnd.syncml+xml xsm +application/vnd.syncml.dm+wbxml bdm +application/vnd.syncml.dm+xml xdm +# application/vnd.syncml.dm.notification +# application/vnd.syncml.ds.notification +application/vnd.tao.intent-module-archive tao +application/vnd.tmobile-livetv tmo +application/vnd.trid.tpt tpt +application/vnd.triscape.mxs mxs +application/vnd.trueapp tra +# application/vnd.truedoc +# application/vnd.ubisoft.webplayer +application/vnd.ufdl ufd ufdl +application/vnd.uiq.theme utz +application/vnd.umajin umj +application/vnd.unity unityweb +application/vnd.uoml+xml uoml +# application/vnd.uplanet.alert +# application/vnd.uplanet.alert-wbxml +# application/vnd.uplanet.bearer-choice +# application/vnd.uplanet.bearer-choice-wbxml +# application/vnd.uplanet.cacheop +# application/vnd.uplanet.cacheop-wbxml +# application/vnd.uplanet.channel +# application/vnd.uplanet.channel-wbxml +# application/vnd.uplanet.list +# application/vnd.uplanet.list-wbxml +# application/vnd.uplanet.listcmd +# application/vnd.uplanet.listcmd-wbxml +# application/vnd.uplanet.signal +application/vnd.vcx vcx +# application/vnd.vd-study +# application/vnd.vectorworks +# application/vnd.verimatrix.vcas +# application/vnd.vidsoft.vidconference +application/vnd.visio vsd vst vss vsw +application/vnd.visionary vis +# application/vnd.vividence.scriptfile +application/vnd.vsf vsf +# application/vnd.wap.sic +# application/vnd.wap.slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.webturbo wtb +# application/vnd.wfa.wsc +# application/vnd.wmc +# application/vnd.wmf.bootstrap +# application/vnd.wolfram.mathematica +# application/vnd.wolfram.mathematica.package +application/vnd.wolfram.player nbp +application/vnd.wordperfect wpd +application/vnd.wqd wqd +# application/vnd.wrq-hp3000-labelled +application/vnd.wt.stf stf +# application/vnd.wv.csp+wbxml +# application/vnd.wv.csp+xml +# application/vnd.wv.ssp+xml +application/vnd.xara xar +application/vnd.xfdl xfdl +# application/vnd.xfdl.webform +# application/vnd.xmi+xml +# application/vnd.xmpie.cpkg +# application/vnd.xmpie.dpkg +# application/vnd.xmpie.plan +# application/vnd.xmpie.ppkg +# application/vnd.xmpie.xlim +application/vnd.yamaha.hv-dic hvd +application/vnd.yamaha.hv-script hvs +application/vnd.yamaha.hv-voice hvp +application/vnd.yamaha.openscoreformat osf +application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg +# application/vnd.yamaha.remote-setup +application/vnd.yamaha.smaf-audio saf +application/vnd.yamaha.smaf-phrase spf +# application/vnd.yamaha.tunnel-udpencap +application/vnd.yellowriver-custom-menu cmp +application/vnd.zul zir zirz +application/vnd.zzazz.deck+xml zaz +application/voicexml+xml vxml +# application/vq-rtcpxr +# application/watcherinfo+xml +# application/whoispp-query +# application/whoispp-response +application/widget wgt +application/winhlp hlp +# application/wita +# application/wordperfect5.1 +application/wsdl+xml wsdl +application/wspolicy+xml wspolicy +application/x-7z-compressed 7z +application/x-abiword abw +application/x-ace-compressed ace +application/x-authorware-bin aab x32 u32 vox +application/x-authorware-map aam +application/x-authorware-seg aas +application/x-bcpio bcpio +application/x-bittorrent torrent +application/x-bzip bz +application/x-bzip2 bz2 boz +application/x-cdlink vcd +application/x-chat chat +application/x-chess-pgn pgn +# application/x-compress +application/x-cpio cpio +application/x-csh csh +application/x-debian-package deb udeb +application/x-director dir dcr dxr cst cct cxt w3d fgd swa +application/x-doom wad +application/x-dtbncx+xml ncx +application/x-dtbook+xml dtb +application/x-dtbresource+xml res +application/x-dvi dvi +application/x-font-bdf bdf +# application/x-font-dos +# application/x-font-framemaker +application/x-font-ghostscript gsf +# application/x-font-libgrx +application/x-font-linux-psf psf +application/x-font-otf otf +application/x-font-pcf pcf +application/x-font-snf snf +# application/x-font-speedo +# application/x-font-sunos-news +application/x-font-ttf ttf ttc +application/x-font-type1 pfa pfb pfm afm +application/x-font-woff woff +# application/x-font-vfont +application/x-futuresplash spl +application/x-gnumeric gnumeric +application/x-gtar gtar +# application/x-gzip +application/x-hdf hdf +application/x-java-jnlp-file jnlp +application/x-latex latex +application/x-mobipocket-ebook prc mobi +application/x-ms-application application +application/x-ms-wmd wmd +application/x-ms-wmz wmz +application/x-ms-xbap xbap +application/x-msaccess mdb +application/x-msbinder obd +application/x-mscardfile crd +application/x-msclip clp +application/x-msdownload exe dll com bat msi +application/x-msmediaview mvb m13 m14 +application/x-msmetafile wmf +application/x-msmoney mny +application/x-mspublisher pub +application/x-msschedule scd +application/x-msterminal trm +application/x-mswrite wri +application/x-netcdf nc cdf +application/x-pkcs12 p12 pfx +application/x-pkcs7-certificates p7b spc +application/x-pkcs7-certreqresp p7r +application/x-rar-compressed rar +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-silverlight-app xap +application/x-stuffit sit +application/x-stuffitx sitx +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-tex-tfm tfm +application/x-texinfo texinfo texi +application/x-ustar ustar +application/x-wais-source src +application/x-x509-ca-cert der crt +application/x-xfig fig +application/x-xpinstall xpi +# application/x400-bp +# application/xcap-att+xml +# application/xcap-caps+xml +application/xcap-diff+xml xdf +# application/xcap-el+xml +# application/xcap-error+xml +# application/xcap-ns+xml +# application/xcon-conference-info-diff+xml +# application/xcon-conference-info+xml +application/xenc+xml xenc +application/xhtml+xml xhtml xht +# application/xhtml-voice+xml +application/xml xml xsl +application/xml-dtd dtd +# application/xml-external-parsed-entity +# application/xmpp+xml +application/xop+xml xop +application/xslt+xml xslt +application/xspf+xml xspf +application/xv+xml mxml xhvml xvml xvm +application/yang yang +application/yin+xml yin +application/zip zip +# audio/1d-interleaved-parityfec +# audio/32kadpcm +# audio/3gpp +# audio/3gpp2 +# audio/ac3 +audio/adpcm adp +# audio/amr +# audio/amr-wb +# audio/amr-wb+ +# audio/asc +# audio/atrac-advanced-lossless +# audio/atrac-x +# audio/atrac3 +audio/basic au snd +# audio/bv16 +# audio/bv32 +# audio/clearmode +# audio/cn +# audio/dat12 +# audio/dls +# audio/dsr-es201108 +# audio/dsr-es202050 +# audio/dsr-es202211 +# audio/dsr-es202212 +# audio/dvi4 +# audio/eac3 +# audio/evrc +# audio/evrc-qcp +# audio/evrc0 +# audio/evrc1 +# audio/evrcb +# audio/evrcb0 +# audio/evrcb1 +# audio/evrcwb +# audio/evrcwb0 +# audio/evrcwb1 +# audio/example +# audio/g719 +# audio/g722 +# audio/g7221 +# audio/g723 +# audio/g726-16 +# audio/g726-24 +# audio/g726-32 +# audio/g726-40 +# audio/g728 +# audio/g729 +# audio/g7291 +# audio/g729d +# audio/g729e +# audio/gsm +# audio/gsm-efr +# audio/gsm-hr-08 +# audio/ilbc +# audio/l16 +# audio/l20 +# audio/l24 +# audio/l8 +# audio/lpc +audio/midi mid midi kar rmi +# audio/mobile-xmf +audio/mp4 mp4a +# audio/mp4a-latm +# audio/mpa +# audio/mpa-robust +audio/mpeg mpga mp2 mp2a mp3 m2a m3a +# audio/mpeg4-generic +audio/ogg oga ogg spx +# audio/parityfec +# audio/pcma +# audio/pcma-wb +# audio/pcmu-wb +# audio/pcmu +# audio/prs.sid +# audio/qcelp +# audio/red +# audio/rtp-enc-aescm128 +# audio/rtp-midi +# audio/rtx +# audio/smv +# audio/smv0 +# audio/smv-qcp +# audio/sp-midi +# audio/speex +# audio/t140c +# audio/t38 +# audio/telephone-event +# audio/tone +# audio/uemclip +# audio/ulpfec +# audio/vdvi +# audio/vmr-wb +# audio/vnd.3gpp.iufp +# audio/vnd.4sb +# audio/vnd.audiokoz +# audio/vnd.celp +# audio/vnd.cisco.nse +# audio/vnd.cmles.radio-events +# audio/vnd.cns.anp1 +# audio/vnd.cns.inf1 +audio/vnd.dece.audio uva uvva +audio/vnd.digital-winds eol +# audio/vnd.dlna.adts +# audio/vnd.dolby.heaac.1 +# audio/vnd.dolby.heaac.2 +# audio/vnd.dolby.mlp +# audio/vnd.dolby.mps +# audio/vnd.dolby.pl2 +# audio/vnd.dolby.pl2x +# audio/vnd.dolby.pl2z +# audio/vnd.dolby.pulse.1 +audio/vnd.dra dra +audio/vnd.dts dts +audio/vnd.dts.hd dtshd +# audio/vnd.everad.plj +# audio/vnd.hns.audio +audio/vnd.lucent.voice lvp +audio/vnd.ms-playready.media.pya pya +# audio/vnd.nokia.mobile-xmf +# audio/vnd.nortel.vbk +audio/vnd.nuera.ecelp4800 ecelp4800 +audio/vnd.nuera.ecelp7470 ecelp7470 +audio/vnd.nuera.ecelp9600 ecelp9600 +# audio/vnd.octel.sbc +# audio/vnd.qcelp +# audio/vnd.rhetorex.32kadpcm +audio/vnd.rip rip +# audio/vnd.sealedmedia.softseal.mpeg +# audio/vnd.vmx.cvsd +# audio/vorbis +# audio/vorbis-config +audio/webm weba +audio/x-aac aac +audio/x-aiff aif aiff aifc +audio/x-mpegurl m3u +audio/x-ms-wax wax +audio/x-ms-wma wma +audio/x-pn-realaudio ram ra +audio/x-pn-realaudio-plugin rmp +audio/x-wav wav +chemical/x-cdx cdx +chemical/x-cif cif +chemical/x-cmdf cmdf +chemical/x-cml cml +chemical/x-csml csml +# chemical/x-pdb +chemical/x-xyz xyz +image/bmp bmp +image/cgm cgm +# image/example +# image/fits +image/g3fax g3 +image/gif gif +image/ief ief +# image/jp2 +image/jpeg jpeg jpg jpe +# image/jpm +# image/jpx +image/ktx ktx +# image/naplps +image/png png +image/prs.btif btif +# image/prs.pti +image/svg+xml svg svgz +# image/t38 +image/tiff tiff tif +# image/tiff-fx +image/vnd.adobe.photoshop psd +# image/vnd.cns.inf2 +image/vnd.dece.graphic uvi uvvi uvg uvvg +image/vnd.dvb.subtitle sub +image/vnd.djvu djvu djv +image/vnd.dwg dwg +image/vnd.dxf dxf +image/vnd.fastbidsheet fbs +image/vnd.fpx fpx +image/vnd.fst fst +image/vnd.fujixerox.edmics-mmr mmr +image/vnd.fujixerox.edmics-rlc rlc +# image/vnd.globalgraphics.pgb +# image/vnd.microsoft.icon +# image/vnd.mix +image/vnd.ms-modi mdi +image/vnd.net-fpx npx +# image/vnd.radiance +# image/vnd.sealed.png +# image/vnd.sealedmedia.softseal.gif +# image/vnd.sealedmedia.softseal.jpg +# image/vnd.svf +image/vnd.wap.wbmp wbmp +image/vnd.xiff xif +image/webp webp +image/x-cmu-raster ras +image/x-cmx cmx +image/x-freehand fh fhc fh4 fh5 fh7 +image/x-icon ico +image/x-pcx pcx +image/x-pict pic pct +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-rgb rgb +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +# message/cpim +# message/delivery-status +# message/disposition-notification +# message/example +# message/external-body +# message/feedback-report +# message/global +# message/global-delivery-status +# message/global-disposition-notification +# message/global-headers +# message/http +# message/imdn+xml +# message/news +# message/partial +message/rfc822 eml mime +# message/s-http +# message/sip +# message/sipfrag +# message/tracking-status +# message/vnd.si.simp +# model/example +model/iges igs iges +model/mesh msh mesh silo +model/vnd.collada+xml dae +model/vnd.dwf dwf +# model/vnd.flatland.3dml +model/vnd.gdl gdl +# model/vnd.gs-gdl +# model/vnd.gs.gdl +model/vnd.gtw gtw +# model/vnd.moml+xml +model/vnd.mts mts +# model/vnd.parasolid.transmit.binary +# model/vnd.parasolid.transmit.text +model/vnd.vtu vtu +model/vrml wrl vrml +# multipart/alternative +# multipart/appledouble +# multipart/byteranges +# multipart/digest +# multipart/encrypted +# multipart/example +# multipart/form-data +# multipart/header-set +# multipart/mixed +# multipart/parallel +# multipart/related +# multipart/report +# multipart/signed +# multipart/voice-message +# text/1d-interleaved-parityfec +text/calendar ics ifb +text/css css +text/csv csv +# text/directory +# text/dns +# text/ecmascript +# text/enriched +# text/example +text/html html htm +# text/javascript +text/n3 n3 +# text/parityfec +text/plain txt text conf def list log in +# text/prs.fallenstein.rst +text/prs.lines.tag dsc +# text/vnd.radisys.msml-basic-layout +# text/red +# text/rfc822-headers +text/richtext rtx +# text/rtf +# text/rtp-enc-aescm128 +# text/rtx +text/sgml sgml sgm +# text/t140 +text/tab-separated-values tsv +text/troff t tr roff man me ms +text/turtle ttl +# text/ulpfec +text/uri-list uri uris urls +# text/vnd.abc +text/vnd.curl curl +text/vnd.curl.dcurl dcurl +text/vnd.curl.scurl scurl +text/vnd.curl.mcurl mcurl +# text/vnd.dmclientscript +# text/vnd.esmertec.theme-descriptor +text/vnd.fly fly +text/vnd.fmi.flexstor flx +text/vnd.graphviz gv +text/vnd.in3d.3dml 3dml +text/vnd.in3d.spot spot +# text/vnd.iptc.newsml +# text/vnd.iptc.nitf +# text/vnd.latex-z +# text/vnd.motorola.reflex +# text/vnd.ms-mediapackage +# text/vnd.net2phone.commcenter.command +# text/vnd.si.uricatalogue +text/vnd.sun.j2me.app-descriptor jad +# text/vnd.trolltech.linguist +# text/vnd.wap.si +# text/vnd.wap.sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-asm s asm +text/x-c c cc cxx cpp h hh dic +text/x-fortran f for f77 f90 +text/x-pascal p pas +text/x-java-source java +text/x-setext etx +text/x-uuencode uu +text/x-vcalendar vcs +text/x-vcard vcf +# text/xml +# text/xml-external-parsed-entity +# video/1d-interleaved-parityfec +video/3gpp 3gp +# video/3gpp-tt +video/3gpp2 3g2 +# video/bmpeg +# video/bt656 +# video/celb +# video/dv +# video/example +video/h261 h261 +video/h263 h263 +# video/h263-1998 +# video/h263-2000 +video/h264 h264 +# video/h264-rcdo +# video/h264-svc +video/jpeg jpgv +# video/jpeg2000 +video/jpm jpm jpgm +video/mj2 mj2 mjp2 +# video/mp1s +# video/mp2p +# video/mp2t +video/mp4 mp4 mp4v mpg4 +# video/mp4v-es +video/mpeg mpeg mpg mpe m1v m2v +# video/mpeg4-generic +# video/mpv +# video/nv +video/ogg ogv +# video/parityfec +# video/pointer +video/quicktime qt mov +# video/raw +# video/rtp-enc-aescm128 +# video/rtx +# video/smpte292m +# video/ulpfec +# video/vc1 +# video/vnd.cctv +video/vnd.dece.hd uvh uvvh +video/vnd.dece.mobile uvm uvvm +# video/vnd.dece.mp4 +video/vnd.dece.pd uvp uvvp +video/vnd.dece.sd uvs uvvs +video/vnd.dece.video uvv uvvv +# video/vnd.directv.mpeg +# video/vnd.directv.mpeg-tts +# video/vnd.dlna.mpeg-tts +video/vnd.fvt fvt +# video/vnd.hns.video +# video/vnd.iptvforum.1dparityfec-1010 +# video/vnd.iptvforum.1dparityfec-2005 +# video/vnd.iptvforum.2dparityfec-1010 +# video/vnd.iptvforum.2dparityfec-2005 +# video/vnd.iptvforum.ttsavc +# video/vnd.iptvforum.ttsmpeg2 +# video/vnd.motorola.video +# video/vnd.motorola.videop +video/vnd.mpegurl mxu m4u +video/vnd.ms-playready.media.pyv pyv +# video/vnd.nokia.interleaved-multimedia +# video/vnd.nokia.videovoip +# video/vnd.objectvideo +# video/vnd.sealed.mpeg1 +# video/vnd.sealed.mpeg4 +# video/vnd.sealed.swf +# video/vnd.sealedmedia.softseal.mov +video/vnd.uvvu.mp4 uvu uvvu +video/vnd.vivo viv +video/webm webm +video/x-f4v f4v +video/x-fli fli +video/x-flv flv +video/x-m4v m4v +video/x-ms-asf asf asx +video/x-ms-wm wm +video/x-ms-wmv wmv +video/x-ms-wmx wmx +video/x-ms-wvx wvx +video/x-msvideo avi +video/x-sgi-movie movie +x-conference/x-cooltalk ice diff --git a/examples/hello_routed_world/src/hello_routed_world.e b/examples/hello_routed_world/src/hello_routed_world.e index 4ece75c9..893022de 100644 --- a/examples/hello_routed_world/src/hello_routed_world.e +++ b/examples/hello_routed_world/src/hello_routed_world.e @@ -14,7 +14,7 @@ inherit ROUTED_APPLICATION_HELPER - DEFAULT_WGI_APPLICATION + DEFAULT_APPLICATION create make @@ -37,8 +37,13 @@ feature {NONE} -- Initialization local ra: REQUEST_AGENT_HANDLER [REQUEST_URI_TEMPLATE_HANDLER_CONTEXT] hello: REQUEST_URI_TEMPLATE_ROUTING_HANDLER + www: REQUEST_FILE_SYSTEM_HANDLER [REQUEST_URI_TEMPLATE_HANDLER_CONTEXT] do router.map_agent ("/home", agent execute_home) + create www.make (document_root) + www.set_directory_index (<<"index.html">>) + + router.map ("/www{/path}{?query}", www) --| Map all "/hello*" using a ROUTING_HANDLER create hello.make (3) @@ -60,11 +65,26 @@ feature {NONE} -- Initialization router.map_agent_with_request_methods ("/method/custom", agent handle_method_post, <<"POST">>) end + + document_root: READABLE_STRING_8 + local + e: EXECUTION_ENVIRONMENT + dn: DIRECTORY_NAME + once + create e + create dn.make_from_string (e.current_working_directory) + dn.extend ("htdocs") + Result := dn.string + if Result[Result.count] = Operating_environment.directory_separator then + Result := Result.substring (1, Result.count - 1) + end + end + feature -- Execution - execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) local - h: EWF_HEADER + h: WSF_HEADER l_url: STRING e: EXECUTION_ENVIRONMENT n: INTEGER @@ -113,7 +133,7 @@ feature -- Execution write_chunk (Void, res) end - write_chunk (s: detachable READABLE_STRING_8; res: WGI_RESPONSE_BUFFER) + write_chunk (s: detachable READABLE_STRING_8; res: WSF_RESPONSE) do if s /= Void then res.write_string (s.count.to_hex_string + {HTTP_CONSTANTS}.crlf) @@ -124,7 +144,7 @@ feature -- Execution res.flush end - execute_home (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_home (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) local l_body: STRING_8 do @@ -148,10 +168,10 @@ feature -- Execution res.write_string (l_body) end - execute_hello (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_name: detachable READABLE_STRING_32; ctx: REQUEST_HANDLER_CONTEXT) + execute_hello (req: WSF_REQUEST; res: WSF_RESPONSE; a_name: detachable READABLE_STRING_32; ctx: REQUEST_HANDLER_CONTEXT) local l_response_content_type: detachable STRING - h: EWF_HEADER + h: WSF_HEADER content_type_supported: ARRAY [STRING] l_body: STRING_8 do @@ -187,33 +207,33 @@ feature -- Execution end end - handle_hello (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + handle_hello (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) do execute_hello (req, res, Void, ctx) end - handle_anonymous_hello (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + handle_anonymous_hello (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) do execute_hello (req, res, ctx.string_parameter ("name"), ctx) end - handle_method_any (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + handle_method_any (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) do execute_hello (req, res, req.request_method, ctx) end - handle_method_get (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + handle_method_get (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) do execute_hello (req, res, "GET", ctx) end - handle_method_post (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + handle_method_post (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) do execute_hello (req, res, "POST", ctx) end - handle_method_get_or_post (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + handle_method_get_or_post (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) do execute_hello (req, res, "GET or POST", ctx) end diff --git a/examples/restbucks/restbucks-safe.ecf b/examples/restbucks/restbucks-safe.ecf index 6ed4fa57..b04a639f 100644 --- a/examples/restbucks/restbucks-safe.ecf +++ b/examples/restbucks/restbucks-safe.ecf @@ -13,11 +13,11 @@ - + - - + + diff --git a/examples/restbucks/src/resource/order_handler.e b/examples/restbucks/src/resource/order_handler.e index 1de6731f..baf3547e 100644 --- a/examples/restbucks/src/resource/order_handler.e +++ b/examples/restbucks/src/resource/order_handler.e @@ -22,7 +22,7 @@ inherit feature -- execute - execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler do execute_methods (ctx, req, res) @@ -34,7 +34,7 @@ feature -- API DOC feature -- HTTP Methods - do_get (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_get (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) -- Using GET to retrieve resource information. -- If the GET request is SUCCESS, we response with -- 200 OK, and a representation of the order @@ -59,7 +59,7 @@ feature -- HTTP Methods end end - is_conditional_get (req : WGI_REQUEST; l_order : ORDER) : BOOLEAN + is_conditional_get (req : WSF_REQUEST; l_order : ORDER) : BOOLEAN -- Check if If-None-Match is present and then if there is a representation that has that etag -- if the representation hasn't changed, we return TRUE -- then the response is a 304 with no entity body returned. @@ -74,9 +74,9 @@ feature -- HTTP Methods end end - compute_response_get (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; l_order : ORDER) + compute_response_get (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER) local - h: EWF_HEADER + h: WSF_HEADER l_msg : STRING etag_utils : ETAG_UTILS do @@ -97,7 +97,7 @@ feature -- HTTP Methods end end - do_put (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_put (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) -- Updating a resource with PUT -- A successful PUT request will not create a new resource, instead it will -- change the state of the resource identified by the current uri. @@ -131,7 +131,7 @@ feature -- HTTP Methods end end - is_conditional_put (req : WGI_REQUEST; order : ORDER) : BOOLEAN + is_conditional_put (req : WSF_REQUEST; order : ORDER) : BOOLEAN -- Check if If-Match is present and then if there is a representation that has that etag -- if the representation hasn't changed, we return TRUE local @@ -150,9 +150,9 @@ feature -- HTTP Methods end - compute_response_put (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; l_order : ORDER) + compute_response_put (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER) local - h: EWF_HEADER + h: WSF_HEADER joc : JSON_ORDER_CONVERTER etag_utils : ETAG_UTILS do @@ -177,7 +177,7 @@ feature -- HTTP Methods end - do_delete (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_delete (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) -- Here we use DELETE to cancel an order, if that order is in state where -- it can still be canceled. -- 200 if is ok @@ -203,9 +203,9 @@ feature -- HTTP Methods end end - compute_response_delete (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + compute_response_delete (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) local - h: EWF_HEADER + h : WSF_HEADER do create h.make h.put_status ({HTTP_STATUS_CODE}.no_content) @@ -217,7 +217,7 @@ feature -- HTTP Methods res.write_headers_string (h.string) end - do_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) -- Here the convention is the following. -- POST is used for creation and the server determines the URI -- of the created resource. @@ -239,9 +239,9 @@ feature -- HTTP Methods end end - compute_response_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; l_order : ORDER) + compute_response_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER) local - h: EWF_HEADER + h: WSF_HEADER l_msg : STRING l_location : STRING joc : JSON_ORDER_CONVERTER diff --git a/examples/restbucks/src/restbucks_server.e b/examples/restbucks/src/restbucks_server.e index 5b01a28c..b58986a7 100644 --- a/examples/restbucks/src/restbucks_server.e +++ b/examples/restbucks/src/restbucks_server.e @@ -14,7 +14,7 @@ inherit ROUTED_APPLICATION_HELPER - DEFAULT_WGI_APPLICATION + DEFAULT_APPLICATION create make @@ -43,12 +43,12 @@ feature {NONE} -- Initialization feature -- Execution - execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) -- I'm using this method to handle the method not allowed response -- in the case that the given uri does not have a corresponding http method -- to handle it. local - h : EWF_HEADER + h : WSF_HEADER l_description : STRING l_api_doc : STRING do diff --git a/examples/restbucks/src/utils/etag_utils.e b/examples/restbucks/src/utils/etag_utils.e new file mode 100644 index 00000000..c8854d57 --- /dev/null +++ b/examples/restbucks/src/utils/etag_utils.e @@ -0,0 +1,35 @@ +note + description: "Summary description for {ETAG_UTILS}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + ETAG_UTILS + +inherit + + ARRAY_FACILITIES + +feature + md5_digest ( a_string : STRING ) : STRING + -- Cryptographic hash function that produces a 128-bit (16-byte) hash value, based on `a_string' + local + md5: MD5 + output: SPECIAL [NATURAL_8] + + do + create md5.make + create output.make_filled (0, 16) + md5.sink_string (a_string) + md5.do_final (output, 0) + Result := as_natural_32_be (output, 0).to_hex_string + Result := Result + as_natural_32_be (output, 4).to_hex_string + Result := Result + as_natural_32_be (output, 8).to_hex_string + Result := Result + as_natural_32_be (output, 12).to_hex_string + end + +note + copyright: "2011-2011, Javier Velilla and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" +end diff --git a/ext/crypto/eapml b/ext/crypto/eapml new file mode 160000 index 00000000..4f341f02 --- /dev/null +++ b/ext/crypto/eapml @@ -0,0 +1 @@ +Subproject commit 4f341f028c1825816bbb7fcb20c6ef11d7843bff diff --git a/ext/crypto/eel b/ext/crypto/eel new file mode 160000 index 00000000..f573b30f --- /dev/null +++ b/ext/crypto/eel @@ -0,0 +1 @@ +Subproject commit f573b30fec6eece84d36d4210b554d81df34577d diff --git a/ext/server/nino b/ext/server/nino index 4cd1b676..7fd4cdbe 160000 --- a/ext/server/nino +++ b/ext/server/nino @@ -1 +1 @@ -Subproject commit 4cd1b676070b98be7f577bdf810719491b09d09b +Subproject commit 7fd4cdbe4462a3fade81b9d029045ef2e7584b64 diff --git a/library/protocol/http/http-safe.ecf b/library/protocol/http/http-safe.ecf index cee2c04b..9a61b2bd 100644 --- a/library/protocol/http/http-safe.ecf +++ b/library/protocol/http/http-safe.ecf @@ -7,7 +7,7 @@ /EIFGENs$ /.svn$ - diff --git a/library/protocol/http/http.ecf b/library/protocol/http/http.ecf index f8e77884..ab2320f6 100644 --- a/library/protocol/http/http.ecf +++ b/library/protocol/http/http.ecf @@ -7,7 +7,7 @@ /EIFGENs$ /.svn$ - diff --git a/library/protocol/http/src/http_file_extension_mime_mapping.e b/library/protocol/http/src/http_file_extension_mime_mapping.e new file mode 100644 index 00000000..387e8ed4 --- /dev/null +++ b/library/protocol/http/src/http_file_extension_mime_mapping.e @@ -0,0 +1,238 @@ +note + description: "[ + Various common MIME types for file extensions + + See also for longer list and description + http://www.webmaster-toolkit.com/mime-types.shtml + + Please suggest missing entries + ]" + date: "$Date$" + revision: "$Revision$" + +class + HTTP_FILE_EXTENSION_MIME_MAPPING + +inherit + ANY + + HTTP_MIME_TYPES + export + {NONE} all + end + +create + make_empty, + make_default, + make_from_string, + make_from_file + +feature {NONE} -- Initialization + + make_empty (n: INTEGER) + -- Create with no mapping + -- but one can use `map' to add new mapping + do + create mapping.make (n) + mapping.compare_objects + end + + make_default + -- Create with default limited mapping + -- One can use `map' to add new mapping + local + m: like mapping + do + create m.make (40) + mapping := m + m.compare_objects + m.force (text_css, "css") + m.force (text_html, "html") + m.force (text_xml, "xml") + m.force (application_json, "json") + m.force (application_javascript, "js") + m.force (application_rss_xml, "rss") + m.force (application_atom_xml, "atom") + m.force (image_x_ico, "ico") + m.force (image_gif, "gif") + m.force (image_jpeg, "jpeg") + m.force (image_jpg, "jpg") + m.force (image_png, "png") + m.force (application_zip, "zip") + m.force (application_x_bzip, "bz") + m.force (application_x_bzip2, "bz2") + m.force (application_x_gzip, "gz") + m.force (application_x_gzip, "gzip") + m.force (application_x_tar, "tar") + m.force (application_x_compressed, "tgz") + m.force (application_postscript, "ps") + m.force (application_pdf, "pdf") + m.force (application_x_shockwave_flash, "swf") + m.force (text_plain, "conf") + m.force (text_plain, "log") + m.force (text_plain, "text") + m.force (text_plain, "txt") + end + + make_from_file (fn: READABLE_STRING_8) + -- Create with mime.types file + -- One can use `map' to add new mapping + local + f: RAW_FILE + do + create f.make (fn) + if f.exists and then f.is_readable then + make_empty (50) + f.open_read + from + f.read_line + until + f.exhausted or f.end_of_file + loop + add_mapping_line (f.last_string) + f.read_line + end + f.close + else + make_empty (0) + end + end + + make_from_string (t: READABLE_STRING_8) + -- Set mapping from multiline string `t' + -- line should be formatted as in http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types + --| # is a comment + --| mime-type space(s) extensions + local + i,j,n: INTEGER + do + make_empty (10) + n := t.count + if n > 0 then + from + i := 1 + until + i = 0 or i > n + loop + j := t.index_of ('%N', i) + if j > 0 then + add_mapping_line (t.substring (i, j - 1)) + i := j + 1 + else + add_mapping_line (t.substring (i, n)) + i := 0 + end + end + end + end + +feature -- Access + + mime_type (ext: READABLE_STRING_8): detachable READABLE_STRING_8 + -- Mime type for extension `ext' + do + Result := mapping.item (ext.as_lower) + end + +feature -- Element change + + map (e: READABLE_STRING_8; t: READABLE_STRING_8) + -- Add mapping extension `e' to mime type `t' + do + mapping.force (t, e.as_lower) + end + +feature {NONE} -- Implementation + + add_mapping_line (t: READABLE_STRING_8) + local + i,j,n: INTEGER + l_type, l_ext: READABLE_STRING_8 + do + n := t.count + if n > 0 then + -- ignore blanks + i := next_non_blank_position (t, i) + if i > 0 then + if t[i] = '#' then + --| ignore + else + j := next_blank_position (t, i) + if j > i then + l_type := t.substring (i, j - 1) + from + until + i = 0 + loop + i := next_non_blank_position (t, j) + if i > 0 then + j := next_blank_position (t, i) + if j = 0 then + l_ext := t.substring (i, n) + i := 0 + else + l_ext := t.substring (i, j - 1) + i := j + end + map (l_ext, l_type) + end + end + end + end + end + end + end + + next_blank_position (s: READABLE_STRING_8; p: INTEGER): INTEGER + local + i, n: INTEGER + do + n := s.count + from + i := p + 1 + until + i > n or s[i].is_space + loop + i := i + 1 + end + if i <= n then + Result := i + end + end + + next_non_blank_position (s: READABLE_STRING_8; p: INTEGER): INTEGER + local + i, n: INTEGER + do + n := s.count + from + i := p + 1 + until + i > n or not s[i].is_space + loop + i := i + 1 + end + if i <= n then + Result := i + end + end + + +feature {NONE} -- Extension MIME mapping + + mapping: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] + +invariant + mapping_keys_are_lowercase: across mapping as c all c.key.same_string (c.key.as_lower) end + +note + copyright: "2011-2011, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/library/protocol/http/src/http_mime_types.e b/library/protocol/http/src/http_mime_types.e index 4110d81c..37d8a924 100644 --- a/library/protocol/http/src/http_mime_types.e +++ b/library/protocol/http/src/http_mime_types.e @@ -19,11 +19,7 @@ feature -- Content type : application application_atom_xml: STRING = "application/atom+xml" -- atom application content-type header - application_x_www_form_encoded: STRING = "application/x-www-form-urlencoded" - -- Starting chars of form url-encoded data content-type header - - application_octet_stream: STRING = "application/octet-stream" - -- Octet stream content-type header + application_force_download: STRING = "application/force-download" application_javascript: STRING = "application/javascript" -- JavaScript application content-type header @@ -31,25 +27,54 @@ feature -- Content type : application application_json: STRING = "application/json" -- JSON application content-type header + application_octet_stream: STRING = "application/octet-stream" + -- Octet stream content-type header + application_pdf: STRING = "application/pdf" -- pdf application content-type header + application_postscript: STRING = "application/postscript" + -- postscript application content-type header + application_rss_xml: STRING = "application/rss+xml" -- rss application content-type header + application_rtf: STRING = "application/rtf" + -- RTF application content-type header + application_xml: STRING = "application/xml" -- xml application content-type header + application_x_shockwave_flash: STRING = "application/x-shockwave-flash" + application_x_compressed: STRING = "application/x-compressed" - -- x-compressed application content-type header + + application_x_gzip: STRING = "application/x-gzip" application_zip: STRING = "application/zip" - -- ZIP application content-type header + + application_x_bzip: STRING = "application/x-bzip" + + application_x_bzip2: STRING = "application/x-bzip2" + + application_x_tar: STRING = "application/x-tar" + + application_x_www_form_encoded: STRING = "application/x-www-form-urlencoded" + -- Starting chars of form url-encoded data content-type header feature -- Content type : audio + audio_mpeg3: STRING = "audio/mpeg3" + + audio_mpeg: STRING = "audio/mpeg" + + audio_wav: STRING = "audio/wav" + feature -- Content type : image + image_bmp: STRING = "image/bmp" + -- BMP image content-type header + image_gif: STRING = "image/gif" -- GIF image content-type header @@ -65,6 +90,12 @@ feature -- Content type : image image_svg_xml: STRING = "image/svg+xml" -- SVG+XML image content-type header + image_tiff: STRING = "image/tiff" + -- TIFF image content-type header + + image_x_ico: STRING = "image/x-ico" + -- ICO image content-type header + feature -- Content type : message message_http: STRING = "message/http" @@ -81,6 +112,8 @@ feature -- Content type : message feature -- Content type : model + model_vrml: STRING = "model/vrml" + feature -- Content type : multipart multipart_mixed: STRING = "multipart/mixed" @@ -95,6 +128,8 @@ feature -- Content type : multipart multipart_encrypted: STRING = "multipart/encrypted" + multipart_x_gzip: STRING = "multipart/x-gzip" + feature -- Content type : text text_css: STRING = "text/css" @@ -119,13 +154,23 @@ feature -- Content type : text text_rtf: STRING = "text/rtf" -- rtf content-type header + text_tab_separated_values: STRING = "text/tab-separated-values" + -- TSV text content-type header + text_xml: STRING = "text/xml" -- XML text content-type header text_vcard: STRING = "text/vcard" -- vcard text content-type header -feature -- Content type : video +feature -- Content type : video + + video_avi: STRING = "video/avi" + + video_quicktime: STRING = "video/quicktime" + + video_x_motion_jpeg: STRING = "video/x-motion-jpeg" + note copyright: "2011-2011, Eiffel Software and others" diff --git a/library/protocol/http/src/http_request_methods.e b/library/protocol/http/src/http_request_methods.e index 56603683..c4f0a0ab 100644 --- a/library/protocol/http/src/http_request_methods.e +++ b/library/protocol/http/src/http_request_methods.e @@ -51,7 +51,7 @@ feature -- Methods intented for actions method_delete: STRING = "DELETE" -- Deletes the specified resource. - + feature -- Other Methods method_connect: STRING = "CONNECT" diff --git a/library/protocol/uri_template/src/uri_template.e b/library/protocol/uri_template/src/uri_template.e index c8d3b843..4f74c0de 100644 --- a/library/protocol/uri_template/src/uri_template.e +++ b/library/protocol/uri_template/src/uri_template.e @@ -189,7 +189,7 @@ feature -- Match exp: URI_TEMPLATE_EXPRESSION vn, s,t: STRING vv, path_vv: STRING - l_vars, l_path_vars, l_query_vars: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL] + l_vars, l_path_vars, l_query_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] l_uri_count: INTEGER tpl_count: INTEGER l_next_literal_separator: detachable STRING @@ -274,7 +274,7 @@ feature -- Match vv := "/" nb := 0 until - vv.is_empty or q + l_offset > a_uri.count + vv.is_empty or q + l_offset + 1 > a_uri.count loop vv := next_path_variable_value (a_uri, q + l_offset + 1, l_next_literal_separator) l_offset := l_offset + vv.count + 1 @@ -414,7 +414,7 @@ feature {NONE} -- Implementation end end - import_path_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]) + import_path_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]) require a_content_attached: a_content /= Void res_attached: res /= Void @@ -422,7 +422,7 @@ feature {NONE} -- Implementation import_custom_style_parameters_into (a_content, ';', res) end - import_form_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]) + import_form_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]) require a_content_attached: a_content /= Void res_attached: res /= Void @@ -430,14 +430,14 @@ feature {NONE} -- Implementation import_custom_style_parameters_into (a_content, '&', res) end - import_custom_style_parameters_into (a_content: STRING; a_separator: CHARACTER; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]) + import_custom_style_parameters_into (a_content: STRING; a_separator: CHARACTER; res: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]) require a_content_attached: a_content /= Void res_attached: res /= Void local n, p, i, j: INTEGER - s: STRING - l_name,l_value: STRING + s: READABLE_STRING_8 + l_name, l_value: READABLE_STRING_8 do n := a_content.count if n > 0 then diff --git a/library/protocol/uri_template/src/uri_template_match_result.e b/library/protocol/uri_template/src/uri_template_match_result.e index 1077444c..7feb8d0e 100644 --- a/library/protocol/uri_template/src/uri_template_match_result.e +++ b/library/protocol/uri_template/src/uri_template_match_result.e @@ -24,30 +24,29 @@ feature {NONE} -- Initialization make (create {like path_variables}.make (0), create {like query_variables}.make (0)) end - feature -- Access - path_variables: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL] + path_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] -- Variables being part of the path segments - query_variables: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL] + query_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] -- Variables being part of the query segments (i.e: after the ?) feature -- Query - path_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + path_variable (n: READABLE_STRING_8): detachable READABLE_STRING_8 -- Value related to query variable name `n' do Result := path_variables.item (n) end - query_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + query_variable (n: READABLE_STRING_8): detachable READABLE_STRING_8 -- Value related to path variable name `n' do Result := query_variables.item (n) end - variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + variable (n: READABLE_STRING_8): detachable READABLE_STRING_8 -- Value related to variable name `n' do Result := query_variable (n) @@ -58,7 +57,7 @@ feature -- Query feature -- Query: url-decoded - url_decoded_query_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + url_decoded_query_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32 -- Unencoded value related to variable name `n' do if attached query_variable (n) as v then @@ -66,7 +65,7 @@ feature -- Query: url-decoded end end - url_decoded_path_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + url_decoded_path_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32 -- Unencoded value related to variable name `n' do if attached path_variable (n) as v then @@ -74,7 +73,7 @@ feature -- Query: url-decoded end end - url_decoded_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + url_decoded_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32 -- Unencoded value related to variable name `n' do if attached variable (n) as v then @@ -84,7 +83,7 @@ feature -- Query: url-decoded feature {NONE} -- Implementation - url_decoded_string (s: READABLE_STRING_GENERAL): READABLE_STRING_32 + url_decoded_string (s: READABLE_STRING_8): READABLE_STRING_32 do Result := url_encoder.decoded_string (s.as_string_8) end diff --git a/library/server/ewsgi/connectors/cgi/cgi-safe.ecf b/library/server/ewsgi/connectors/cgi/cgi-safe.ecf index 512dd955..6ddc9af7 100644 --- a/library/server/ewsgi/connectors/cgi/cgi-safe.ecf +++ b/library/server/ewsgi/connectors/cgi/cgi-safe.ecf @@ -10,6 +10,7 @@ + diff --git a/library/server/ewsgi/connectors/cgi/cgi.ecf b/library/server/ewsgi/connectors/cgi/cgi.ecf index d6c265ec..0e8b4361 100644 --- a/library/server/ewsgi/connectors/cgi/cgi.ecf +++ b/library/server/ewsgi/connectors/cgi/cgi.ecf @@ -10,6 +10,7 @@ + diff --git a/library/server/ewsgi/connectors/cgi/src/ewf_cgi_connector.e b/library/server/ewsgi/connectors/cgi/src/ewf_cgi_connector.e deleted file mode 100644 index 3a665d43..00000000 --- a/library/server/ewsgi/connectors/cgi/src/ewf_cgi_connector.e +++ /dev/null @@ -1,38 +0,0 @@ -note - description: "Summary description for {EWF_CGI_CONNECTOR}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - EWF_CGI_CONNECTOR - -inherit - WGI_CONNECTOR - -create - make - -feature -- Execution - - launch - local - req: WGI_REQUEST_FROM_TABLE - res: WGI_RESPONSE_STREAM_BUFFER - do - create req.make ((create {EXECUTION_ENVIRONMENT}).starting_environment_variables, create {EWF_CGI_INPUT_STREAM}.make) - create res.make (create {EWF_CGI_OUTPUT_STREAM}.make) - application.process (req, res) - end - -note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/connectors/cgi/src/wgi_cgi_connector.e b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_connector.e new file mode 100644 index 00000000..5b30cc66 --- /dev/null +++ b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_connector.e @@ -0,0 +1,55 @@ +note + description: "Summary description for {WGI_CGI_CONNECTOR}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WGI_CGI_CONNECTOR + +inherit + WGI_CONNECTOR + +create + make + +feature -- Execution + + launch + local + req: WGI_REQUEST_FROM_TABLE + res: detachable WGI_RESPONSE_STREAM_BUFFER + rescued: BOOLEAN + do + if not rescued then + create req.make ((create {EXECUTION_ENVIRONMENT}).starting_environment_variables, create {WGI_CGI_INPUT_STREAM}.make) + create res.make (create {WGI_CGI_OUTPUT_STREAM}.make) + application.execute (req, res) + else + if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then + if res /= Void then + if not res.status_is_set then + res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void) + end + if res.message_writable then + res.write_string ("
" + l_trace + "
") + end + end + end + end + rescue + rescued := True + retry + end + +note + copyright: "2011-2011, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/library/server/ewsgi/connectors/cgi/src/ewf_cgi_input_stream.e b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_input_stream.e similarity index 88% rename from library/server/ewsgi/connectors/cgi/src/ewf_cgi_input_stream.e rename to library/server/ewsgi/connectors/cgi/src/wgi_cgi_input_stream.e index 7d09236b..5659f599 100644 --- a/library/server/ewsgi/connectors/cgi/src/ewf_cgi_input_stream.e +++ b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_input_stream.e @@ -1,12 +1,12 @@ note - description: "Summary description for EWF_CGI_INPUT_STREAM." + description: "Summary description for WGI_CGI_INPUT_STREAM." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class - EWF_CGI_INPUT_STREAM + WGI_CGI_INPUT_STREAM inherit WGI_INPUT_STREAM diff --git a/library/server/ewsgi/connectors/cgi/src/ewf_cgi_output_stream.e b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_output_stream.e similarity index 93% rename from library/server/ewsgi/connectors/cgi/src/ewf_cgi_output_stream.e rename to library/server/ewsgi/connectors/cgi/src/wgi_cgi_output_stream.e index f586a548..1a714b21 100644 --- a/library/server/ewsgi/connectors/cgi/src/ewf_cgi_output_stream.e +++ b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_output_stream.e @@ -1,12 +1,12 @@ note - description: "Summary description for EWF_CGI_OUTPUT_STREAM." + description: "Summary description for WGI_CGI_OUTPUT_STREAM." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class - EWF_CGI_OUTPUT_STREAM + WGI_CGI_OUTPUT_STREAM inherit WGI_OUTPUT_STREAM diff --git a/library/server/ewsgi/src/connector/wgi_connector.e b/library/server/ewsgi/connectors/common/wgi_connector.e similarity index 100% rename from library/server/ewsgi/src/connector/wgi_connector.e rename to library/server/ewsgi/connectors/common/wgi_connector.e diff --git a/library/server/ewsgi/connectors/connector-safe.ecf b/library/server/ewsgi/connectors/connector-safe.ecf new file mode 100644 index 00000000..1361b1c6 --- /dev/null +++ b/library/server/ewsgi/connectors/connector-safe.ecf @@ -0,0 +1,16 @@ + + + + + + /.git$ + /EIFGENs$ + /.svn$ + + + + + + + diff --git a/library/server/ewsgi/connectors/connector.ecf b/library/server/ewsgi/connectors/connector.ecf new file mode 100644 index 00000000..0a591f8f --- /dev/null +++ b/library/server/ewsgi/connectors/connector.ecf @@ -0,0 +1,16 @@ + + + + + + /.git$ + /EIFGENs$ + /.svn$ + + + + + + + diff --git a/library/server/ewsgi/connectors/libfcgi/libfcgi-safe.ecf b/library/server/ewsgi/connectors/libfcgi/libfcgi-safe.ecf index 875f24c0..fbc3d0ac 100644 --- a/library/server/ewsgi/connectors/libfcgi/libfcgi-safe.ecf +++ b/library/server/ewsgi/connectors/libfcgi/libfcgi-safe.ecf @@ -10,6 +10,7 @@ + diff --git a/library/server/ewsgi/connectors/libfcgi/libfcgi.ecf b/library/server/ewsgi/connectors/libfcgi/libfcgi.ecf index bf084003..5240dad5 100644 --- a/library/server/ewsgi/connectors/libfcgi/libfcgi.ecf +++ b/library/server/ewsgi/connectors/libfcgi/libfcgi.ecf @@ -10,6 +10,7 @@ + diff --git a/library/server/ewsgi/connectors/libfcgi/src/ewf_libfcgi_connector.e b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e similarity index 61% rename from library/server/ewsgi/connectors/libfcgi/src/ewf_libfcgi_connector.e rename to library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e index 7354ad6d..49838b2a 100644 --- a/library/server/ewsgi/connectors/libfcgi/src/ewf_libfcgi_connector.e +++ b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e @@ -1,12 +1,12 @@ note - description: "Summary description for {EWF_LIBFCGI_CONNECTOR}." + description: "Summary description for {WGI_LIBFCGI_CONNECTOR}." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class - EWF_LIBFCGI_CONNECTOR + WGI_LIBFCGI_CONNECTOR inherit WGI_CONNECTOR @@ -22,8 +22,8 @@ feature {NONE} -- Initialization initialize do create fcgi.make - create {EWF_LIBFCGI_INPUT_STREAM} input.make (fcgi) - create {EWF_LIBFCGI_OUTPUT_STREAM} output.make (fcgi) + create {WGI_LIBFCGI_INPUT_STREAM} input.make (fcgi) + create {WGI_LIBFCGI_OUTPUT_STREAM} output.make (fcgi) end feature -- Server @@ -47,11 +47,28 @@ feature -- Execution process_fcgi_request (vars: HASH_TABLE [STRING, STRING]; a_input: like input; a_output: like output) local req: WGI_REQUEST_FROM_TABLE - res: WGI_RESPONSE_STREAM_BUFFER + res: detachable WGI_RESPONSE_STREAM_BUFFER + rescued: BOOLEAN do - create req.make (vars, a_input) - create res.make (a_output) - application.process (req, res) + if not rescued then + create req.make (vars, a_input) + create res.make (a_output) + application.execute (req, res) + else + if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then + if res /= Void then + if not res.status_is_set then + res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void) + end + if res.message_writable then + res.write_string ("
" + l_trace + "
") + end + end + end + end + rescue + rescued := True + retry end feature -- Input/Output diff --git a/library/server/ewsgi/connectors/libfcgi/src/ewf_libfcgi_input_stream.e b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_input_stream.e similarity index 92% rename from library/server/ewsgi/connectors/libfcgi/src/ewf_libfcgi_input_stream.e rename to library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_input_stream.e index 494ff28e..5fc258cf 100644 --- a/library/server/ewsgi/connectors/libfcgi/src/ewf_libfcgi_input_stream.e +++ b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_input_stream.e @@ -1,12 +1,12 @@ note - description: "Summary description for EWF_LIBFCGI_INPUT_STREAM." + description: "Summary description for WGI_LIBFCGI_INPUT_STREAM." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class - EWF_LIBFCGI_INPUT_STREAM + WGI_LIBFCGI_INPUT_STREAM inherit WGI_INPUT_STREAM diff --git a/library/server/ewsgi/connectors/libfcgi/src/ewf_libfcgi_output_stream.e b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_output_stream.e similarity index 94% rename from library/server/ewsgi/connectors/libfcgi/src/ewf_libfcgi_output_stream.e rename to library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_output_stream.e index 9a5c5a7c..45c6c9b3 100644 --- a/library/server/ewsgi/connectors/libfcgi/src/ewf_libfcgi_output_stream.e +++ b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_output_stream.e @@ -1,12 +1,12 @@ note - description: "Summary description for {EWF_LIBFCGI_OUTPUT_STREAM}." + description: "Summary description for {WGI_LIBFCGI_OUTPUT_STREAM}." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class - EWF_LIBFCGI_OUTPUT_STREAM + WGI_LIBFCGI_OUTPUT_STREAM inherit WGI_OUTPUT_STREAM diff --git a/library/server/ewsgi/connectors/nino/nino-safe.ecf b/library/server/ewsgi/connectors/nino/nino-safe.ecf index 746f7baf..17f34c9e 100644 --- a/library/server/ewsgi/connectors/nino/nino-safe.ecf +++ b/library/server/ewsgi/connectors/nino/nino-safe.ecf @@ -10,6 +10,7 @@ + diff --git a/library/server/ewsgi/connectors/nino/nino.ecf b/library/server/ewsgi/connectors/nino/nino.ecf index 68818796..375ae126 100644 --- a/library/server/ewsgi/connectors/nino/nino.ecf +++ b/library/server/ewsgi/connectors/nino/nino.ecf @@ -10,6 +10,7 @@ + diff --git a/library/server/ewsgi/default/nino/nino_application.e b/library/server/ewsgi/connectors/nino/src/nino_application.e similarity index 98% rename from library/server/ewsgi/default/nino/nino_application.e rename to library/server/ewsgi/connectors/nino/src/nino_application.e index 51d85966..d942dd1d 100644 --- a/library/server/ewsgi/default/nino/nino_application.e +++ b/library/server/ewsgi/connectors/nino/src/nino_application.e @@ -29,7 +29,7 @@ feature {NONE} -- Implementation create connector.make_with_base (app, a_base_url) end - connector: EWF_NINO_CONNECTOR + connector: WGI_NINO_CONNECTOR -- Web server connector feature -- Status settings diff --git a/library/server/ewsgi/connectors/nino/src/ewf_nino_connector.e b/library/server/ewsgi/connectors/nino/src/wgi_nino_connector.e similarity index 66% rename from library/server/ewsgi/connectors/nino/src/ewf_nino_connector.e rename to library/server/ewsgi/connectors/nino/src/wgi_nino_connector.e index a5891067..d7ca04fb 100644 --- a/library/server/ewsgi/connectors/nino/src/ewf_nino_connector.e +++ b/library/server/ewsgi/connectors/nino/src/wgi_nino_connector.e @@ -1,11 +1,11 @@ note - description: "Summary description for {EWF_NINO_CONNECTOR}." + description: "Summary description for {WGI_NINO_CONNECTOR}." author: "" date: "$Date$" revision: "$Revision$" class - EWF_NINO_CONNECTOR + WGI_NINO_CONNECTOR inherit WGI_CONNECTOR @@ -68,7 +68,7 @@ feature -- Server local l_http_handler : HTTP_HANDLER do - create {EWF_NINO_HANDLER} l_http_handler.make_with_callback (server, "NINO_HANDLER", Current) + create {WGI_NINO_HANDLER} l_http_handler.make_with_callback (server, "NINO_HANDLER", Current) debug ("nino") if attached base as l_base then print ("Base=" + l_base + "%N") @@ -80,12 +80,29 @@ feature -- Server process_request (env: HASH_TABLE [STRING, STRING]; a_headers_text: STRING; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM) local req: WGI_REQUEST_FROM_TABLE - res: WGI_RESPONSE_STREAM_BUFFER + res: detachable WGI_RESPONSE_STREAM_BUFFER + rescued: BOOLEAN do - create req.make (env, create {EWF_NINO_INPUT_STREAM}.make (a_input)) - create res.make (create {EWF_NINO_OUTPUT_STREAM}.make (a_output)) - req.set_meta_string_variable ("RAW_HEADER_DATA", a_headers_text) - application.execute (req, res) + if not rescued then + create req.make (env, create {WGI_NINO_INPUT_STREAM}.make (a_input)) + create res.make (create {WGI_NINO_OUTPUT_STREAM}.make (a_output)) + req.set_meta_string_variable ("RAW_HEADER_DATA", a_headers_text) + application.execute (req, res) + else + if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then + if res /= Void then + if not res.status_is_set then + res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void) + end + if res.message_writable then + res.write_string ("
" + l_trace + "
") + end + end + end + end + rescue + rescued := True + retry end note diff --git a/library/server/ewsgi/connectors/nino/src/ewf_nino_handler.e b/library/server/ewsgi/connectors/nino/src/wgi_nino_handler.e similarity index 99% rename from library/server/ewsgi/connectors/nino/src/ewf_nino_handler.e rename to library/server/ewsgi/connectors/nino/src/wgi_nino_handler.e index d6ac6d0d..2f0de156 100644 --- a/library/server/ewsgi/connectors/nino/src/ewf_nino_handler.e +++ b/library/server/ewsgi/connectors/nino/src/wgi_nino_handler.e @@ -5,7 +5,7 @@ note revision : "$Revision$" class - EWF_NINO_HANDLER + WGI_NINO_HANDLER inherit HTTP_CONNECTION_HANDLER @@ -23,7 +23,7 @@ feature {NONE} -- Initialization callback := a_callback end - callback: EWF_NINO_CONNECTOR + callback: WGI_NINO_CONNECTOR feature -- Access diff --git a/library/server/ewsgi/connectors/nino/src/ewf_nino_input_stream.e b/library/server/ewsgi/connectors/nino/src/wgi_nino_input_stream.e similarity index 88% rename from library/server/ewsgi/connectors/nino/src/ewf_nino_input_stream.e rename to library/server/ewsgi/connectors/nino/src/wgi_nino_input_stream.e index 9cc0d4ec..95fb8cbd 100644 --- a/library/server/ewsgi/connectors/nino/src/ewf_nino_input_stream.e +++ b/library/server/ewsgi/connectors/nino/src/wgi_nino_input_stream.e @@ -1,12 +1,12 @@ note - description: "Summary description for {EWF_NINO_INPUT_STREAM}." + description: "Summary description for {WGI_NINO_INPUT_STREAM}." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class - EWF_NINO_INPUT_STREAM + WGI_NINO_INPUT_STREAM inherit WGI_INPUT_STREAM @@ -22,7 +22,7 @@ feature {NONE} -- Initialization set_nino_input (a_nino_input) end -feature {EWF_NINO_CONNECTOR, WGI_APPLICATION} -- Nino +feature {WGI_NINO_CONNECTOR, WGI_APPLICATION} -- Nino set_nino_input (i: like nino_input) do diff --git a/library/server/ewsgi/connectors/nino/src/ewf_nino_output_stream.e b/library/server/ewsgi/connectors/nino/src/wgi_nino_output_stream.e similarity index 91% rename from library/server/ewsgi/connectors/nino/src/ewf_nino_output_stream.e rename to library/server/ewsgi/connectors/nino/src/wgi_nino_output_stream.e index b3b9488d..fd13d180 100644 --- a/library/server/ewsgi/connectors/nino/src/ewf_nino_output_stream.e +++ b/library/server/ewsgi/connectors/nino/src/wgi_nino_output_stream.e @@ -1,12 +1,12 @@ note - description: "Summary description for {EWF_NINO_OUTPUT_STREAM}." + description: "Summary description for {WGI_NINO_OUTPUT_STREAM}." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class - EWF_NINO_OUTPUT_STREAM + WGI_NINO_OUTPUT_STREAM inherit WGI_OUTPUT_STREAM @@ -26,7 +26,7 @@ feature {NONE} -- Initialization set_nino_output (a_nino_output) end -feature {EWF_NINO_CONNECTOR, WGI_APPLICATION} -- Nino +feature {WGI_NINO_CONNECTOR, WGI_APPLICATION} -- Nino set_nino_output (o: like nino_output) do diff --git a/library/server/ewsgi/default.7z b/library/server/ewsgi/default.7z new file mode 100644 index 00000000..74ae7912 Binary files /dev/null and b/library/server/ewsgi/default.7z differ diff --git a/library/server/ewsgi/examples/hello_world/hello-safe.ecf b/library/server/ewsgi/examples/hello_world/hello-safe.ecf index aabd666f..76cdb452 100644 --- a/library/server/ewsgi/examples/hello_world/hello-safe.ecf +++ b/library/server/ewsgi/examples/hello_world/hello-safe.ecf @@ -11,7 +11,6 @@ - diff --git a/library/server/ewsgi/examples/hello_world/hello.ecf b/library/server/ewsgi/examples/hello_world/hello.ecf index 2eea409b..9d081303 100644 --- a/library/server/ewsgi/examples/hello_world/hello.ecf +++ b/library/server/ewsgi/examples/hello_world/hello.ecf @@ -11,7 +11,6 @@ - diff --git a/library/server/ewsgi/examples/hello_world_with_response/hello-safe.ecf b/library/server/ewsgi/examples/hello_world_with_response/hello-safe.ecf deleted file mode 100644 index f388706e..00000000 --- a/library/server/ewsgi/examples/hello_world_with_response/hello-safe.ecf +++ /dev/null @@ -1,28 +0,0 @@ - - - - - /EIFGENs$ - /\.git$ - /\.svn$ - - - - - - - - - - - - - - - - - - - diff --git a/library/server/ewsgi/examples/hello_world_with_response/license.lic b/library/server/ewsgi/examples/hello_world_with_response/license.lic deleted file mode 100644 index cf2d1ed9..00000000 --- a/library/server/ewsgi/examples/hello_world_with_response/license.lic +++ /dev/null @@ -1,10 +0,0 @@ -${NOTE_KEYWORD} - copyright: "2011-${YEAR}, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" diff --git a/library/server/ewsgi/examples/hello_world_with_response/src/hello_world.e b/library/server/ewsgi/examples/hello_world_with_response/src/hello_world.e deleted file mode 100644 index 910a9f5d..00000000 --- a/library/server/ewsgi/examples/hello_world_with_response/src/hello_world.e +++ /dev/null @@ -1,48 +0,0 @@ -note - description : "Objects that ..." - author : "$Author$" - date : "$Date$" - revision : "$Revision$" - -class - HELLO_WORLD - -inherit - WGI_RESPONSE_APPLICATION - - DEFAULT_WGI_APPLICATION - -create - make_and_launch - -feature -- Response - - response (request: WGI_REQUEST): WGI_RESPONSE - do - if request.path_info.starts_with ("/streaming/") then - Result := streaming_response (request) - else - create Result.make - Result.set_status (200) - Result.set_header ("Content-Type", "text/html; charset=utf-8") - Result.set_message_body ("Hello World") - end - end - - streaming_response (request: WGI_REQUEST): WGI_RESPONSE - do - create {HELLO_WORLD_RESPONSE} Result.make - Result.set_status (200) - Result.set_header ("Content-Type", "text/html; charset=utf-8") - end -note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/examples/hello_world_with_response/src/hello_world_response.e b/library/server/ewsgi/examples/hello_world_with_response/src/hello_world_response.e deleted file mode 100644 index 09fde7f2..00000000 --- a/library/server/ewsgi/examples/hello_world_with_response/src/hello_world_response.e +++ /dev/null @@ -1,70 +0,0 @@ -note - description: "A streaming (non-buffered) Hello World example." - author: "Paul Cohen " - status: "Draft" - -class HELLO_WORLD_RESPONSE - -inherit - WGI_RESPONSE - redefine - make, - read_block - end - -create - make - -feature {NONE} -- Initialization - - make - do - precursor - set_ready_to_transmit - current_hello := 0 - end - -feature {NONE} -- Entity body - - read_block - -- Reads a block of 100000 lines of "Hello World". - local - i: INTEGER - do - if current_hello >= 10000 then - end_of_blocks := True - else - if current_hello = 0 then - current_block := "%N" - current_block.append ("Welcome
In progress
") - end - from - i := 0 - until - i = 1000 - loop - current_block.append ("Hello World ("+ current_hello.out +","+ i.out +")
%N") - i := i + 1 - end - current_hello := current_hello + i - current_block.append ("
In progress - "+ (100 * current_hello // 10000).out +"%%
") - if current_hello = 10000 then - current_block.append ("Bye bye..
Completed - GO TO BOTTOM
") - end_of_blocks := True - end - end - end - - current_hello: INTEGER - -;note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/specification/connector/wgi_connector.e b/library/server/ewsgi/specification/connector/wgi_connector.e deleted file mode 100644 index cfd400d3..00000000 --- a/library/server/ewsgi/specification/connector/wgi_connector.e +++ /dev/null @@ -1,44 +0,0 @@ -note - description: "Summary description for {WGI_CONNECTOR}." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - WGI_CONNECTOR - -feature {NONE} -- Initialization - - make (a_app: like application) - do - application := a_app - initialize - end - - initialize - -- Initialize connector - do - end - -feature {NONE} -- Access - - application: WGI_APPLICATION - -- Gateway Application - -feature -- Server - - launch - deferred - end - -note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/specification/request/obsolete/wgi_cookie.e b/library/server/ewsgi/specification/request/obsolete/wgi_cookie.e deleted file mode 100644 index d76edbbc..00000000 --- a/library/server/ewsgi/specification/request/obsolete/wgi_cookie.e +++ /dev/null @@ -1,76 +0,0 @@ -note - description: "[ - Contains all information of a rfc2109 cookie that was read from the request header - ]" - legal: "See notice at end of class." - status: "See notice at end of class." - date: "$Date$" - revision: "$Revision$" - -class - WGI_COOKIE - -create - make - -convert - value: {READABLE_STRING_8, STRING_8, READABLE_STRING_GENERAL, STRING_GENERAL} - -feature {NONE} -- Initialization - - make (a_name: STRING; a_value: STRING) - -- Creates current. - require - a_name_not_empty: a_name /= Void and then not a_name.is_empty - a_value_not_empty: a_value /= Void and then not a_value.is_empty - do - name := a_name - value := a_value - ensure - a_name_set: name = a_name - a_value_set: value = a_value - end - -feature -- Access - - name: STRING - -- Required. The name of the state information ("cookie") is NAME, - -- and its value is VALUE. NAMEs that begin with $ are reserved for - -- other uses and must not be used by applications. - - value: STRING - -- The VALUE is opaque to the user agent and may be anything the - -- origin server chooses to send, possibly in a server-selected - -- printable ASCII encoding. "Opaque" implies that the content is of - -- interest and relevance only to the origin server. The content - -- may, in fact, be readable by anyone that examines the Set-Cookie - -- header. - -feature -- Query - - variables: detachable HASH_TABLE [STRING, STRING] - -- Potential variable contained in the encoded cookie's value. - -feature -- Status report - - value_is_string (s: READABLE_STRING_GENERAL): BOOLEAN - -- Is `value' same string as `s' - do - Result := s.same_string (value) - end - -invariant - name_attached: name /= Void - value_attached: value /= Void - -note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/specification/request/obsolete/wgi_variables.e b/library/server/ewsgi/specification/request/obsolete/wgi_variables.e deleted file mode 100644 index f3da8079..00000000 --- a/library/server/ewsgi/specification/request/obsolete/wgi_variables.e +++ /dev/null @@ -1,80 +0,0 @@ -note - description : "[ - Interface to access the variable stored in a container - ]" - legal: "See notice at end of class." - status: "See notice at end of class." - date: "$Date$" - revision: "$Revision$" - -deferred class - WGI_VARIABLES [G -> STRING_GENERAL] - -inherit - ITERABLE [G] - -feature -- Status report - - has_variable (a_name: STRING): BOOLEAN - -- Has variable associated with `a_name' - require - a_name_not_empty: a_name /= Void and then not a_name.is_empty - deferred - end - -feature -- Access - - variable (a_name: STRING): detachable G - -- Value for variable associated with `a_name' - -- If not found, return Void - require - a_name_not_empty: a_name /= Void and then not a_name.is_empty - deferred - end - - variable_or_default (a_name: STRING; a_default: G; use_default_when_empty: BOOLEAN): G - -- Value for variable `a_name' - -- If not found, return `a_default' - require - a_name_not_empty: a_name /= Void and then not a_name.is_empty - do - if attached variable (a_name) as s then - if use_default_when_empty and then s.is_empty then - Result := a_default - else - Result := s - end - else - Result := a_default - end - end - -feature {WGI_REQUEST, WGI_APPLICATION, WGI_CONNECTOR} -- Element change - - set_variable (a_name: STRING; a_value: G) - require - a_name_not_empty: a_name /= Void and then not a_name.is_empty - deferred - ensure - variable_set: has_variable (a_name) and then variable (a_name) ~ a_value - end - - unset_variable (a_name: STRING) - require - a_name_not_empty: a_name /= Void and then not a_name.is_empty - deferred - ensure - variable_unset: not has_variable (a_name) - end - -note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/specification/request/wgi_request.e b/library/server/ewsgi/specification/request/wgi_request.e index 2e3c6a97..cf169bf5 100644 --- a/library/server/ewsgi/specification/request/wgi_request.e +++ b/library/server/ewsgi/specification/request/wgi_request.e @@ -80,23 +80,16 @@ feature -- Access: Input deferred end -feature -- Access: extra values - - request_time: detachable DATE_TIME - -- Request time (UTC) - deferred - end - feature -- Access: CGI meta variables - meta_variable (a_name: READABLE_STRING_GENERAL): detachable WGI_STRING_VALUE + meta_variable (a_name: READABLE_STRING_8): detachable READABLE_STRING_8 -- Environment variable related to `a_name' require a_name_valid: a_name /= Void and then not a_name.is_empty deferred end - meta_string_variable (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + meta_string_variable (a_name: READABLE_STRING_8): detachable READABLE_STRING_8 -- Environment variable related to `a_name' require a_name_valid: a_name /= Void and then not a_name.is_empty @@ -106,7 +99,7 @@ feature -- Access: CGI meta variables end end - meta_variables: ITERABLE [WGI_STRING_VALUE] + meta_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] -- These variables are specific to requests made with HTTP. -- Interpretation of these variables may depend on the value of -- SERVER_PROTOCOL. @@ -138,7 +131,7 @@ feature -- Access: CGI meta variables feature -- Common Gateway Interface - 1.1 8 January 1996 - auth_type: detachable READABLE_STRING_32 + auth_type: detachable READABLE_STRING_8 -- This variable is specific to requests made via the "http" -- scheme. -- @@ -160,7 +153,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - content_length: detachable READABLE_STRING_32 + content_length: detachable READABLE_STRING_8 -- This metavariable is set to the size of the message-body -- entity attached to the request, if any, in decimal number of -- octets. If no data are attached, then this metavariable is @@ -175,12 +168,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - content_length_value: NATURAL_64 - -- Integer value related to `content_length" - deferred - end - - content_type: detachable READABLE_STRING_32 + content_type: detachable READABLE_STRING_8 -- If the request includes a message-body, CONTENT_TYPE is set to -- the Internet Media Type [9] of the attached entity if the type -- was provided via a "Content-type" field in the request header, @@ -223,7 +211,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - gateway_interface: READABLE_STRING_32 + gateway_interface: READABLE_STRING_8 -- This metavariable is set to the dialect of CGI being used by -- the server to communicate with the script. Syntax: -- @@ -256,7 +244,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - path_info: READABLE_STRING_32 + path_info: READABLE_STRING_8 -- The PATH_INFO metavariable specifies a path to be interpreted -- by the CGI script. It identifies the resource or sub-resource -- to be returned by the CGI script, and it is derived from the @@ -287,7 +275,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - path_translated: detachable READABLE_STRING_32 + path_translated: detachable READABLE_STRING_8 -- PATH_TRANSLATED is derived by taking any path-info component -- of the request URI (see section 6.1.6), decoding it (see -- section 3.1), parsing it as a URI in its own right, and @@ -333,7 +321,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - query_string: READABLE_STRING_32 + query_string: READABLE_STRING_8 -- A URL-encoded string; the part of the Script-URI. (See -- section 3.2.) -- @@ -350,7 +338,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - remote_addr: READABLE_STRING_32 + remote_addr: READABLE_STRING_8 -- The IP address of the client sending the request to the -- server. This is not necessarily that of the user agent (such -- as if the request came through a proxy). @@ -365,7 +353,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - remote_host: detachable READABLE_STRING_32 + remote_host: detachable READABLE_STRING_8 -- The fully qualified domain name of the client sending the -- request to the server, if available, otherwise NULL. (See -- section 6.1.9.) Fully qualified domain names take the form as @@ -376,7 +364,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - remote_ident: detachable READABLE_STRING_32 + remote_ident: detachable READABLE_STRING_8 -- The identity information reported about the connection by a -- RFC 1413 [11] request to the remote agent, if available. -- Servers MAY choose not to support this feature, or not to @@ -392,7 +380,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - remote_user: detachable READABLE_STRING_32 + remote_user: detachable READABLE_STRING_8 -- If the request required authentication using the "Basic" -- mechanism (i.e., the AUTH_TYPE metavariable is set to -- "Basic"), then the value of the REMOTE_USER metavariable is @@ -408,7 +396,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - request_method: READABLE_STRING_32 + request_method: READABLE_STRING_8 -- The REQUEST_METHOD metavariable is set to the method with -- which the request was made, as described in section 5.1.1 of -- the HTTP/1.0 specification [3] and section 5.1.1 of the @@ -429,7 +417,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - script_name: READABLE_STRING_32 + script_name: READABLE_STRING_8 -- The SCRIPT_NAME metavariable is set to a URL path that could -- identify the CGI script (rather than the script's output). The -- syntax and semantics are identical to a decoded HTTP URL @@ -447,7 +435,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - server_name: READABLE_STRING_32 + server_name: READABLE_STRING_8 -- The SERVER_NAME metavariable is set to the name of the server, -- as derived from the part of the Script-URI (see section -- 3.2). @@ -473,7 +461,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - server_protocol: READABLE_STRING_32 + server_protocol: READABLE_STRING_8 -- The SERVER_PROTOCOL metavariable is set to the name and -- revision of the information protocol with which the request -- arrived. This is not necessarily the same as the protocol @@ -501,7 +489,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - server_software: READABLE_STRING_32 + server_software: READABLE_STRING_8 -- The SERVER_SOFTWARE metavariable is set to the name and -- version of the information server software answering the -- request (and running the gateway). @@ -516,42 +504,42 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 feature -- HTTP_* - http_accept: detachable READABLE_STRING_32 + http_accept: detachable READABLE_STRING_8 -- Contents of the Accept: header from the current request, if there is one. -- Example: 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' deferred end - http_accept_charset: detachable READABLE_STRING_32 + http_accept_charset: detachable READABLE_STRING_8 -- Contents of the Accept-Charset: header from the current request, if there is one. -- Example: 'iso-8859-1,*,utf-8'. deferred end - http_accept_encoding: detachable READABLE_STRING_32 + http_accept_encoding: detachable READABLE_STRING_8 -- Contents of the Accept-Encoding: header from the current request, if there is one. -- Example: 'gzip'. deferred end - http_accept_language: detachable READABLE_STRING_32 + http_accept_language: detachable READABLE_STRING_8 -- Contents of the Accept-Language: header from the current request, if there is one. -- Example: 'en'. deferred end - http_connection: detachable READABLE_STRING_32 + http_connection: detachable READABLE_STRING_8 -- Contents of the Connection: header from the current request, if there is one. -- Example: 'Keep-Alive'. deferred end - http_host: detachable READABLE_STRING_32 + http_host: detachable READABLE_STRING_8 -- Contents of the Host: header from the current request, if there is one. deferred end - http_referer: detachable READABLE_STRING_32 + http_referer: detachable READABLE_STRING_8 -- The address of the page (if any) which referred the user agent to the current page. -- This is set by the user agent. -- Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. @@ -559,7 +547,7 @@ feature -- HTTP_* deferred end - http_user_agent: detachable READABLE_STRING_32 + http_user_agent: detachable READABLE_STRING_8 -- Contents of the User-Agent: header from the current request, if there is one. -- This is a string denoting the user agent being which is accessing the page. -- A typical example is: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586). @@ -568,127 +556,23 @@ feature -- HTTP_* deferred end - http_authorization: detachable READABLE_STRING_32 + http_authorization: detachable READABLE_STRING_8 -- Contents of the Authorization: header from the current request, if there is one. deferred end feature -- Extra CGI environment variables - request_uri: READABLE_STRING_32 + request_uri: READABLE_STRING_8 -- The URI which was given in order to access this page; for instance, '/index.html'. deferred end - orig_path_info: detachable READABLE_STRING_32 + orig_path_info: detachable READABLE_STRING_8 -- Original version of `path_info' before processed by Current environment deferred end -feature -- Query string Parameters - - query_parameters: ITERABLE [WGI_VALUE] - -- Variables extracted from QUERY_STRING - deferred - end - - query_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE - -- Parameter for name `n'. - require - a_name_valid: a_name /= Void and then not a_name.is_empty - deferred - end - -feature -- Form fields and related - - form_data_parameters: ITERABLE [WGI_VALUE] - -- Variables sent by POST request - deferred - end - - form_data_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE - -- Field for name `a_name'. - require - a_name_valid: a_name /= Void and then not a_name.is_empty - deferred - end - - uploaded_files: HASH_TABLE [WGI_UPLOADED_FILE_DATA, READABLE_STRING_GENERAL] - -- Table of uploaded files information - --| name: original path from the user - --| type: content type - --| tmp_name: path to temp file that resides on server - --| tmp_base_name: basename of `tmp_name' - --| error: if /= 0 , there was an error : TODO ... - --| size: size of the file given by the http request - deferred - end - -feature -- Cookies - - cookies: ITERABLE [WGI_VALUE] - -- Expanded cookies variable - deferred - end - - cookie (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE - -- Field for name `a_name'. - require - a_name_valid: a_name /= Void and then not a_name.is_empty - deferred - end - -feature -- Access: all variables - - parameters: like items - obsolete "use items" - do - Result := items - end - - parameter (a_name: READABLE_STRING_GENERAL): like item - obsolete "use item" - do - Result := item (a_name) - end - - items: ITERABLE [WGI_VALUE] - -- Table containing all the various variables - -- Warning: this is computed each time, if you change the content of other containers - -- this won't update this Result's content, unless you query it again - deferred - end - - item (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE - -- Variable named `a_name' from any of the variables container - -- and following a specific order - -- execution, environment, get, post, cookies - require - a_name_valid: a_name /= Void and then not a_name.is_empty - deferred - end - -feature -- Uploaded File Handling - - is_uploaded_file (a_filename: READABLE_STRING_GENERAL): BOOLEAN - -- Is `a_filename' a file uploaded via HTTP POST - deferred - end - -feature -- URL Utility - - absolute_script_url (a_path: STRING): STRING - -- Absolute Url for the script if any, extended by `a_path' - deferred - end - - script_url (a_path: STRING): STRING - -- Url relative to script name if any, extended by `a_path' - require - a_path_attached: a_path /= Void - deferred - end - invariant server_name_not_empty: not server_name.is_empty server_port_set: server_port /= 0 diff --git a/library/server/ewsgi/src/extra/ewf_buffered_response.e b/library/server/ewsgi/src/extra/ewf_buffered_response.e deleted file mode 100644 index 123dd75a..00000000 --- a/library/server/ewsgi/src/extra/ewf_buffered_response.e +++ /dev/null @@ -1,186 +0,0 @@ -note - description: "Summary description for {EWF_BUFFERED_RESPONSE}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - EWF_BUFFERED_RESPONSE - -inherit - WGI_RESPONSE_BUFFER - -create {WGI_APPLICATION} - make - -feature {NONE} -- Initialization - - make (a_res: like response_buffer; a_buffer_size: INTEGER) - do - response_buffer := a_res - buffer_capacity := a_buffer_size - create buffer.make (a_buffer_size) - end - - response_buffer: WGI_RESPONSE_BUFFER - - buffer: STRING_8 - - buffer_capacity: INTEGER - - buffer_count: INTEGER - -feature {NONE} -- Core output operation - - write (s: STRING) - -- Send the content of `s' - local - buf: like buffer - len_b, len_s: INTEGER - do - buf := buffer - len_s := s.count - len_b := buffer_count - if len_b + len_s >= buffer_capacity then - flush_buffer - if len_s >= buffer_capacity then - -- replace buffer by `s' - buffer := s - buffer_count := len_s - flush_buffer - -- restore buffer with `buf' - buffer := buf - else - buf.append (s) - buffer_count := len_s - end - else - buf.append (s) - buffer_count := len_b + len_s - end - end - -feature -- Output operation - - flush - do - flush_buffer - end - -feature {NONE} -- Implementation - - flush_buffer - require - buffer_count_match_buffer: buffer_count = buffer.count - do - response_buffer.write (buffer) - buffer_count := 0 - ensure - buffer_flushed: buffer_count = 0 and buffer.count = 0 - end - -feature {WGI_APPLICATION} -- Commit - - commit - do - flush_buffer - end - -feature -- Status report - - header_committed: BOOLEAN - -- Header committed? - - message_committed: BOOLEAN - -- Message committed? - - message_writable: BOOLEAN - -- Can message be written? - do - Result := status_is_set and header_committed - end - -feature -- Status setting - - status_is_set: BOOLEAN - -- Is status set? - do - Result := status_code /= 0 - end - - set_status_code (a_code: INTEGER) - -- Set response status code - -- Should be done before sending any data back to the client - do - status_code := a_code - response_buffer.set_status_code (a_code) - end - - status_code: INTEGER - -- Response status - -feature -- Header output operation - - write_headers_string (a_headers: STRING) - do - write (a_headers) - header_committed := True - end - - write_header (a_status_code: INTEGER; a_headers: detachable ARRAY [TUPLE [key: STRING; value: STRING]]) - -- Send headers with status `a_status', and headers from `a_headers' - local - h: EWF_HEADER - i,n: INTEGER - do - set_status_code (a_status_code) - create h.make - h.put_status (a_status_code) - if a_headers /= Void then - from - i := a_headers.lower - n := a_headers.upper - until - i > n - loop - h.put_header_key_value (a_headers[i].key, a_headers[i].value) - i := i + 1 - end - end - write_headers_string (h.string) - end - -feature -- Output operation - - write_string (s: STRING) - -- Send the string `s' - do - write (s) - end - - write_substring (s: STRING; start_index, end_index: INTEGER) - -- Send the substring `start_index:end_index]' - --| Could be optimized according to the target output - do - flush_buffer - response_buffer.write_substring (s, start_index, end_index) - end - - write_file_content (fn: STRING) - -- Send the content of file `fn' - do - flush_buffer - response_buffer.write_file_content (fn) - end - -;note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/src/extra/in_memory/ewf_in_memory_response.e b/library/server/ewsgi/src/extra/in_memory/ewf_in_memory_response.e deleted file mode 100644 index d6688b0b..00000000 --- a/library/server/ewsgi/src/extra/in_memory/ewf_in_memory_response.e +++ /dev/null @@ -1,151 +0,0 @@ -note - description: "Summary description for {EWF_IN_MEMORY_RESPONSE}." - date: "$Date$" - revision: "$Revision$" - -class - EWF_IN_MEMORY_RESPONSE - -inherit - WGI_RESPONSE_BUFFER - -create {WGI_APPLICATION} - make - -feature {NONE} -- Initialization - - make (res: WGI_RESPONSE_BUFFER) - do - response_buffer := res - create header.make - create body.make (100) - end - - response_buffer: WGI_RESPONSE_BUFFER - - header: EWF_HEADER - - body: STRING_8 - -feature {WGI_APPLICATION} -- Commit - - commit - local - r: like response_buffer - do - r := response_buffer - r.set_status_code (status_code) - r.write_headers_string (header.string) - header_committed := True - r.write_string (body) - r.flush - end - -feature -- Status report - - header_committed: BOOLEAN - -- Header committed? - - message_committed: BOOLEAN - -- Message committed? - - message_writable: BOOLEAN - -- Can message be written? - do - Result := status_is_set and header_committed - end - - -feature -- Status setting - - status_is_set: BOOLEAN - -- Is status set? - do - Result := status_code /= 0 - end - - set_status_code (a_code: INTEGER) - -- Set response status code - -- Should be done before sending any data back to the client - do - status_code := a_code - end - - status_code: INTEGER - -- Response status - -feature {NONE} -- Status output - - write (s: STRING) - -- Send the content of `s' - do - body.append (s) - end - -feature -- Header output operation - - write_headers_string (a_headers: STRING) - do - write (a_headers) - header_committed := True - end - - write_header (a_status_code: INTEGER; a_headers: detachable ARRAY [TUPLE [key: STRING; value: STRING]]) - -- Send headers with status `a_status', and headers from `a_headers' - local - h: EWF_HEADER - i,n: INTEGER - do - set_status_code (a_status_code) - create h.make - if a_headers /= Void then - from - i := a_headers.lower - n := a_headers.upper - until - i > n - loop - h.put_header_key_value (a_headers[i].key, a_headers[i].value) - i := i + 1 - end - end - header := h - end - -feature -- Output operation - - write_string (s: STRING) - -- Send the string `s' - do - write (s) - end - - write_substring (s: STRING; start_index, end_index: INTEGER) - -- Send the substring `start_index:end_index]' - --| Could be optimized according to the target output - do - write_string (s.substring (start_index, end_index)) - end - - write_file_content (fn: STRING) - -- Send the content of file `fn' - do - response_buffer.write_file_content (fn) - end - - flush - do - --| Do nothing ... this is in_memory response - end - -;note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/src/extra/in_memory/ewf_in_memory_response_application.e b/library/server/ewsgi/src/extra/in_memory/ewf_in_memory_response_application.e deleted file mode 100644 index c1528e0c..00000000 --- a/library/server/ewsgi/src/extra/in_memory/ewf_in_memory_response_application.e +++ /dev/null @@ -1,59 +0,0 @@ -note - description: "Summary description for {EWF_IN_MEMORY_RESPONSE_APPLICATION}." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - EWF_IN_MEMORY_RESPONSE_APPLICATION - -inherit - WGI_APPLICATION - rename - execute as app_execute - end - - -feature -- Execution - - app_execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) - -- Execute the request - -- See `req.input' for input stream - -- `req.environment' for the Gateway environment - -- and `res' for output buffer - do - execute (req, new_response (req, res)) - end - -feature -- Execute - - execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) - -- Execute the request - -- See `req.input' for input stream - -- `req.environment' for the Gateway environment - -- and `res' for output buffer - require - res_status_unset: not res.status_is_set - deferred - ensure - res_status_set: res.status_is_set - end - -feature {NONE} -- Implementation - - new_response (req: WGI_REQUEST; a_res: WGI_RESPONSE_BUFFER): EWF_IN_MEMORY_RESPONSE - do - create {EWF_IN_MEMORY_RESPONSE} Result.make (a_res) - end - -note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/src/extra/response_as_result/wgi_response.e b/library/server/ewsgi/src/extra/response_as_result/wgi_response.e deleted file mode 100644 index 62cce845..00000000 --- a/library/server/ewsgi/src/extra/response_as_result/wgi_response.e +++ /dev/null @@ -1,226 +0,0 @@ -note - description: "[ - An EWSGI response. This may be used as is or specialized (subclassed) - if a developer wishes to reimplement their own version of the feature - 'read_message_body_block' for supporting a block-based message body - response. - ]" - author: "Paul Cohen " - status: "Draft" - -class WGI_RESPONSE - -create - make - -feature {NONE} -- Initialization - - make - -- Create new response object - do - is_buffered := False - ready_to_transmit := False - end_of_blocks := False - max_block_size := default_max_block_size - current_block := "" - create headers_table.make (10) - end - -feature {WGI_RESPONSE_APPLICATION} -- Response status - - transmit_to (res: WGI_RESPONSE_BUFFER) - do - res.set_status_code (status) - res.write_headers_string (headers) - from - read_block - res.write_string (last_block) --- res.flush - until - end_of_blocks - loop - read_block - res.write_string (last_block) --- res.flush - end - end - - ready_to_transmit: BOOLEAN - -- Is this response ready to be transmitted? - - set_ready_to_transmit - -- Set response to ready to transmit. - do - if is_buffered then - set_header ("Content-Length", current_block.count.out) --- elseif tmp_file /= Void then --- if tmp_file.is_open_write then --- tmp_file.close --- set_header ("Content-Length", tmp_file.count.out) --- end - end - ready_to_transmit := True - ensure - ready_to_transmit - end - -feature {WGI_RESPONSE_APPLICATION} -- Message start line and status - - status: INTEGER - -- HTTP status code - - set_status (s: INTEGER) - -- Set 'status_code'. - do - status := s - set_header ("Status", s.out) - ensure - status = s - end - - start_line: STRING - -- HTTP message start-line - do - if attached status as st then - Result := "HTTP/1.1 " + st.out + " " + status_text (st) + crlf - else - Result := "HTTP/1.1 200 " + status_text (200) + crlf - end - end - -feature {WGI_RESPONSE_APPLICATION} -- Message headers - - headers: STRING - -- HTTP message headers including trailing empty line. - local - t: HASH_TABLE [STRING, STRING] - do - Result := "" - t := headers_table - from - t.start - until - t.after - loop - Result.append (t.key_for_iteration + ": " + t.item_for_iteration + crlf) - t.forth - end - Result.append (crlf) - end - - headers_table: HASH_TABLE [STRING, STRING] - -- Hash table of HTTP headers - - set_header (key, value: STRING) - -- Set the HTTP header with the given 'key' to the given 'value'. - do - headers_table.put (value, key) - ensure - headers_table.has (key) and headers_table @ key = value - end - -feature {WGI_RESPONSE_APPLICATION} -- Message body - - read_block - -- Read a message body block. - do - if is_buffered then - end_of_blocks := True --- else --- -- File based block-based output --- -- TBD! - end - ensure ---Commented, since it is far from obvious to ensure that: --- not is_buffered implies last_block.count <= max_block_size - end - - last_block: STRING - -- Last message body block that has been read. - do - Result := current_block - end - - is_buffered: BOOLEAN - -- Is the entire entity body buffered in memory (STRING)? - - end_of_blocks: BOOLEAN - -- Has the last of the entity body blocks been read? - - set_message_body (s: STRING) - -- Set the message body to 's'. Use this for when you want a memory - -- buffered response. - do - current_block := s - is_buffered := True - set_ready_to_transmit - ensure - is_buffered - ready_to_transmit - last_block.is_equal (s) - end - - max_block_size: INTEGER - -- Maximum block size returned by message body if not buffered - - set_max_block_size (block_size: INTEGER) - -- Set 'max_block_size'. - do - max_block_size := block_size - ensure - max_block_size = block_size - end - --- write_message_block (s: STRING) --- -- Write message body block 's' to a temporary file. Us this when --- -- you want a non-buffered response. --- require --- not is_buffered --- do --- -- TBD! --- ensure --- not is_buffered --- not ready_to_transmit --- end - -feature {NONE} -- Implementation - --- tmp_file_name: STRING - --- tmp_file: detachable FILE --- -- Created with mktmp - --- position: INTEGER --- -- Current read position in tmp_file - - current_block: STRING - -- Current message body block - - default_max_block_size: INTEGER = 65536 - -- Default value of 'max_block_size' - - crlf: STRING = "%/13/%/10/" - - status_text (code: INTEGER): STRING - do - inspect code - when 500 then - Result := "Internal Server Error" - when 200 then - Result := "OK" - else - Result := "Code " + code.out - end - end - -note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/src/extra/response_as_result/wgi_response_application.e b/library/server/ewsgi/src/extra/response_as_result/wgi_response_application.e deleted file mode 100644 index aad8bf91..00000000 --- a/library/server/ewsgi/src/extra/response_as_result/wgi_response_application.e +++ /dev/null @@ -1,56 +0,0 @@ -note - description: "Summary description for {WGI_RESPONSE_APPLICATION} " - legal: "See notice at end of class." - status: "See notice at end of class." - date: "$Date$" - revision: "$Revision$" - -deferred class - WGI_RESPONSE_APPLICATION - -feature -- Execution - - execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) - -- Execute the request - -- See `req.input' for input stream - -- `req.environment' for the Gateway environment - -- and `res.output' for output stream - local - rs: WGI_RESPONSE - do - rs := response (req) - if rs.ready_to_transmit then - rs.transmit_to (res) - else - -- Report internal server error. - -- Response not ready to transmit! - -- Implementor of WGI_APPLICATION has not done his job! - create rs.make - rs.set_status (500) - rs.set_header ("Content-Type", "text/plain") - rs.set_message_body ("Incomplete server implementation: Response not ready to transmit.%NTell the programmer to finish his/her job!") - rs.transmit_to (res) - end - end - -feature -- Response - - response (request: WGI_REQUEST): WGI_RESPONSE - -- HTTP response for given 'request'. - deferred - ensure - ready_to_transmit: Result.ready_to_transmit - end - -;note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" - -end diff --git a/library/server/ewsgi/src/helper/wgi_request_from_table.e b/library/server/ewsgi/src/helper/wgi_request_from_table.e new file mode 100644 index 00000000..a39b1c12 --- /dev/null +++ b/library/server/ewsgi/src/helper/wgi_request_from_table.e @@ -0,0 +1,412 @@ +note + description: "[ + Request instanciated from a hash_table of meta variables + ]" + specification: "EWSGI specification https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki/EWSGI-specification" + legal: "See notice at end of class." + status: "See notice at end of class." + date: "$Date$" + revision: "$Revision$" + +class + WGI_REQUEST_FROM_TABLE + +inherit + WGI_REQUEST + +create + make + +feature {NONE} -- Initialization + + make (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]; a_input: like input) + require + vars_attached: a_vars /= Void + do + input := a_input + set_meta_variables (a_vars) + + update_path_info + end + +feature -- Access: Input + + input: WGI_INPUT_STREAM + -- Server input channel + +feature -- Access: CGI meta parameters + + meta_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] + -- CGI Environment parameters + + meta_variable (a_name: READABLE_STRING_8): detachable READABLE_STRING_8 + -- CGI meta variable related to `a_name' + do + Result := meta_variables.item (a_name) + end + + meta_string_variable_or_default (a_name: READABLE_STRING_8; a_default: READABLE_STRING_8; use_default_when_empty: BOOLEAN): READABLE_STRING_8 + -- Value for meta parameter `a_name' + -- If not found, return `a_default' + require + a_name_not_empty: a_name /= Void and then not a_name.is_empty + do + if attached meta_variable (a_name) as val then + Result := val.string + if use_default_when_empty and then Result.is_empty then + Result := a_default + end + else + Result := a_default + end + end + + set_meta_string_variable (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8) + do + meta_variables.force (a_value, a_name) + ensure + param_set: attached meta_variable (a_name) as val and then val ~ a_value + end + + unset_meta_variable (a_name: READABLE_STRING_8) + do + meta_variables.remove (a_name) + ensure + param_unset: meta_variable (a_name) = Void + end + +feature -- Access: CGI meta parameters - 1.1 + + auth_type: detachable READABLE_STRING_8 + + content_length: detachable READABLE_STRING_8 + + content_type: detachable READABLE_STRING_8 + + gateway_interface: READABLE_STRING_8 + do + Result := meta_string_variable_or_default ({WGI_META_NAMES}.gateway_interface, "", False) + end + + path_info: READABLE_STRING_8 + -- + -- + --| For instance, if the current script was accessed via the URL + --| http://www.example.com/eiffel/path_info.exe/some/stuff?foo=bar, then $_SERVER['PATH_INFO'] would contain /some/stuff. + --| + --| Note that is the PATH_INFO variable does not exists, the `path_info' value will be empty + + path_translated: detachable READABLE_STRING_8 + do + Result := meta_string_variable ({WGI_META_NAMES}.path_translated) + end + + query_string: READABLE_STRING_8 + + remote_addr: READABLE_STRING_8 + + remote_host: READABLE_STRING_8 + + remote_ident: detachable READABLE_STRING_8 + do + Result := meta_string_variable ({WGI_META_NAMES}.remote_ident) + end + + remote_user: detachable READABLE_STRING_8 + do + Result := meta_string_variable ({WGI_META_NAMES}.remote_user) + end + + request_method: READABLE_STRING_8 + + script_name: READABLE_STRING_8 + + server_name: READABLE_STRING_8 + + server_port: INTEGER + + server_protocol: READABLE_STRING_8 + do + Result := meta_string_variable_or_default ({WGI_META_NAMES}.server_protocol, "HTTP/1.0", True) + end + + server_software: READABLE_STRING_8 + do + Result := meta_string_variable_or_default ({WGI_META_NAMES}.server_software, "Unknown Server", True) + end + +feature -- Access: HTTP_* CGI meta parameters - 1.1 + + http_accept: detachable READABLE_STRING_8 + -- Contents of the Accept: header from the current request, if there is one. + do + Result := meta_string_variable ({WGI_META_NAMES}.http_accept) + end + + http_accept_charset: detachable READABLE_STRING_8 + -- Contents of the Accept-Charset: header from the current request, if there is one. + -- Example: 'iso-8859-1,*,utf-8'. + do + Result := meta_string_variable ({WGI_META_NAMES}.http_accept_charset) + end + + http_accept_encoding: detachable READABLE_STRING_8 + -- Contents of the Accept-Encoding: header from the current request, if there is one. + -- Example: 'gzip'. + do + Result := meta_string_variable ({WGI_META_NAMES}.http_accept_encoding) + end + + http_accept_language: detachable READABLE_STRING_8 + -- Contents of the Accept-Language: header from the current request, if there is one. + -- Example: 'en'. + do + Result := meta_string_variable ({WGI_META_NAMES}.http_accept_language) + end + + http_connection: detachable READABLE_STRING_8 + -- Contents of the Connection: header from the current request, if there is one. + -- Example: 'Keep-Alive'. + do + Result := meta_string_variable ({WGI_META_NAMES}.http_connection) + end + + http_host: detachable READABLE_STRING_8 + -- Contents of the Host: header from the current request, if there is one. + do + Result := meta_string_variable ({WGI_META_NAMES}.http_host) + end + + http_referer: detachable READABLE_STRING_8 + -- The address of the page (if any) which referred the user agent to the current page. + -- This is set by the user agent. + -- Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. + -- In short, it cannot really be trusted. + do + Result := meta_string_variable ({WGI_META_NAMES}.http_referer) + end + + http_user_agent: detachable READABLE_STRING_8 + -- Contents of the User-Agent: header from the current request, if there is one. + -- This is a string denoting the user agent being which is accessing the page. + -- A typical example is: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586). + -- Among other things, you can use this value to tailor your page's + -- output to the capabilities of the user agent. + do + Result := meta_string_variable ({WGI_META_NAMES}.http_user_agent) + end + + http_authorization: detachable READABLE_STRING_8 + -- Contents of the Authorization: header from the current request, if there is one. + do + Result := meta_string_variable ({WGI_META_NAMES}.http_authorization) + end + +feature -- Access: Extension to CGI meta parameters - 1.1 + + request_uri: READABLE_STRING_8 + -- The URI which was given in order to access this page; for instance, '/index.html'. + + orig_path_info: detachable READABLE_STRING_8 + -- Original version of `path_info' before processed by Current environment + +feature {NONE} -- Element change: CGI meta parameter related to PATH_INFO + + set_meta_variables (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]) + -- Fill with variable from `a_vars' + local + s: like meta_string_variable + table: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] + l_query_string: like query_string + l_request_uri: detachable STRING_32 + do + create {STRING_8} empty_string.make_empty + + create table.make (a_vars.count) + table.compare_objects + meta_variables := table + from + a_vars.start + until + a_vars.after + loop + table.force (a_vars.item_for_iteration, a_vars.key_for_iteration) + a_vars.forth + end + + --| QUERY_STRING + l_query_string := meta_string_variable_or_default ({WGI_META_NAMES}.query_string, empty_string, False) + query_string := l_query_string + + --| REQUEST_METHOD + request_method := meta_string_variable_or_default ({WGI_META_NAMES}.request_method, empty_string, False) + + --| CONTENT_TYPE + s := meta_string_variable ({WGI_META_NAMES}.content_type) + if s /= Void and then not s.is_empty then + content_type := s + else + content_type := Void + end + + --| CONTENT_LENGTH + content_length := meta_string_variable ({WGI_META_NAMES}.content_length) + + --| PATH_INFO + path_info := meta_string_variable_or_default ({WGI_META_NAMES}.path_info, empty_string, False) + + --| SERVER_NAME + server_name := meta_string_variable_or_default ({WGI_META_NAMES}.server_name, empty_string, False) + + --| SERVER_PORT + s := meta_string_variable ({WGI_META_NAMES}.server_port) + if s /= Void and then s.is_integer then + server_port := s.to_integer + else + server_port := 80 + end + + --| SCRIPT_NAME + script_name := meta_string_variable_or_default ({WGI_META_NAMES}.script_name, empty_string, False) + + --| REMOTE_ADDR + remote_addr := meta_string_variable_or_default ({WGI_META_NAMES}.remote_addr, empty_string, False) + + --| REMOTE_HOST + remote_host := meta_string_variable_or_default ({WGI_META_NAMES}.remote_host, empty_string, False) + + --| REQUEST_URI + s := meta_string_variable ({WGI_META_NAMES}.request_uri) + if s /= Void then + l_request_uri := s + else + --| It might occur that REQUEST_URI is not available, so let's compute it from SCRIPT_NAME + create l_request_uri.make_from_string (script_name) + if not l_query_string.is_empty then + l_request_uri.append_character ('?') + l_request_uri.append (l_query_string) + end + end + request_uri := single_slash_starting_string (l_request_uri) + end + + set_orig_path_info (s: READABLE_STRING_8) + -- Set ORIG_PATH_INFO to `s' + require + s_attached: s /= Void + do + orig_path_info := s + set_meta_string_variable ({WGI_META_NAMES}.orig_path_info, s) + end + + unset_orig_path_info + -- Unset ORIG_PATH_INFO + do + orig_path_info := Void + unset_meta_variable ({WGI_META_NAMES}.orig_path_info) + ensure + unset: attached meta_variable ({WGI_META_NAMES}.orig_path_info) + end + + update_path_info + -- Fix and update PATH_INFO value if needed + local + l_path_info: STRING + do + l_path_info := path_info + --| Warning + --| on IIS: we might have PATH_INFO = /sample.exe/foo/bar + --| on apache: PATH_INFO = /foo/bar + --| So, we might need to check with SCRIPT_NAME and remove it on IIS + --| store original PATH_INFO in ORIG_PATH_INFO + if l_path_info.is_empty then + unset_orig_path_info + else + set_orig_path_info (l_path_info) + if attached script_name as l_script_name then + if l_path_info.starts_with (l_script_name) then + path_info := l_path_info.substring (l_script_name.count + 1 , l_path_info.count) + end + end + end + end + +feature {NONE} -- I/O: implementation + + read_input (nb: INTEGER) + -- Read `nb' bytes from `input' + do + input.read_stream (nb) + end + + last_input_string: STRING + -- Last string read from `input' + do + Result := input.last_string + end + +feature {NONE} -- Implementation: utilities + + single_slash_starting_string (s: READABLE_STRING_8): STRING_8 + -- Return the string `s' (or twin) with one and only one starting slash + local + i, n: INTEGER + do + n := s.count + if n > 1 then + if s[1] /= '/' then + create Result.make (1 + n) + Result.append_character ('/') + Result.append (s) + elseif s[2] = '/' then + --| We need to remove all starting slash, except one + from + i := 3 + until + i > n + loop + if s[i] /= '/' then + n := 0 --| exit loop + else + i := i + 1 + end + end + n := s.count + check i >= 2 and i <= n end + Result := s.substring (i - 1, s.count) + else + --| starts with one '/' and only one + Result := s + end + elseif n = 1 then + if s[1] = '/' then + Result := s + else + create Result.make (2) + Result.append_character ('/') + Result.append (s) + end + else --| n = 0 + create Result.make_filled ('/', 1) + end + ensure + one_starting_slash: Result[1] = '/' and (Result.count = 1 or else Result[2] /= '/') + end + + empty_string: READABLE_STRING_8 + -- Reusable empty string + +invariant + empty_string_unchanged: empty_string.is_empty + +note + copyright: "2011-2011, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/library/server/ewsgi/src/wgi_response_stream_buffer.e b/library/server/ewsgi/src/helper/wgi_response_stream_buffer.e similarity index 100% rename from library/server/ewsgi/src/wgi_response_stream_buffer.e rename to library/server/ewsgi/src/helper/wgi_response_stream_buffer.e diff --git a/library/server/ewsgi/src/wgi_application.e b/library/server/ewsgi/src/wgi_application.e index e7c1849c..58df970f 100644 --- a/library/server/ewsgi/src/wgi_application.e +++ b/library/server/ewsgi/src/wgi_application.e @@ -25,43 +25,7 @@ feature -- Execution res_status_set: res.status_is_set end -feature -- Process request - - frozen process (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) - -- Process request with environment `env', and i/o streams `a_input' and `a_output' - local - rescued: BOOLEAN - do - if not rescued then - request_count := request_count + 1 - execute (req, res) - else - rescue_execute (req, res, (create {EXCEPTION_MANAGER}).last_exception) - end - if res /= Void then - res.commit - end - end - -feature -- Access - - request_count: INTEGER - -- Request count - -feature {NONE} -- Execution - - rescue_execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_exception: detachable EXCEPTION) - -- Operation processed on rescue of `execute' - do - if - a_exception /= Void and then attached a_exception.exception_trace as l_trace - then - res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void) - res.write_string ("
" + l_trace + "
") - end - end - -;note +note copyright: "2011-2011, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ diff --git a/library/server/request/rest/rest-safe.ecf b/library/server/request/rest/rest-safe.ecf index a6865a9a..ad2cfd15 100644 --- a/library/server/request/rest/rest-safe.ecf +++ b/library/server/request/rest/rest-safe.ecf @@ -7,12 +7,13 @@ /\.git$ /\.svn$ - - + - + /html$ diff --git a/library/server/request/rest/rest.ecf b/library/server/request/rest/rest.ecf index 0c5c4034..502bf28f 100644 --- a/library/server/request/rest/rest.ecf +++ b/library/server/request/rest/rest.ecf @@ -9,7 +9,7 @@
@@ -42,7 +42,7 @@ - + diff --git a/library/server/request/rest/tests/src/app/app_account_verify_credential.e b/library/server/request/rest/tests/src/app/app_account_verify_credential.e index 3161dff7..419aceea 100644 --- a/library/server/request/rest/tests/src/app/app_account_verify_credential.e +++ b/library/server/request/rest/tests/src/app/app_account_verify_credential.e @@ -35,14 +35,14 @@ feature {NONE} -- Initialization feature -- Access - authentication_required (req: WGI_REQUEST): BOOLEAN + authentication_required (req: WSF_REQUEST): BOOLEAN do Result := True end feature -- Execution - execute_unauthorized (a_hdl_context: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_unauthorized (a_hdl_context: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) local s: STRING lst: LIST [STRING] @@ -52,16 +52,16 @@ feature -- Execution res.write_string ("Unauthorized") end - execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) local l_full: BOOLEAN - h: EWF_HEADER + h: WSF_HEADER l_login: STRING_8 s: STRING content_type_supported: ARRAY [STRING] l_format_id: INTEGER do - content_type_supported := <<{HTTP_CONSTANTS}.json_app, {HTTP_CONSTANTS}.xml_text, {HTTP_CONSTANTS}.plain_text>> + content_type_supported := <<{HTTP_CONSTANTS}.application_json, {HTTP_CONSTANTS}.text_xml, {HTTP_CONSTANTS}.text_plain>> l_format_id := ctx.request_format_id ("format", content_type_supported) if authenticated (ctx) then l_full := attached ctx.query_parameter ("details") as v and then v.is_case_insensitive_equal ("true") diff --git a/library/server/request/rest/tests/src/app/app_test.e b/library/server/request/rest/tests/src/app/app_test.e index 1b54ae5e..99aa4ba7 100644 --- a/library/server/request/rest/tests/src/app/app_test.e +++ b/library/server/request/rest/tests/src/app/app_test.e @@ -32,17 +32,17 @@ feature {NONE} -- Initialization feature -- Access - authentication_required (req: WGI_REQUEST): BOOLEAN + authentication_required (req: WSF_REQUEST): BOOLEAN do end feature -- Execution - execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler local s: STRING - h: EWF_HEADER + h: WSF_HEADER do create h.make h.put_content_type_text_plain diff --git a/library/server/request/rest/tests/src/app_server.e b/library/server/request/rest/tests/src/app_server.e index 0da1ce72..7e497c0b 100644 --- a/library/server/request/rest/tests/src/app_server.e +++ b/library/server/request/rest/tests/src/app_server.e @@ -68,17 +68,17 @@ feature {NONE} -- Handlers feature -- Execution - execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute (req: WSF_REQUEST; res: WSF_RESPONSE) do request_count := request_count + 1 Precursor (req, res) end - execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) local rqst_uri: detachable STRING l_path_info: detachable STRING - h: EWF_HEADER + h: WSF_HEADER s: STRING l_redir_url: STRING do @@ -96,6 +96,8 @@ feature -- Execution res.write_string (s) end + request_count: INTEGER + -- execute_rescue (ctx: like new_request_context) -- -- Execute the default rescue behavior -- do @@ -106,7 +108,7 @@ feature -- Implementation -- execute_exception_trace (ctx: like new_request_context) -- local --- h: EWF_HEADER +-- h: WSF_HEADER -- s: STRING -- do -- create h.make @@ -121,7 +123,7 @@ feature -- Implementation -- exit_with_code (-1) -- end - execute_exit_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_exit_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) local s: STRING do diff --git a/library/server/request/rest/tests/src/gateway/cgi/rest_application_gateway.e b/library/server/request/rest/tests/src/gateway/cgi/rest_application_gateway.e index ab7b0997..17460d10 100644 --- a/library/server/request/rest/tests/src/gateway/cgi/rest_application_gateway.e +++ b/library/server/request/rest/tests/src/gateway/cgi/rest_application_gateway.e @@ -2,17 +2,17 @@ deferred class REST_APPLICATION_GATEWAY inherit - WGI_APPLICATION + WSF_APPLICATION feature -- Access build_gateway_and_launch local - cgi: EWF_CGI_CONNECTOR + cgi: WGI_CGI_CONNECTOR do create cgi.make (Current) cgi.launch - end + end gateway_name: STRING = "CGI" @@ -20,5 +20,5 @@ feature -- Access do (create {EXCEPTIONS}).die (a_code) end - + end diff --git a/library/server/request/rest/tests/src/gateway/fcgi/rest_application_gateway.e b/library/server/request/rest/tests/src/gateway/fcgi/rest_application_gateway.e index f78f80e8..e60c9fed 100644 --- a/library/server/request/rest/tests/src/gateway/fcgi/rest_application_gateway.e +++ b/library/server/request/rest/tests/src/gateway/fcgi/rest_application_gateway.e @@ -2,13 +2,13 @@ deferred class REST_APPLICATION_GATEWAY inherit - WGI_APPLICATION + WSF_APPLICATION feature -- Access build_gateway_and_launch local - libfcgi: EWF_LIBFCGI_CONNECTOR + libfcgi: WGI_LIBFCGI_CONNECTOR do create libfcgi.make (Current) libfcgi.launch diff --git a/library/server/request/rest/tests/src/gateway/nino/rest_application_gateway.e b/library/server/request/rest/tests/src/gateway/nino/rest_application_gateway.e index af955abd..34bf8341 100644 --- a/library/server/request/rest/tests/src/gateway/nino/rest_application_gateway.e +++ b/library/server/request/rest/tests/src/gateway/nino/rest_application_gateway.e @@ -2,7 +2,7 @@ deferred class REST_APPLICATION_GATEWAY inherit - WGI_APPLICATION + WSF_APPLICATION feature -- Access @@ -18,7 +18,7 @@ feature -- Access print ("Example: start a Nino web server on port " + port_number.out + ", %Nand reply Hello World for any request such as http://localhost:" + port_number.out + "/" + base_url + "%N") end - create app.make_custom (agent execute, base_url) + create app.make_custom (agent wgi_execute, base_url) app.force_single_threaded app.listen (port_number) diff --git a/library/server/request/rest/tests/src/handler/app_request_handler.e b/library/server/request/rest/tests/src/handler/app_request_handler.e index 1c5e8116..158c730b 100644 --- a/library/server/request/rest/tests/src/handler/app_request_handler.e +++ b/library/server/request/rest/tests/src/handler/app_request_handler.e @@ -23,7 +23,7 @@ feature {NONE} -- Initialization feature {NONE} -- Implementation - wgi_value_iteration_to_string (v: ITERABLE [WGI_VALUE]; using_pre: BOOLEAN): STRING_8 + wgi_value_iteration_to_string (v: ITERABLE [WSF_VALUE]; using_pre: BOOLEAN): STRING_8 do create Result.make (100) if using_pre then diff --git a/library/server/request/rest/tests/src/handler/app_request_handler_context.e b/library/server/request/rest/tests/src/handler/app_request_handler_context.e index 76b703a0..45ae824f 100644 --- a/library/server/request/rest/tests/src/handler/app_request_handler_context.e +++ b/library/server/request/rest/tests/src/handler/app_request_handler_context.e @@ -16,14 +16,14 @@ create feature -- Format - get_format_id (a_format_variable_name: detachable READABLE_STRING_GENERAL; a_content_type_supported: detachable ARRAY [STRING_8]) + get_format_id (a_format_variable_name: detachable READABLE_STRING_8; a_content_type_supported: detachable ARRAY [STRING_8]) do if internal_format_id = 0 then internal_format_id := request_format_id (a_format_variable_name, a_content_type_supported) end end - get_format_name (a_format_variable_name: detachable READABLE_STRING_GENERAL; a_content_type_supported: detachable ARRAY [STRING_8]) + get_format_name (a_format_variable_name: detachable READABLE_STRING_8; a_content_type_supported: detachable ARRAY [STRING_8]) do if internal_format_name = Void then internal_format_name := request_format (a_format_variable_name, a_content_type_supported) diff --git a/library/server/request/rest/tests/src/handler/app_request_helper.e b/library/server/request/rest/tests/src/handler/app_request_helper.e index 77cde314..f4d2ed7f 100644 --- a/library/server/request/rest/tests/src/handler/app_request_helper.e +++ b/library/server/request/rest/tests/src/handler/app_request_helper.e @@ -9,7 +9,7 @@ deferred class feature -- Helpers - send_error (a_path: STRING; a_error_id: INTEGER; a_error_name: STRING; a_error_message: detachable STRING; ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + send_error (a_path: STRING; a_error_id: INTEGER; a_error_name: STRING; a_error_message: detachable STRING; ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) local s: STRING i,nb: INTEGER diff --git a/library/server/request/router/router-safe.ecf b/library/server/request/router/router-safe.ecf index f7aff5b6..dc39ca12 100644 --- a/library/server/request/router/router-safe.ecf +++ b/library/server/request/router/router-safe.ecf @@ -12,7 +12,7 @@ - + @@ -29,7 +29,7 @@ - + diff --git a/library/server/request/router/router.ecf b/library/server/request/router/router.ecf index 93fae79f..664d0879 100644 --- a/library/server/request/router/router.ecf +++ b/library/server/request/router/router.ecf @@ -12,7 +12,7 @@ - + @@ -29,7 +29,7 @@ - + diff --git a/library/server/request/router/src/misc/request_format_utility.e b/library/server/request/router/src/misc/request_format_utility.e index b5914a49..ca0dd7ab 100644 --- a/library/server/request/router/src/misc/request_format_utility.e +++ b/library/server/request/router/src/misc/request_format_utility.e @@ -9,19 +9,16 @@ class feature -- Access - accepted_content_types (req: WGI_REQUEST): detachable ARRAYED_LIST [READABLE_STRING_8] + accepted_content_types (req: WSF_REQUEST): detachable ARRAYED_LIST [READABLE_STRING_8] local - l_accept: detachable READABLE_STRING_32 s: STRING_8 q: READABLE_STRING_8 p: INTEGER lst: LIST [READABLE_STRING_8] qs: QUICK_SORTER [READABLE_STRING_8] do - l_accept := req.http_accept ---TEST l_accept := "text/html,application/xhtml+xml;q=0.6,application/xml;q=0.2,text/plain;q=0.5,*/*;q=0.8" - - if l_accept /= Void then +--TEST if attached ("text/html,application/xhtml+xml;q=0.6,application/xml;q=0.2,text/plain;q=0.5,*/*;q=0.8") as l_accept then + if attached req.http_accept as l_accept then lst := l_accept.as_string_8.split (',') create Result.make (lst.count) from diff --git a/library/server/request/router/src/misc/request_resource_handler_helper.e b/library/server/request/router/src/misc/request_resource_handler_helper.e index c852085c..9741111d 100644 --- a/library/server/request/router/src/misc/request_resource_handler_helper.e +++ b/library/server/request/router/src/misc/request_resource_handler_helper.e @@ -9,7 +9,7 @@ class feature -- Execute template - execute_methods (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_methods (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request and dispatch according to the request method local m: READABLE_STRING_8 @@ -41,7 +41,7 @@ feature -- Execute template feature -- Method Post - execute_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do if req.content_length_value > 0 then do_post (ctx, req, res) @@ -50,14 +50,14 @@ feature -- Method Post end end - do_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do handle_not_implemented ("Method POST not implemented", ctx, req, res) end feature-- Method Put - execute_put (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_put (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do if req.content_length_value > 0 then do_put (ctx, req, res) @@ -66,91 +66,91 @@ feature-- Method Put end end - do_put (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_put (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do handle_not_implemented ("Method PUT not implemented", ctx, req, res) end feature -- Method Get - execute_get (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_get (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do do_get (ctx, req, res) end - do_get (ctx: C;req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_get (ctx: C;req: WSF_REQUEST; res: WSF_RESPONSE) do handle_not_implemented ("Method HEAD not implemented", ctx, req, res) end feature -- Method DELETE - execute_delete (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_delete (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do do_delete (ctx, req, res) end - do_delete (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_delete (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do handle_not_implemented ("Method DELETE not implemented", ctx, req, res) end feature -- Method CONNECT - execute_connect (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_connect (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do do_connect (ctx, req, res) end - do_connect (ctx: C;req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_connect (ctx: C;req: WSF_REQUEST; res: WSF_RESPONSE) do handle_not_implemented ("Method CONNECT not implemented", ctx, req, res) end feature -- Method HEAD - execute_head (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_head (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do do_head (ctx, req, res) end - do_head (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_head (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do handle_not_implemented ("Method HEAD not implemented", ctx, req, res) end feature -- Method OPTIONS - execute_options (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_options (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do do_options (ctx, req, res) end - do_options (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_options (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do handle_not_implemented ("Method OPTIONS not implemented", ctx, req, res) end feature -- Method TRACE - execute_trace (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_trace (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do do_trace (ctx, req, res) end - do_trace (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_trace (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do handle_not_implemented ("Method TRACE not implemented", ctx, req, res) end feature -- Method Extension Method - execute_extension_method (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_extension_method (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do do_extension_method (ctx, req, res) end - do_extension_method (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do_extension_method (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do handle_not_implemented ("Method extension-method not implemented", ctx, req, res) end @@ -164,9 +164,9 @@ feature -- Handle responses Result := Void end - handle_bad_request_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER ) + handle_bad_request_response (a_description:STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE ) local - h : EWF_HEADER + h : WSF_HEADER do create h.make h.put_status ({HTTP_STATUS_CODE}.bad_request) @@ -183,9 +183,9 @@ feature -- Handle responses end - handle_precondition_fail_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER ) + handle_precondition_fail_response (a_description:STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE ) local - h : EWF_HEADER + h : WSF_HEADER do create h.make h.put_status ({HTTP_STATUS_CODE}.precondition_failed) @@ -201,9 +201,9 @@ feature -- Handle responses res.write_string (a_description) end - handle_internal_server_error (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER ) + handle_internal_server_error (a_description:STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE ) local - h : EWF_HEADER + h : WSF_HEADER do create h.make h.put_status ({HTTP_STATUS_CODE}.internal_server_error) @@ -221,9 +221,9 @@ feature -- Handle responses res.write_string (a_description) end - handle_not_implemented (a_description: STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER ) + handle_not_implemented (a_description: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE ) local - h : EWF_HEADER + h : WSF_HEADER do create h.make h.put_status ({HTTP_STATUS_CODE}.not_implemented) @@ -239,9 +239,9 @@ feature -- Handle responses res.write_string (a_description) end - handle_method_not_allowed_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER ) + handle_method_not_allowed_response (a_description:STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) local - h : EWF_HEADER + h : WSF_HEADER do create h.make h.put_status ({HTTP_STATUS_CODE}.method_not_allowed) @@ -256,9 +256,10 @@ feature -- Handle responses res.write_headers_string (h.string) res.write_string (a_description) end - handle_resource_not_found_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + + handle_resource_not_found_response (a_description:STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) local - h : EWF_HEADER + h : WSF_HEADER do create h.make h.put_status ({HTTP_STATUS_CODE}.not_found) @@ -275,9 +276,9 @@ feature -- Handle responses end - handle_resource_not_modified_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + handle_resource_not_modified_response (a_description:STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) local - h : EWF_HEADER + h : WSF_HEADER do res.flush create h.make @@ -295,9 +296,9 @@ feature -- Handle responses end - handle_resource_conflict_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + handle_resource_conflict_response (a_description:STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) local - h : EWF_HEADER + h : WSF_HEADER do create h.make h.put_status ({HTTP_STATUS_CODE}.conflict) diff --git a/library/server/request/router/src/misc/routed_application_helper.e b/library/server/request/router/src/misc/routed_application_helper.e index ce36ac54..681c3f5d 100644 --- a/library/server/request/router/src/misc/routed_application_helper.e +++ b/library/server/request/router/src/misc/routed_application_helper.e @@ -12,7 +12,7 @@ inherit feature -- Helper - execute_content_type_not_allowed (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_content_types: detachable ARRAY [STRING]; a_uri_formats: detachable ARRAY [STRING]) + execute_content_type_not_allowed (req: WSF_REQUEST; res: WSF_RESPONSE; a_content_types: detachable ARRAY [STRING]; a_uri_formats: detachable ARRAY [STRING]) local accept_s, uri_s: detachable STRING i, n: INTEGER @@ -62,7 +62,7 @@ feature -- Helper end end - execute_request_method_not_allowed (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_methods: ITERABLE [STRING]) + execute_request_method_not_allowed (req: WSF_REQUEST; res: WSF_RESPONSE; a_methods: ITERABLE [STRING]) local s: STRING do diff --git a/library/server/request/router/src/request_agent_handler.e b/library/server/request/router/src/request_agent_handler.e index 66704ece..87365d7e 100644 --- a/library/server/request/router/src/request_agent_handler.e +++ b/library/server/request/router/src/request_agent_handler.e @@ -22,11 +22,11 @@ feature -- Initialization feature -- Access - action: PROCEDURE [ANY, TUPLE [ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]] + action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]] feature -- Execution - execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do action.call ([ctx, req, res]) end diff --git a/library/server/request/router/src/request_file_system_handler.e b/library/server/request/router/src/request_file_system_handler.e new file mode 100644 index 00000000..86865253 --- /dev/null +++ b/library/server/request/router/src/request_file_system_handler.e @@ -0,0 +1,335 @@ +note + description: "[ + Request handler used to respond file system request. + ]" + date: "$Date$" + revision: "$Revision$" + +class + REQUEST_FILE_SYSTEM_HANDLER [C -> REQUEST_HANDLER_CONTEXT] + +inherit + REQUEST_HANDLER [C] + +create + make + +feature {NONE} -- Initialization + + make (a_root: READABLE_STRING_8) + require + a_root_exists: node_exists (a_root) + do + document_root := a_root + end + +feature -- Access + + document_root: READABLE_STRING_8 + -- Document root for the file system + + directory_index: detachable ARRAY [READABLE_STRING_8] + -- File serve if a directory index is requested + +feature -- Element change + + set_directory_index (idx: like directory_index) + -- Set `directory_index' as `idx' + do + if idx = Void or else idx.is_empty then + directory_index := Void + else + directory_index := idx + end + end + +feature -- Execution + + execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + local + h: WSF_HEADER + s: STRING + uri: STRING + do + if attached ctx.path_parameter ("path") as l_path then + uri := l_path.as_string + process_uri (uri, ctx, req, res) + else + create h.make + h.put_content_type_text_html + s := "Hello " + ctx.path + "%N" + s.append ("root=" + document_root) + + h.put_content_length (s.count) + res.set_status_code ({HTTP_STATUS_CODE}.ok) + res.write_headers_string (h.string) + res.write_string (s) + end + end + + process_uri (uri: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + local + f: RAW_FILE + fn: READABLE_STRING_8 + do + fn := resource_filename (uri) + create f.make (fn) + if f.exists then + if f.is_readable then + if f.is_directory then + respond_index (req.request_uri, fn, ctx, req, res) + else + respond_file (f, ctx, req, res) + end + else + respond_access_denied (uri, ctx, req, res) + end + else + respond_not_found (uri, ctx, req, res) + end + end + + respond_index (a_uri: READABLE_STRING_8; dn: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + local + h: WSF_HEADER + uri, s: STRING_8 + d: DIRECTORY + l_files: LIST [STRING_8] + do + create d.make_open_read (dn) + if attached directory_index_file (d) as f then + respond_file (f, ctx, req, res) + else + uri := a_uri + if not uri.is_empty and then uri [uri.count] /= '/' then + uri.append_character ('/') + end + s := "[ + + + Index for folder: $URI + + +

Index for $URI

+
    + ]" + s.replace_substring_all ("$URI", uri) + + from + l_files := d.linear_representation + l_files.start + until + l_files.after + loop + s.append ("
  • " + l_files.item_for_iteration + "
  • %N") + l_files.forth + end + s.append ("[ +
+ + + ]" + ) + + create h.make + h.put_content_type_text_html + res.set_status_code ({HTTP_STATUS_CODE}.ok) + h.put_content_length (s.count) + res.write_headers_string (h.string) + if not req.request_method.same_string ({HTTP_REQUEST_METHODS}.method_head) then + res.write_string (s) + end + res.flush + end + d.close + end + + respond_file (f: FILE; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + local + fn: READABLE_STRING_8 + h: WSF_HEADER + ext: READABLE_STRING_8 + ct: detachable READABLE_STRING_8 + do + fn := f.name + ext := extension (fn) + ct := extension_mime_mapping.mime_type (ext) + create h.make + + if ct /= Void then + h.put_content_type (ct) + h.put_content_length (f.count) + res.set_status_code ({HTTP_STATUS_CODE}.ok) + res.write_headers_string (h.string) + else + create h.make + h.put_content_type ({HTTP_MIME_TYPES}.application_force_download) + h.put_content_length (f.count) + res.set_status_code ({HTTP_STATUS_CODE}.ok) + res.write_headers_string (h.string) + end + if not req.request_method.same_string ({HTTP_REQUEST_METHODS}.method_head) then + res.write_file_content (fn) + end + res.flush + end + + respond_not_found (uri: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + local + h: WSF_HEADER + s: STRING_8 + do + create h.make + h.put_content_type_text_plain + create s.make_empty + s.append ("Resource %"" + uri + "%" not found%N") + res.set_status_code ({HTTP_STATUS_CODE}.not_found) + h.put_content_length (s.count) + res.write_headers_string (h.string) + res.write_string (s) + res.flush + end + + respond_access_denied (uri: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + local + h: WSF_HEADER + s: STRING_8 + do + create h.make + h.put_content_type_text_plain + create s.make_empty + s.append ("Resource %"" + uri + "%": Access denied%N") + res.set_status_code ({HTTP_STATUS_CODE}.forbidden) + h.put_content_length (s.count) + res.write_headers_string (h.string) + res.write_string (s) + res.flush + end + +feature {NONE} -- Implementation + + directory_index_file (d: DIRECTORY): detachable FILE + local + f: detachable RAW_FILE + fn: FILE_NAME + do + if attached directory_index as default_index then + across + default_index as c + until + Result /= Void + loop + if d.has_entry (c.item) then + create fn.make_from_string (d.name) + fn.set_file_name (c.item) + if f = Void then + create f.make (fn.string) + else + f.make (fn.string) + end + if f.exists and then f.is_readable then + Result := f + end + end + end + end + end + + resource_filename (uri: READABLE_STRING_8): READABLE_STRING_8 + do + Result := real_filename (document_root + real_filename (uri)) + end + + dirname (uri: READABLE_STRING_8): READABLE_STRING_8 + local + p: INTEGER + do + p := uri.last_index_of ('/', uri.count) + if p > 0 then + Result := uri.substring (1, p - 1) + else + create {STRING_8} Result.make_empty + end + end + + filename (uri: READABLE_STRING_8): READABLE_STRING_8 + local + p: INTEGER + do + p := uri.last_index_of ('/', uri.count) + if p > 0 then + Result := uri.substring (p + 1, uri.count) + else + Result := uri.twin + end + end + + extension (uri: READABLE_STRING_8): READABLE_STRING_8 + local + p: INTEGER + do + p := uri.last_index_of ('.', uri.count) + if p > 0 then + Result := uri.substring (p + 1, uri.count) + else + create {STRING_8} Result.make_empty + end + end + + real_filename (fn: STRING): STRING + -- Real filename from url-path `fn' + --| Find a better design for this piece of code + --| Eventually in a spec/$ISE_PLATFORM/ specific cluster + do + if fn.is_empty then + Result := fn + else + if {PLATFORM}.is_windows then + create Result.make_from_string (fn) + Result.replace_substring_all ("/", "\") + if Result [Result.count] = '\' then + Result.remove_tail (1) + end + else + Result := fn + if Result [Result.count] = '/' then + Result.remove_tail (1) + end + end + end + end + +feature {NONE} -- Implementation + + node_exists (p: READABLE_STRING_8): BOOLEAN + local + f: RAW_FILE + do + create f.make (p) + Result := f.exists + end + + extension_mime_mapping: HTTP_FILE_EXTENSION_MIME_MAPPING + local + f: RAW_FILE + once + create f.make ("mime.types") + if f.exists and then f.is_readable then + create Result.make_from_file (f.name) + else + create Result.make_default + end + end + +note + copyright: "2011-2011, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/library/server/request/router/src/request_handler.e b/library/server/request/router/src/request_handler.e index 76ba939b..71822760 100644 --- a/library/server/request/router/src/request_handler.e +++ b/library/server/request/router/src/request_handler.e @@ -17,7 +17,7 @@ inherit feature -- Status report - is_valid_context (req: WGI_REQUEST): BOOLEAN + is_valid_context (req: WSF_REQUEST): BOOLEAN -- Is `req' valid context for current handler? do Result := True @@ -25,7 +25,7 @@ feature -- Status report feature -- Execution - execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler require is_valid_context: is_valid_context (req) @@ -34,7 +34,7 @@ feature -- Execution feature -- Execution: report - url (req: WGI_REQUEST; a_base: detachable READABLE_STRING_8; args: detachable STRING; abs: BOOLEAN): STRING + url (req: WSF_REQUEST; a_base: detachable READABLE_STRING_8; args: detachable STRING; abs: BOOLEAN): STRING -- Associated url based on `a_base' and `args' -- if `abs' then return absolute url local diff --git a/library/server/request/router/src/request_handler_context.e b/library/server/request/router/src/request_handler_context.e index 0e29c643..12cbda99 100644 --- a/library/server/request/router/src/request_handler_context.e +++ b/library/server/request/router/src/request_handler_context.e @@ -16,7 +16,7 @@ inherit feature -- Access - request: WGI_REQUEST + request: WSF_REQUEST -- Associated request path: READABLE_STRING_8 @@ -31,7 +31,7 @@ feature {NONE} -- Constants feature -- Query - request_format (a_format_variable_name: detachable READABLE_STRING_GENERAL; content_type_supported: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8 + request_format (a_format_variable_name: detachable READABLE_STRING_8; content_type_supported: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8 -- Format id for the request based on {HTTP_FORMAT_CONSTANTS} do if a_format_variable_name /= Void and then attached string_parameter (a_format_variable_name) as ctx_format then @@ -41,7 +41,7 @@ feature -- Query end end - request_format_id (a_format_variable_name: detachable READABLE_STRING_GENERAL; content_type_supported: detachable ARRAY [READABLE_STRING_8]): INTEGER + request_format_id (a_format_variable_name: detachable READABLE_STRING_8; content_type_supported: detachable ARRAY [READABLE_STRING_8]): INTEGER -- Format id for the request based on {HTTP_FORMAT_CONSTANTS} do if attached request_format (a_format_variable_name, content_type_supported) as l_format then @@ -71,12 +71,11 @@ feature -- Query request_content_type (content_type_supported: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8 local - s: detachable READABLE_STRING_32 + s: detachable READABLE_STRING_8 i,n: INTEGER do - s := request.content_type - if s /= Void then - Result := s + if attached request.content_type as ct then + Result := ct else if attached accepted_content_types (request) as l_accept_lst then from @@ -108,18 +107,18 @@ feature -- Query feature -- Query - path_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE + path_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE -- Parameter value for path variable `a_name' deferred end - query_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE + query_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE -- Parameter value for query variable `a_name' --| i.e after the ? character deferred end - parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE + parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE -- Any parameter value for variable `a_name' -- URI template parameter and query parameters do @@ -131,24 +130,24 @@ feature -- Query feature -- String query - string_from (a_value: detachable WGI_VALUE): detachable READABLE_STRING_32 + string_from (a_value: detachable WSF_VALUE): detachable READABLE_STRING_32 do - if attached {WGI_STRING_VALUE} a_value as val then + if attached {WSF_STRING_VALUE} a_value as val then Result := val.string end end - string_path_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + string_path_parameter (a_name: READABLE_STRING_8): detachable READABLE_STRING_32 do Result := string_from (path_parameter (a_name)) end - string_query_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + string_query_parameter (a_name: READABLE_STRING_8): detachable READABLE_STRING_32 do Result := string_from (query_parameter (a_name)) end - string_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + string_parameter (a_name: READABLE_STRING_8): detachable READABLE_STRING_32 do Result := string_from (parameter (a_name)) end diff --git a/library/server/request/router/src/request_router.e b/library/server/request/router/src/request_router.e index 901b3e83..e903a893 100644 --- a/library/server/request/router/src/request_router.e +++ b/library/server/request/router/src/request_router.e @@ -34,12 +34,12 @@ feature -- Mapping deferred end - map_agent (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]) + map_agent (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]) do map_agent_with_request_methods (a_resource, a_action, Void) end - map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]; + map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable ARRAY [READABLE_STRING_8]) local rah: REQUEST_AGENT_HANDLER [C] @@ -65,14 +65,14 @@ feature -- Base url feature -- Execution - dispatch (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER): BOOLEAN + dispatch (req: WSF_REQUEST; res: WSF_RESPONSE): BOOLEAN -- Dispatch `req, res' to the associated handler -- And return True is handled, otherwise False do Result := dispatch_and_return_handler (req, res) /= Void end - dispatch_and_return_handler (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER): detachable H + dispatch_and_return_handler (req: WSF_REQUEST; res: WSF_RESPONSE): detachable H -- Dispatch `req, res' to the associated handler -- And return this handler -- If Result is Void, this means no handler was found. @@ -108,13 +108,13 @@ feature -- Traversing feature {NONE} -- Access: Implementation - source_uri (req: WGI_REQUEST): READABLE_STRING_32 + source_uri (req: WSF_REQUEST): READABLE_STRING_32 -- URI to use to find handler. do Result := req.path_info end - handler (req: WGI_REQUEST): detachable TUPLE [handler: H; context: like default_handler_context] + handler (req: WSF_REQUEST): detachable TUPLE [handler: H; context: like default_handler_context] -- Handler whose map matched with `req' require req_valid: source_uri (req) /= Void @@ -179,7 +179,7 @@ feature {NONE} -- Implementation deferred end - default_handler_context (req: WGI_REQUEST): C + default_handler_context (req: WSF_REQUEST): C -- Default handler context associated with `default_handler' require has_default_handler: default_handler /= Void diff --git a/library/server/request/router/src/request_routing_handler.e b/library/server/request/router/src/request_routing_handler.e index 19940f5f..d4519ef2 100644 --- a/library/server/request/router/src/request_routing_handler.e +++ b/library/server/request/router/src/request_routing_handler.e @@ -13,7 +13,7 @@ inherit feature -- Execution - execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler local hdl: detachable H @@ -49,12 +49,12 @@ feature -- Mapping router.map_with_request_methods (a_resource, h, rqst_methods) end - map_agent (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]) + map_agent (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]) do router.map_agent (a_resource, a_action) end - map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]; + map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable ARRAY [READABLE_STRING_8]) do router.map_agent_with_request_methods (a_resource, a_action, rqst_methods) diff --git a/library/server/request/router/src/routed_application_i.e b/library/server/request/router/src/routed_application_i.e index eabefeb4..3c68daf1 100644 --- a/library/server/request/router/src/routed_application_i.e +++ b/library/server/request/router/src/routed_application_i.e @@ -35,7 +35,7 @@ feature -- Setup feature -- Execution - execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute (req: WSF_REQUEST; res: WSF_RESPONSE) local l_handled: BOOLEAN rescued: BOOLEAN @@ -50,11 +50,11 @@ feature -- Execution end end - execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) deferred end - execute_rescue (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute_rescue (req: WSF_REQUEST; res: WSF_RESPONSE) do if not res.header_committed then res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void) diff --git a/library/server/request/router/src/uri/default/request_uri_router.e b/library/server/request/router/src/uri/default/request_uri_router.e index 99c4d588..0cd35d9f 100644 --- a/library/server/request/router/src/uri/default/request_uri_router.e +++ b/library/server/request/router/src/uri/default/request_uri_router.e @@ -17,7 +17,7 @@ create feature -- Mapping - map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REQUEST_URI_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]; + map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REQUEST_URI_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable ARRAY [READABLE_STRING_8]) local h: REQUEST_AGENT_HANDLER [REQUEST_URI_HANDLER_CONTEXT] diff --git a/library/server/request/router/src/uri/request_uri_handler_context.e b/library/server/request/router/src/uri/request_uri_handler_context.e index bfb167f1..ec7077c8 100644 --- a/library/server/request/router/src/uri/request_uri_handler_context.e +++ b/library/server/request/router/src/uri/request_uri_handler_context.e @@ -15,7 +15,7 @@ create feature {NONE} -- Initialization - make (req: WGI_REQUEST; p: like path) + make (req: WSF_REQUEST; p: like path) do request := req path := p @@ -23,11 +23,11 @@ feature {NONE} -- Initialization feature -- Query - path_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE + path_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE do end - query_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE + query_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE do Result := request.query_parameter (a_name) end diff --git a/library/server/request/router/src/uri/request_uri_router_i.e b/library/server/request/router/src/uri/request_uri_router_i.e index 2bea6d90..c7cb069e 100644 --- a/library/server/request/router/src/uri/request_uri_router_i.e +++ b/library/server/request/router/src/uri/request_uri_router_i.e @@ -38,7 +38,7 @@ feature -- Registration feature {NONE} -- Access: Implementation - handler (req: WGI_REQUEST): detachable TUPLE [handler: H; context: like default_handler_context] + handler (req: WSF_REQUEST): detachable TUPLE [handler: H; context: like default_handler_context] local h: detachable H ctx: detachable like default_handler_context @@ -62,7 +62,7 @@ feature {NONE} -- Access: Implementation end end - smart_handler (req: WGI_REQUEST): detachable TUPLE [path: READABLE_STRING_8; handler: H] + smart_handler (req: WSF_REQUEST): detachable TUPLE [path: READABLE_STRING_8; handler: H] require req_valid: req /= Void and then source_uri (req) /= Void do @@ -124,7 +124,7 @@ feature {NONE} -- Access: Implementation feature {NONE} -- Context factory - handler_context (p: detachable STRING; req: WGI_REQUEST): C + handler_context (p: detachable STRING; req: WSF_REQUEST): C local ctx: C do @@ -184,7 +184,7 @@ feature {NONE} -- Default: implementation default_handler := h end - default_handler_context (req: WGI_REQUEST): C + default_handler_context (req: WSF_REQUEST): C do Result := handler_context (Void, req) end diff --git a/library/server/request/router/src/uri_template/default/request_uri_template_router.e b/library/server/request/router/src/uri_template/default/request_uri_template_router.e index 41cefe4f..3fef77bf 100644 --- a/library/server/request/router/src/uri_template/default/request_uri_template_router.e +++ b/library/server/request/router/src/uri_template/default/request_uri_template_router.e @@ -18,7 +18,7 @@ create feature -- Mapping - map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]; + map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable ARRAY [READABLE_STRING_8]) local h: REQUEST_AGENT_HANDLER [REQUEST_URI_TEMPLATE_HANDLER_CONTEXT] diff --git a/library/server/request/router/src/uri_template/request_uri_template_handler_context.e b/library/server/request/router/src/uri_template/request_uri_template_handler_context.e index 5cf1c7db..2c1eafb2 100644 --- a/library/server/request/router/src/uri_template/request_uri_template_handler_context.e +++ b/library/server/request/router/src/uri_template/request_uri_template_handler_context.e @@ -15,7 +15,7 @@ create feature {NONE} -- Initialization - make (req: WGI_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT; p: like path) + make (req: WSF_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT; p: like path) do request := req uri_template := tpl @@ -31,17 +31,17 @@ feature -- Access feature -- Query - path_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE + path_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE do if attached uri_template_match.url_decoded_path_variable (a_name) as s then - create {WGI_STRING_VALUE} Result.make (a_name, s) + create {WSF_STRING_VALUE} Result.make (a_name, s) end end - query_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE + query_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE do if attached uri_template_match.url_decoded_query_variable (a_name) as s then - create {WGI_STRING_VALUE} Result.make (a_name, s) + create {WSF_STRING_VALUE} Result.make (a_name, s) else Result := request.query_parameter (a_name) end diff --git a/library/server/request/router/src/uri_template/request_uri_template_router_i.e b/library/server/request/router/src/uri_template/request_uri_template_router_i.e index 9c3ec225..18ab2b42 100644 --- a/library/server/request/router/src/uri_template/request_uri_template_router_i.e +++ b/library/server/request/router/src/uri_template/request_uri_template_router_i.e @@ -54,11 +54,11 @@ feature -- Registration feature {NONE} -- Access: Implementation - handler (req: WGI_REQUEST): detachable TUPLE [handler: attached like default_handler; context: like default_handler_context] + handler (req: WSF_REQUEST): detachable TUPLE [handler: attached like default_handler; context: like default_handler_context] local l_handlers: like handlers - t: STRING - p: STRING + t: READABLE_STRING_8 + p: READABLE_STRING_8 l_req_method: READABLE_STRING_GENERAL l_res: URI_TEMPLATE_MATCH_RESULT do @@ -94,7 +94,7 @@ feature {NONE} -- Access: Implementation feature {NONE} -- Context factory - handler_context (p: detachable STRING; req: WGI_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT): C + handler_context (p: detachable STRING; req: WSF_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT): C do if p /= Void then create Result.make (req, tpl, tpl_res, p) @@ -151,7 +151,7 @@ feature {NONE} -- Default: implementation default_handler := h end - default_handler_context (req: WGI_REQUEST): C + default_handler_context (req: WSF_REQUEST): C do Result := handler_context (Void, req, create {URI_TEMPLATE}.make ("/"), create {URI_TEMPLATE_MATCH_RESULT}.make_empty) end diff --git a/library/server/ewsgi/default/ewsgi_cgi-safe.ecf b/library/server/wsf/default/cgi-safe.ecf similarity index 76% rename from library/server/ewsgi/default/ewsgi_cgi-safe.ecf rename to library/server/wsf/default/cgi-safe.ecf index 21f4677f..db7056f7 100644 --- a/library/server/ewsgi/default/ewsgi_cgi-safe.ecf +++ b/library/server/wsf/default/cgi-safe.ecf @@ -1,6 +1,6 @@ - - + + /EIFGENs$ @@ -11,8 +11,9 @@ - - + + + diff --git a/library/server/ewsgi/default/ewsgi_cgi.ecf b/library/server/wsf/default/cgi.ecf similarity index 75% rename from library/server/ewsgi/default/ewsgi_cgi.ecf rename to library/server/wsf/default/cgi.ecf index 5abbca2c..e1efa845 100644 --- a/library/server/ewsgi/default/ewsgi_cgi.ecf +++ b/library/server/wsf/default/cgi.ecf @@ -1,6 +1,6 @@ - - + + /EIFGENs$ @@ -11,8 +11,9 @@ - - + + + diff --git a/library/server/ewsgi/default/cgi/default_wgi_application.e b/library/server/wsf/default/cgi/default_application.e similarity index 79% rename from library/server/ewsgi/default/cgi/default_wgi_application.e rename to library/server/wsf/default/cgi/default_application.e index e42f84ae..7fb7b785 100644 --- a/library/server/ewsgi/default/cgi/default_wgi_application.e +++ b/library/server/wsf/default/cgi/default_application.e @@ -1,19 +1,19 @@ note - description: "Summary description for {DEFAULT_WGI_APPLICATION}." + description: "Summary description for {DEFAULT_APPLICATION}." date: "$Date$" revision: "$Revision$" deferred class - DEFAULT_WGI_APPLICATION + DEFAULT_APPLICATION inherit - WGI_APPLICATION + WSF_APPLICATION feature {NONE} -- Initialization make_and_launch local - cgi: EWF_CGI_CONNECTOR + cgi: WGI_CGI_CONNECTOR do create cgi.make (Current) cgi.launch diff --git a/library/server/ewsgi/default/ewsgi_nino-safe.ecf b/library/server/wsf/default/nino-safe.ecf similarity index 78% rename from library/server/ewsgi/default/ewsgi_nino-safe.ecf rename to library/server/wsf/default/nino-safe.ecf index 8a827054..8965e4d9 100644 --- a/library/server/ewsgi/default/ewsgi_nino-safe.ecf +++ b/library/server/wsf/default/nino-safe.ecf @@ -1,6 +1,6 @@ - - + + /EIFGENs$ @@ -11,8 +11,9 @@ - - + + + diff --git a/library/server/ewsgi/default/ewsgi_nino.ecf b/library/server/wsf/default/nino.ecf similarity index 78% rename from library/server/ewsgi/default/ewsgi_nino.ecf rename to library/server/wsf/default/nino.ecf index 0e3f9479..9b2ac5da 100644 --- a/library/server/ewsgi/default/ewsgi_nino.ecf +++ b/library/server/wsf/default/nino.ecf @@ -1,6 +1,6 @@ - - + + /EIFGENs$ @@ -11,8 +11,9 @@ - - + + + diff --git a/library/server/ewsgi/default/nino/default_wgi_application.e b/library/server/wsf/default/nino/default_application.e similarity index 82% rename from library/server/ewsgi/default/nino/default_wgi_application.e rename to library/server/wsf/default/nino/default_application.e index 7ff198fa..becc688a 100644 --- a/library/server/ewsgi/default/nino/default_wgi_application.e +++ b/library/server/wsf/default/nino/default_application.e @@ -1,13 +1,13 @@ note - description: "Summary description for {DEFAULT_WGI_APPLICATION}." + description: "Summary description for {DEFAULT_APPLICATION}." date: "$Date$" revision: "$Revision$" deferred class - DEFAULT_WGI_APPLICATION + DEFAULT_APPLICATION inherit - WGI_APPLICATION + WSF_APPLICATION feature {NONE} -- Initialization @@ -15,13 +15,13 @@ feature {NONE} -- Initialization local app: NINO_APPLICATION do - port_number := 80 + port_number := 8080 base_url := "" debug ("nino") print ("Example: start a Nino web server on port " + port_number.out + ", %Nand reply Hello World for any request such as http://localhost:" + port_number.out + "/" + base_url + "%N") end - create app.make_custom (agent execute, base_url) + create app.make_custom (agent wgi_execute, base_url) app.listen (port_number) end diff --git a/library/server/wsf/src/cgi_meta_names.e b/library/server/wsf/src/cgi_meta_names.e new file mode 100644 index 00000000..2d4621a7 --- /dev/null +++ b/library/server/wsf/src/cgi_meta_names.e @@ -0,0 +1,13 @@ +note + description: "Summary description for {WSF_META_NAMES}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + CGI_META_NAMES + +inherit + WGI_META_NAMES + +end diff --git a/library/server/ewsgi/specification/request/value/wgi_multiple_string_value.e b/library/server/wsf/src/request/value/wsf_multiple_string_value.e similarity index 78% rename from library/server/ewsgi/specification/request/value/wgi_multiple_string_value.e rename to library/server/wsf/src/request/value/wsf_multiple_string_value.e index acd6645d..1325e67e 100644 --- a/library/server/ewsgi/specification/request/value/wgi_multiple_string_value.e +++ b/library/server/wsf/src/request/value/wsf_multiple_string_value.e @@ -1,16 +1,16 @@ note - description: "Summary description for {WGI_MULTIPLE_STRING_VALUE}." + description: "Summary description for {WSF_MULTIPLE_STRING_VALUE}." author: "" date: "$Date$" revision: "$Revision$" class - WGI_MULTIPLE_STRING_VALUE + WSF_MULTIPLE_STRING_VALUE inherit - WGI_VALUE + WSF_VALUE - ITERABLE [WGI_STRING_VALUE] + ITERABLE [WSF_STRING_VALUE] create make_with_value, @@ -19,14 +19,14 @@ create feature {NONE} -- Initialization - make_with_value (a_value: WGI_VALUE) + make_with_value (a_value: WSF_VALUE) do name := a_value.name - create {LINKED_LIST [WGI_STRING_VALUE]} string_values.make + create {LINKED_LIST [WSF_STRING_VALUE]} string_values.make add_value (a_value) end - make_with_array (arr: ARRAY [WGI_VALUE]) + make_with_array (arr: ARRAY [WSF_VALUE]) require arr_not_empty: not arr.is_empty all_same_name: across arr as c all c.item.name.same_string (arr[arr.lower].name) end @@ -48,23 +48,23 @@ feature {NONE} -- Initialization make_with_string (a_name: like name; a_string: READABLE_STRING_32) do - make_with_value (create {WGI_STRING_VALUE}.make (a_name, a_string)) + make_with_value (create {WSF_STRING_VALUE}.make (a_name, a_string)) end feature -- Access name: READABLE_STRING_32 - string_values: LIST [WGI_STRING_VALUE] + string_values: LIST [WSF_STRING_VALUE] - first_string_value: WGI_STRING_VALUE + first_string_value: WSF_STRING_VALUE do Result := string_values.first end feature -- Traversing - new_cursor: ITERATION_CURSOR [WGI_STRING_VALUE] + new_cursor: ITERATION_CURSOR [WSF_STRING_VALUE] do Result := string_values.new_cursor end @@ -107,13 +107,13 @@ feature -- Helper feature -- Element change - add_value (a_value: WGI_VALUE) + add_value (a_value: WSF_VALUE) require same_name: a_value.name.same_string (name) do - if attached {WGI_STRING_VALUE} a_value as sval then + if attached {WSF_STRING_VALUE} a_value as sval then add_string_value (sval) - elseif attached {WGI_MULTIPLE_STRING_VALUE} a_value as slst then + elseif attached {WSF_MULTIPLE_STRING_VALUE} a_value as slst then across slst as cur loop @@ -122,7 +122,7 @@ feature -- Element change end end - add_string_value (s: WGI_STRING_VALUE) + add_string_value (s: WSF_STRING_VALUE) do string_values.extend (s) end diff --git a/library/server/ewsgi/specification/request/value/wgi_string_value.e b/library/server/wsf/src/request/value/wsf_string_value.e similarity index 66% rename from library/server/ewsgi/specification/request/value/wgi_string_value.e rename to library/server/wsf/src/request/value/wsf_string_value.e index 3f3f6f2d..dfc7e4a6 100644 --- a/library/server/ewsgi/specification/request/value/wgi_string_value.e +++ b/library/server/wsf/src/request/value/wsf_string_value.e @@ -1,14 +1,14 @@ note - description: "Summary description for {WGI_STRING_VALUE}." + description: "Summary description for {WSF_STRING_VALUE}." author: "" date: "$Date$" revision: "$Revision$" class - WGI_STRING_VALUE + WSF_STRING_VALUE inherit - WGI_VALUE + WSF_VALUE create make @@ -18,10 +18,13 @@ convert feature {NONE} -- Initialization - make (a_name: READABLE_STRING_GENERAL; a_string: like string) + make (a_name: READABLE_STRING_8; a_string: READABLE_STRING_8) do - name := a_name.as_string_32 - string := a_string + name := url_decoded_string (a_name) + string := url_decoded_string (a_string) + + url_encoded_name := a_name + url_encoded_string := a_string end feature -- Access @@ -30,6 +33,10 @@ feature -- Access string: READABLE_STRING_32 + url_encoded_name: READABLE_STRING_32 + + url_encoded_string: READABLE_STRING_32 + feature -- Helper same_string (a_other: READABLE_STRING_GENERAL): BOOLEAN @@ -58,6 +65,19 @@ feature -- Conversion create Result.make_from_string (string) end +feature {NONE} -- Implementation + + url_decoded_string (s: READABLE_STRING_8): READABLE_STRING_32 + -- Decoded url-encoded string `s' + do + Result := url_encoder.decoded_string (s) + end + + url_encoder: URL_ENCODER + once + create Result + end + ;note copyright: "2011-2011, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/library/server/ewsgi/specification/request/wgi_value.e b/library/server/wsf/src/request/wsf_value.e similarity index 94% rename from library/server/ewsgi/specification/request/wgi_value.e rename to library/server/wsf/src/request/wsf_value.e index 59d4e6eb..b0bc9b35 100644 --- a/library/server/ewsgi/specification/request/wgi_value.e +++ b/library/server/wsf/src/request/wsf_value.e @@ -1,11 +1,11 @@ note - description: "Summary description for {WGI_VALUE}." + description: "Summary description for {WSF_VALUE}." author: "" date: "$Date$" revision: "$Revision$" deferred class - WGI_VALUE + WSF_VALUE inherit DEBUG_OUTPUT diff --git a/library/server/ewsgi/src/support/ewf_error.e b/library/server/wsf/src/support/wsf_error.e similarity index 94% rename from library/server/ewsgi/src/support/ewf_error.e rename to library/server/wsf/src/support/wsf_error.e index 5884d12e..d4f9eb47 100644 --- a/library/server/ewsgi/src/support/ewf_error.e +++ b/library/server/wsf/src/support/wsf_error.e @@ -1,12 +1,12 @@ note - description: "Summary description for {EWF_ERROR}." + description: "Summary description for {WSF_ERROR}." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class - EWF_ERROR + WSF_ERROR inherit ERROR diff --git a/library/server/wsf/src/support/wsf_header.e b/library/server/wsf/src/support/wsf_header.e new file mode 100644 index 00000000..5d333cdb --- /dev/null +++ b/library/server/wsf/src/support/wsf_header.e @@ -0,0 +1,42 @@ +note + description: "[ + The class provides an easy way to build HTTP header. + + You will also find some helper feature to help coding most common usage + + Please, have a look at constants classes such as + HTTP_MIME_TYPES + HTTP_HEADER_NAMES + HTTP_STATUS_CODE + HTTP_REQUEST_METHODS + (or HTTP_CONSTANTS which groups them for convenience) + + Note the return status code is not part of the HTTP header + However you can set the "Status: " header line if you want + ]" + legal: "See notice at end of class." + status: "See notice at end of class." + date: "$Date$" + revision: "$Revision$" + +class + WSF_HEADER + +inherit + EWF_HEADER + +create + make, + make_with_count + +note + copyright: "2011-2011, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" +end diff --git a/library/server/wsf/src/wsf_application.e b/library/server/wsf/src/wsf_application.e new file mode 100644 index 00000000..2d845a04 --- /dev/null +++ b/library/server/wsf/src/wsf_application.e @@ -0,0 +1,32 @@ +note + description: "Objects that ..." + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_APPLICATION + +inherit + WGI_APPLICATION + rename + execute as wgi_execute + end + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute the request + -- See `req.input' for input stream + -- `req.meta_variables' for the CGI meta variable + -- and `res' for output buffer + deferred + end + +feature -- WGI Execution + + wgi_execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + do + execute (req, res) + end + +end diff --git a/library/server/ewsgi/src/wgi_request_from_table.e b/library/server/wsf/src/wsf_request.e similarity index 51% rename from library/server/ewsgi/src/wgi_request_from_table.e rename to library/server/wsf/src/wsf_request.e index 9d181d79..f3aa67b4 100644 --- a/library/server/ewsgi/src/wgi_request_from_table.e +++ b/library/server/wsf/src/wsf_request.e @@ -1,130 +1,81 @@ note description: "[ - Request instanciated from a hash_table of meta variables - ]" - specification: "EWSGI specification https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki/EWSGI-specification" - legal: "See notice at end of class." - status: "See notice at end of class." + Summary description for {WSF_REQUEST}. + ]" date: "$Date$" revision: "$Revision$" class - WGI_REQUEST_FROM_TABLE + WSF_REQUEST inherit - WGI_REQUEST + DEBUG_OUTPUT -create - make +create {WSF_APPLICATION} + make_from_wgi + +convert + make_from_wgi ({WGI_REQUEST}) feature {NONE} -- Initialization - make (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]; a_input: like input) - require - vars_attached: a_vars /= Void + make_from_wgi (r: WGI_REQUEST) do + wgi_request := r + if attached r.meta_variables as l_vars then + create meta_variables_table.make (l_vars.count) + across + l_vars as c + loop + meta_variables_table.force (new_string_value (c.key, c.item), c.item) + end + else + create meta_variables_table.make (0) + end + meta_variables := meta_variables_table create error_handler.make - input := a_input - set_meta_parameters (a_vars) create uploaded_files.make (0) - raw_post_data_recorded := True + create {STRING_32} empty_string.make_empty initialize analyze end - set_meta_parameters (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_GENERAL]) - -- Fill with variable from `a_vars' - local - s: like meta_string_variable - table: HASH_TABLE [WGI_STRING_VALUE, READABLE_STRING_GENERAL] - l_query_string: like query_string - l_request_uri: detachable STRING_32 - do - create {STRING_32} empty_string.make_empty - - create table.make (a_vars.count) - table.compare_objects - meta_variables_table := table - from - a_vars.start - until - a_vars.after - loop - table.force (new_string_value (a_vars.key_for_iteration, a_vars.item_for_iteration), a_vars.key_for_iteration) - a_vars.forth - end - - --| QUERY_STRING - l_query_string := meta_string_variable_or_default ({WGI_META_NAMES}.query_string, empty_string, False) - query_string := l_query_string - - --| REQUEST_METHOD - request_method := meta_string_variable_or_default ({WGI_META_NAMES}.request_method, empty_string, False) - - --| CONTENT_TYPE - s := meta_string_variable ({WGI_META_NAMES}.content_type) - if s /= Void and then not s.is_empty then - content_type := s - else - content_type := Void - end - - --| CONTENT_LENGTH - s := meta_string_variable ({WGI_META_NAMES}.content_length) - content_length := s - if s /= Void and then s.is_natural_64 then - content_length_value := s.to_natural_64 - else - --| content_length := 0 - end - - --| PATH_INFO - path_info := meta_string_variable_or_default ({WGI_META_NAMES}.path_info, empty_string, False) - - --| SERVER_NAME - server_name := meta_string_variable_or_default ({WGI_META_NAMES}.server_name, empty_string, False) - - --| SERVER_PORT - s := meta_string_variable ({WGI_META_NAMES}.server_port) - if s /= Void and then s.is_integer then - server_port := s.to_integer - else - server_port := 80 - end - - --| SCRIPT_NAME - script_name := meta_string_variable_or_default ({WGI_META_NAMES}.script_name, empty_string, False) - - --| REMOTE_ADDR - remote_addr := meta_string_variable_or_default ({WGI_META_NAMES}.remote_addr, empty_string, False) - - --| REMOTE_HOST - remote_host := meta_string_variable_or_default ({WGI_META_NAMES}.remote_host, empty_string, False) - - --| REQUEST_URI - s := meta_string_variable ({WGI_META_NAMES}.request_uri) - if s /= Void then - l_request_uri := s - else - --| It might occur that REQUEST_URI is not available, so let's compute it from SCRIPT_NAME - create l_request_uri.make_from_string (script_name) - if not l_query_string.is_empty then - l_request_uri.append_character ('?') - l_request_uri.append (l_query_string) - end - end - request_uri := single_slash_starting_string (l_request_uri) - end - initialize -- Specific initialization + local + s8: detachable READABLE_STRING_8 do - --| Here one can set its own environment entries if needed - if meta_variable ({WGI_META_NAMES}.request_time) = Void then - set_meta_string_variable ({WGI_META_NAMES}.request_time, date_time_utilities.unix_time_stamp (Void).out) + --| Content-Length + if attached content_length as s and then s.is_natural_64 then + content_length_value := s.to_natural_64 + else + content_length_value := 0 end + + --| PATH_INFO + path_info := url_encoder.decoded_string (wgi_request.path_info) + + --| PATH_TRANSLATED + s8 := wgi_request.path_translated + if s8 /= Void then + path_translated := url_encoder.decoded_string (s8) + end + + --| Here one can set its own environment entries if needed + if meta_variable ({CGI_META_NAMES}.request_time) = Void then + set_meta_string_variable ({CGI_META_NAMES}.request_time, date_time_utilities.unix_time_stamp (Void).out) + end + end + + wgi_request: WGI_REQUEST + +feature -- Status report + + debug_output: STRING_8 + do + create Result.make_from_string (request_method + " " + request_uri) end feature -- Status @@ -144,484 +95,19 @@ feature -- Error handling error_handler: ERROR_HANDLER -- Error handler - -- By default initialized to new handler + -- By default initialized to new handler feature -- Access: Input input: WGI_INPUT_STREAM -- Server input channel - -feature -- Access extra information - - request_time: detachable DATE_TIME - -- Request time (UTC) do - if - attached {WGI_STRING_VALUE} meta_variable ({WGI_META_NAMES}.request_time) as t and then - t.string.is_integer_64 - then - Result := date_time_utilities.unix_time_stamp_to_date_time (t.string.to_integer_64) - end - end - -feature {NONE} -- Access: CGI meta parameters - - meta_variables_table: HASH_TABLE [WGI_STRING_VALUE, READABLE_STRING_GENERAL] - -- CGI Environment parameters - -feature -- Access: CGI meta parameters - - meta_variables: ITERABLE [WGI_STRING_VALUE] - do - Result := meta_variables_table - end - - meta_variable (a_name: READABLE_STRING_GENERAL): detachable WGI_STRING_VALUE - -- CGI meta variable related to `a_name' - do - Result := meta_variables_table.item (a_name) - end - - meta_string_variable_or_default (a_name: READABLE_STRING_GENERAL; a_default: READABLE_STRING_32; use_default_when_empty: BOOLEAN): READABLE_STRING_32 - -- Value for meta parameter `a_name' - -- If not found, return `a_default' - require - a_name_not_empty: a_name /= Void and then not a_name.is_empty - do - if attached meta_variable (a_name) as val then - Result := val.string - if use_default_when_empty and then Result.is_empty then - Result := a_default - end - else - Result := a_default - end - end - - set_meta_string_variable (a_name: READABLE_STRING_GENERAL; a_value: READABLE_STRING_32) - do - meta_variables_table.force (new_string_value (a_name, a_value), a_name) - ensure - param_set: attached {WGI_STRING_VALUE} meta_variable (a_name) as val and then val ~ a_value - end - - unset_meta_variable (a_name: READABLE_STRING_GENERAL) - do - meta_variables_table.remove (a_name) - ensure - param_unset: meta_variable (a_name) = Void - end - -feature -- Access: CGI meta parameters - 1.1 - - auth_type: detachable READABLE_STRING_32 - - content_length: detachable READABLE_STRING_32 - - content_length_value: NATURAL_64 - - content_type: detachable READABLE_STRING_32 - - gateway_interface: READABLE_STRING_32 - do - Result := meta_string_variable_or_default ({WGI_META_NAMES}.gateway_interface, "", False) - end - - path_info: READABLE_STRING_32 - -- - -- - --| For instance, if the current script was accessed via the URL - --| http://www.example.com/eiffel/path_info.exe/some/stuff?foo=bar, then $_SERVER['PATH_INFO'] would contain /some/stuff. - --| - --| Note that is the PATH_INFO variable does not exists, the `path_info' value will be empty - - path_translated: detachable READABLE_STRING_32 - do - Result := meta_string_variable ({WGI_META_NAMES}.path_translated) - end - - query_string: READABLE_STRING_32 - - remote_addr: READABLE_STRING_32 - - remote_host: READABLE_STRING_32 - - remote_ident: detachable READABLE_STRING_32 - do - Result := meta_string_variable ({WGI_META_NAMES}.remote_ident) - end - - remote_user: detachable READABLE_STRING_32 - do - Result := meta_string_variable ({WGI_META_NAMES}.remote_user) - end - - request_method: READABLE_STRING_32 - - script_name: READABLE_STRING_32 - - server_name: READABLE_STRING_32 - - server_port: INTEGER - - server_protocol: READABLE_STRING_32 - do - Result := meta_string_variable_or_default ({WGI_META_NAMES}.server_protocol, "HTTP/1.0", True) - end - - server_software: READABLE_STRING_32 - do - Result := meta_string_variable_or_default ({WGI_META_NAMES}.server_software, "Unknown Server", True) - end - -feature -- Access: HTTP_* CGI meta parameters - 1.1 - - http_accept: detachable READABLE_STRING_32 - -- Contents of the Accept: header from the current request, if there is one. - do - Result := meta_string_variable ({WGI_META_NAMES}.http_accept) - end - - http_accept_charset: detachable READABLE_STRING_32 - -- Contents of the Accept-Charset: header from the current request, if there is one. - -- Example: 'iso-8859-1,*,utf-8'. - do - Result := meta_string_variable ({WGI_META_NAMES}.http_accept_charset) - end - - http_accept_encoding: detachable READABLE_STRING_32 - -- Contents of the Accept-Encoding: header from the current request, if there is one. - -- Example: 'gzip'. - do - Result := meta_string_variable ({WGI_META_NAMES}.http_accept_encoding) - end - - http_accept_language: detachable READABLE_STRING_32 - -- Contents of the Accept-Language: header from the current request, if there is one. - -- Example: 'en'. - do - Result := meta_string_variable ({WGI_META_NAMES}.http_accept_language) - end - - http_connection: detachable READABLE_STRING_32 - -- Contents of the Connection: header from the current request, if there is one. - -- Example: 'Keep-Alive'. - do - Result := meta_string_variable ({WGI_META_NAMES}.http_connection) - end - - http_host: detachable READABLE_STRING_32 - -- Contents of the Host: header from the current request, if there is one. - do - Result := meta_string_variable ({WGI_META_NAMES}.http_host) - end - - http_referer: detachable READABLE_STRING_32 - -- The address of the page (if any) which referred the user agent to the current page. - -- This is set by the user agent. - -- Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. - -- In short, it cannot really be trusted. - do - Result := meta_string_variable ({WGI_META_NAMES}.http_referer) - end - - http_user_agent: detachable READABLE_STRING_32 - -- Contents of the User-Agent: header from the current request, if there is one. - -- This is a string denoting the user agent being which is accessing the page. - -- A typical example is: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586). - -- Among other things, you can use this value to tailor your page's - -- output to the capabilities of the user agent. - do - Result := meta_string_variable ({WGI_META_NAMES}.http_user_agent) - end - - http_authorization: detachable READABLE_STRING_32 - -- Contents of the Authorization: header from the current request, if there is one. - do - Result := meta_string_variable ({WGI_META_NAMES}.http_authorization) - end - -feature -- Access: Extension to CGI meta parameters - 1.1 - - request_uri: READABLE_STRING_32 - -- The URI which was given in order to access this page; for instance, '/index.html'. - - orig_path_info: detachable READABLE_STRING_32 - -- Original version of `path_info' before processed by Current environment - -feature {NONE} -- Element change: CGI meta parameter related to PATH_INFO - - set_orig_path_info (s: READABLE_STRING_32) - -- Set ORIG_PATH_INFO to `s' - require - s_attached: s /= Void - do - orig_path_info := s - set_meta_string_variable ({WGI_META_NAMES}.orig_path_info, s) - end - - unset_orig_path_info - -- Unset ORIG_PATH_INFO - do - orig_path_info := Void - unset_meta_variable ({WGI_META_NAMES}.orig_path_info) - ensure - unset: attached meta_variable ({WGI_META_NAMES}.orig_path_info) - end - - update_path_info - -- Fix and update PATH_INFO value if needed - local - l_path_info: STRING - do - l_path_info := path_info - --| Warning - --| on IIS: we might have PATH_INFO = /sample.exe/foo/bar - --| on apache: PATH_INFO = /foo/bar - --| So, we might need to check with SCRIPT_NAME and remove it on IIS - --| store original PATH_INFO in ORIG_PATH_INFO - if l_path_info.is_empty then - unset_orig_path_info - else - set_orig_path_info (l_path_info) - if attached script_name as l_script_name then - if l_path_info.starts_with (l_script_name) then - path_info := l_path_info.substring (l_script_name.count + 1 , l_path_info.count) - end - end - end - end - -feature {NONE} -- Query parameters - - query_parameters_table: HASH_TABLE [WGI_VALUE, READABLE_STRING_GENERAL] - -- Variables extracted from QUERY_STRING - local - vars: like internal_query_parameters_table - p,e: INTEGER - rq_uri: like request_uri - s: detachable STRING - do - vars := internal_query_parameters_table - if vars = Void then - s := query_string - if s = Void then - rq_uri := request_uri - p := rq_uri.index_of ('?', 1) - if p > 0 then - e := rq_uri.index_of ('#', p + 1) - if e = 0 then - e := rq_uri.count - else - e := e - 1 - end - s := rq_uri.substring (p+1, e) - end - end - vars := urlencoded_parameters (s, True) - vars.compare_objects - internal_query_parameters_table := vars - end - Result := vars - end - -feature -- Query parameters - - query_parameters: ITERABLE [WGI_VALUE] - do - Result := query_parameters_table - end - - query_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE - -- Parameter for name `n'. - do - Result := query_parameters_table.item (a_name) - end - -feature {NONE} -- Query parameters: implementation - - urlencoded_parameters (a_content: detachable READABLE_STRING_8; decoding: BOOLEAN): HASH_TABLE [WGI_VALUE, STRING] - -- Import `a_content' - local - n, p, i, j: INTEGER - s: STRING - l_name,l_value: STRING_32 - v: WGI_VALUE - do - if a_content = Void then - create Result.make (0) - else - n := a_content.count - if n = 0 then - create Result.make (0) - else - create Result.make (3) - from - p := 1 - until - p = 0 - loop - i := a_content.index_of ('&', p) - if i = 0 then - s := a_content.substring (p, n) - p := 0 - else - s := a_content.substring (p, i - 1) - p := i + 1 - end - if not s.is_empty then - j := s.index_of ('=', 1) - if j > 0 then - l_name := s.substring (1, j - 1) - l_value := s.substring (j + 1, s.count) - if decoding then - l_name := url_encoder.decoded_string (l_name) - l_value := url_encoder.decoded_string (l_value) - end - v := new_string_value (l_name, l_value) - if Result.has_key (l_name) and then attached Result.found_item as l_existing_value then - if attached {WGI_MULTIPLE_STRING_VALUE} l_existing_value as l_multi then - l_multi.add_value (v) - else - Result.force (create {WGI_MULTIPLE_STRING_VALUE}.make_with_array (<>), l_name) - check replaced: Result.found and then Result.found_item ~ l_existing_value end - end - else - Result.force (v, l_name) - end - end - end - end - end - end - end - -feature {NONE} -- Form fields and related - - form_data_parameters_table: HASH_TABLE [WGI_VALUE, READABLE_STRING_GENERAL] - -- Variables sent by POST request - local - vars: like internal_form_data_parameters_table - s: STRING - n: NATURAL_64 - l_type: like content_type - do - vars := internal_form_data_parameters_table - if vars = Void then - n := content_length_value - if n > 0 then - l_type := content_type - if - l_type /= Void and then - l_type.starts_with ({HTTP_MIME_TYPES}.multipart_form_data) - then - create vars.make (5) - vars.compare_objects - --| FIXME: optimization ... fetch the input data progressively, otherwise we might run out of memory ... - s := form_input_data (n.to_integer_32) --| FIXME truncated from NAT64 to INT32 - analyze_multipart_form (l_type, s, vars) - else - s := form_input_data (n.to_integer_32) --| FIXME truncated from NAT64 to INT32 - vars := urlencoded_parameters (s, True) - end - if raw_post_data_recorded then - set_meta_string_variable ("RAW_POST_DATA", s) - end - else - create vars.make (0) - vars.compare_objects - end - internal_form_data_parameters_table := vars - end - Result := vars - end - -feature -- Form fields and related - - form_data_parameters: ITERABLE [WGI_VALUE] - do - Result := form_data_parameters_table - end - - form_data_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE - -- Field for name `a_name'. - do - Result := form_data_parameters_table.item (a_name) - end - - uploaded_files: HASH_TABLE [WGI_UPLOADED_FILE_DATA, STRING] - -- Table of uploaded files information - --| name: original path from the user - --| type: content type - --| tmp_name: path to temp file that resides on server - --| tmp_base_name: basename of `tmp_name' - --| error: if /= 0 , there was an error : TODO ... - --| size: size of the file given by the http request - -feature {NONE} -- Cookies - - cookies_table: HASH_TABLE [WGI_VALUE, READABLE_STRING_GENERAL] - -- Expanded cookies variable - local - i,j,p,n: INTEGER - l_cookies: like internal_cookies_table - k,v,s: STRING - do - l_cookies := internal_cookies_table - if l_cookies = Void then - if attached {WGI_STRING_VALUE} meta_variable ({WGI_META_NAMES}.http_cookie) as val then - s := val.string - create l_cookies.make (5) - l_cookies.compare_objects - from - n := s.count - p := 1 - i := 1 - until - p < 1 - loop - i := s.index_of ('=', p) - if i > 0 then - j := s.index_of (';', i) - if j = 0 then - j := n + 1 - k := s.substring (p, i - 1) - v := s.substring (i + 1, n) - - p := 0 -- force termination - else - k := s.substring (p, i - 1) - v := s.substring (i + 1, j - 1) - p := j + 1 - end - l_cookies.force (new_string_value (k, v), k) - end - end - else - create l_cookies.make (0) - l_cookies.compare_objects - end - internal_cookies_table := l_cookies - end - Result := l_cookies - end - -feature -- Cookies - - cookies: ITERABLE [WGI_VALUE] - do - Result := cookies_table - end - - cookie (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE - -- Field for name `a_name'. - do - Result := cookies_table.item (a_name) + Result := wgi_request.input end feature {NONE} -- Access: global variable - items_table: HASH_TABLE [WGI_VALUE, READABLE_STRING_GENERAL] + items_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_8] -- Table containing all the various variables -- Warning: this is computed each time, if you change the content of other containers -- this won't update this Result's content, unless you query it again @@ -651,22 +137,21 @@ feature {NONE} -- Access: global variable loop Result.force (vars.item, vars.item.name) end - end feature -- Access: global variable - items: ITERABLE [WGI_VALUE] + items: ITERABLE [WSF_VALUE] do Result := items_table end - item (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE + item (a_name: READABLE_STRING_8): detachable WSF_VALUE -- Variable named `a_name' from any of the variables container -- and following a specific order -- execution, environment, get, post, cookies local - v: detachable WGI_VALUE + v: detachable WSF_VALUE do v := meta_variable (a_name) if v = Void then @@ -678,20 +163,784 @@ feature -- Access: global variable end end end --- if s /= Void then --- Result := s.as_string_32 --- end end - string_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + string_item (a_name: READABLE_STRING_8): detachable READABLE_STRING_32 do - if attached {WGI_STRING_VALUE} item (a_name) as val then + if attached {WSF_STRING_VALUE} item (a_name) as val then Result := val.string else check is_string_value: False end end end +feature -- Access: CGI Meta variables + + meta_variable (a_name: READABLE_STRING_8): detachable WSF_STRING_VALUE + -- CGI Meta variable related to `a_name' + require + a_name_valid: a_name /= Void and then not a_name.is_empty + do + Result := meta_variables_table.item (a_name) + end + + meta_string_variable (a_name: READABLE_STRING_8): detachable READABLE_STRING_32 + -- CGI meta variable related to `a_name' + require + a_name_valid: a_name /= Void and then not a_name.is_empty + do + if attached meta_variable (a_name) as val then + Result := val.string + end + end + + meta_variables: ITERABLE [WSF_STRING_VALUE] + -- CGI meta variables values + + meta_string_variable_or_default (a_name: READABLE_STRING_8; a_default: READABLE_STRING_32; use_default_when_empty: BOOLEAN): READABLE_STRING_32 + -- Value for meta parameter `a_name' + -- If not found, return `a_default' + require + a_name_not_empty: a_name /= Void and then not a_name.is_empty + do + if attached meta_variable (a_name) as val then + Result := val.string + if use_default_when_empty and then Result.is_empty then + Result := a_default + end + else + Result := a_default + end + end + + set_meta_string_variable (a_name: READABLE_STRING_8; a_value: READABLE_STRING_32) + do + meta_variables_table.force (new_string_value (a_name, a_value), a_name) + ensure + param_set: attached {WSF_STRING_VALUE} meta_variable (a_name) as val and then val ~ a_value + end + + unset_meta_variable (a_name: READABLE_STRING_8) + do + meta_variables_table.remove (a_name) + ensure + param_unset: meta_variable (a_name) = Void + end + +feature {NONE} -- Access: CGI meta parameters + + meta_variables_table: HASH_TABLE [WSF_STRING_VALUE, READABLE_STRING_8] + -- CGI Environment parameters + +feature -- Access: CGI meta parameters - 1.1 + + auth_type: detachable READABLE_STRING_8 + -- This variable is specific to requests made via the "http" + -- scheme. + -- + -- If the Script-URI required access authentication for external + -- access, then the server MUST set the value of this variable + -- from the 'auth-scheme' token in the wgi_request's "Authorization" + -- header field. Otherwise it is set to NULL. + -- + -- AUTH_TYPE = "" | auth-scheme + -- auth-scheme = "Basic" | "Digest" | token + -- + -- HTTP access authentication schemes are described in section 11 + -- of the HTTP/1.1 specification [8]. The auth-scheme is not + -- case-sensitive. + -- + -- Servers MUST provide this metavariable to scripts if the + -- wgi_request header included an "Authorization" field that was + -- authenticated. + do + Result := wgi_request.auth_type + end + + content_length: detachable READABLE_STRING_8 + -- This metavariable is set to the size of the message-body + -- entity attached to the wgi_request, if any, in decimal number of + -- octets. If no data are attached, then this metavariable is + -- either NULL or not defined. The syntax is the same as for the + -- HTTP "Content-Length" header field (section 14.14, HTTP/1.1 + -- specification [8]). + -- + -- CONTENT_LENGTH = "" | 1*digit + -- + -- Servers MUST provide this metavariable to scripts if the + -- wgi_request was accompanied by a message-body entity. + do + Result := wgi_request.content_length + end + + content_length_value: NATURAL_64 + -- Integer value related to `content_length" + + content_type: detachable READABLE_STRING_8 + -- If the wgi_request includes a message-body, CONTENT_TYPE is set to + -- the Internet Media Type [9] of the attached entity if the type + -- was provided via a "Content-type" field in the wgi_request header, + -- or if the server can determine it in the absence of a supplied + -- "Content-type" field. The syntax is the same as for the HTTP + -- "Content-Type" header field. + -- + -- CONTENT_TYPE = "" | media-type + -- media-type = type "/" subtype *( ";" parameter) + -- type = token + -- subtype = token + -- parameter = attribute "=" value + -- attribute = token + -- value = token | quoted-string + -- + -- The type, subtype, and parameter attribute names are not + -- case-sensitive. Parameter values MAY be case sensitive. Media + -- types and their use in HTTP are described in section 3.7 of + -- the HTTP/1.1 specification [8]. + -- + -- Example: + -- + -- application/x-www-form-urlencoded + -- + -- There is no default value for this variable. If and only if it + -- is unset, then the script MAY attempt to determine the media + -- type from the data received. If the type remains unknown, then + -- the script MAY choose to either assume a content-type of + -- application/octet-stream or reject the wgi_request with a 415 + -- ("Unsupported Media Type") error. See section 7.2.1.3 for more + -- information about returning error status values. + -- + -- Servers MUST provide this metavariable to scripts if a + -- "Content-Type" field was present in the original wgi_request + -- header. If the server receives a wgi_request with an attached + -- entity but no "Content-Type" header field, it MAY attempt to + -- determine the correct datatype, or it MAY omit this + -- metavariable when communicating the wgi_request information to the + -- script. + do + Result := wgi_request.content_type + end + + gateway_interface: READABLE_STRING_8 + -- This metavariable is set to the dialect of CGI being used by + -- the server to communicate with the script. Syntax: + -- + -- GATEWAY_INTERFACE = "CGI" "/" major "." minor + -- major = 1*digit + -- minor = 1*digit + -- + -- Note that the major and minor numbers are treated as separate + -- integers and hence each may be more than a single digit. Thus + -- CGI/2.4 is a lower version than CGI/2.13 which in turn is + -- lower than CGI/12.3. Leading zeros in either the major or the + -- minor number MUST be ignored by scripts and SHOULD NOT be + -- generated by servers. + -- + -- This document defines the 1.1 version of the CGI interface + -- ("CGI/1.1"). + -- + -- Servers MUST provide this metavariable to scripts. + -- + -- The version of the CGI specification to which this server + -- complies. Syntax: + -- + -- GATEWAY_INTERFACE = "CGI" "/" 1*digit "." 1*digit + -- + -- Note that the major and minor numbers are treated as separate + -- integers and that each may be incremented higher than a single + -- digit. Thus CGI/2.4 is a lower version than CGI/2.13 which in + -- turn is lower than CGI/12.3. Leading zeros must be ignored by + -- scripts and should never be generated by servers. + do + Result := wgi_request.gateway_interface + end + + path_info: READABLE_STRING_32 + -- The PATH_INFO metavariable specifies a path to be interpreted + -- by the CGI script. It identifies the resource or sub-resource + -- to be returned by the CGI script, and it is derived from the + -- portion of the URI path following the script name but + -- preceding any query data. The syntax and semantics are similar + -- to a decoded HTTP URL 'path' token (defined in RFC 2396 [4]), + -- with the exception that a PATH_INFO of "/" represents a single + -- void path segment. + -- + -- PATH_INFO = "" | ( "/" path ) + -- path = segment *( "/" segment ) + -- segment = *pchar + -- pchar = + -- + -- The PATH_INFO string is the trailing part of the + -- component of the Script-URI (see section 3.2) that follows the + -- SCRIPT_NAME portion of the path. + -- + -- Servers MAY impose their own restrictions and limitations on + -- what values they will accept for PATH_INFO, and MAY reject or + -- edit any values they consider objectionable before passing + -- them to the script. + -- + -- Servers MUST make this URI component available to CGI scripts. + -- The PATH_INFO value is case-sensitive, and the server MUST + -- preserve the case of the PATH_INFO element of the URI when + -- making it available to scripts. + + path_translated: detachable READABLE_STRING_32 + -- PATH_TRANSLATED is derived by taking any path-info component + -- of the wgi_request URI (see section 6.1.6), decoding it (see + -- section 3.1), parsing it as a URI in its own right, and + -- performing any virtual-to-physical translation appropriate to + -- map it onto the server's document repository structure. If the + -- wgi_request URI includes no path-info component, the + -- PATH_TRANSLATED metavariable SHOULD NOT be defined. + -- + -- + -- PATH_TRANSLATED = *CHAR + -- + -- For a wgi_request such as the following: + -- + -- http://somehost.com/cgi-bin/somescript/this%2eis%2epath%2einfo + -- + -- the PATH_INFO component would be decoded, and the result + -- parsed as though it were a wgi_request for the following: + -- + -- http://somehost.com/this.is.the.path.info + -- + -- This would then be translated to a location in the server's + -- document repository, perhaps a filesystem path something like + -- this: + -- + -- /usr/local/www/htdocs/this.is.the.path.info + -- + -- The result of the translation is the value of PATH_TRANSLATED. + -- + -- The value of PATH_TRANSLATED may or may not map to a valid + -- repository location. Servers MUST preserve the case of the + -- path-info segment if and only if the underlying repository + -- supports case-sensitive names. If the repository is only + -- case-aware, case-preserving, or case-blind with regard to + -- document names, servers are not required to preserve the case + -- of the original segment through the translation. + -- + -- The translation algorithm the server uses to derive + -- PATH_TRANSLATED is implementation defined; CGI scripts which + -- use this variable may suffer limited portability. + -- + -- Servers SHOULD provide this metavariable to scripts if and + -- only if the wgi_request URI includes a path-info component. + + query_string: READABLE_STRING_8 + -- A URL-encoded string; the part of the Script-URI. (See + -- section 3.2.) + -- + -- QUERY_STRING = query-string + -- query-string = *uric + + -- The URL syntax for a query string is described in section 3 of + -- RFC 2396 [4]. + -- + -- Servers MUST supply this value to scripts. The QUERY_STRING + -- value is case-sensitive. If the Script-URI does not include a + -- query component, the QUERY_STRING metavariable MUST be defined + -- as an empty string (""). + do + Result := wgi_request.query_string + end + + remote_addr: READABLE_STRING_8 + -- The IP address of the client sending the wgi_request to the + -- server. This is not necessarily that of the user agent (such + -- as if the wgi_request came through a proxy). + -- + -- REMOTE_ADDR = hostnumber + -- hostnumber = ipv4-address | ipv6-address + + -- The definitions of ipv4-address and ipv6-address are provided + -- in Appendix B of RFC 2373 [13]. + -- + -- Servers MUST supply this value to scripts. + do + Result := wgi_request.remote_addr + end + + remote_host: detachable READABLE_STRING_8 + -- The fully qualified domain name of the client sending the + -- wgi_request to the server, if available, otherwise NULL. (See + -- section 6.1.9.) Fully qualified domain names take the form as + -- described in section 3.5 of RFC 1034 [10] and section 2.1 of + -- RFC 1123 [5]. Domain names are not case sensitive. + -- + -- Servers SHOULD provide this information to scripts. + do + Result := wgi_request.remote_host + end + + remote_ident: detachable READABLE_STRING_8 + -- The identity information reported about the connection by a + -- RFC 1413 [11] wgi_request to the remote agent, if available. + -- Servers MAY choose not to support this feature, or not to + -- wgi_request the data for efficiency reasons. + -- + -- REMOTE_IDENT = *CHAR + -- + -- The data returned may be used for authentication purposes, but + -- the level of trust reposed in them should be minimal. + -- + -- Servers MAY supply this information to scripts if the RFC1413 + -- [11] lookup is performed. + do + Result := wgi_request.remote_ident + end + + remote_user: detachable READABLE_STRING_8 + -- If the wgi_request required authentication using the "Basic" + -- mechanism (i.e., the AUTH_TYPE metavariable is set to + -- "Basic"), then the value of the REMOTE_USER metavariable is + -- set to the user-ID supplied. In all other cases the value of + -- this metavariable is undefined. + -- + -- REMOTE_USER = *OCTET + -- + -- This variable is specific to requests made via the HTTP + -- protocol. + -- + -- Servers SHOULD provide this metavariable to scripts. + do + Result := wgi_request.remote_user + end + + request_method: READABLE_STRING_8 + -- The REQUEST_METHOD metavariable is set to the method with + -- which the wgi_request was made, as described in section 5.1.1 of + -- the HTTP/1.0 specification [3] and section 5.1.1 of the + -- HTTP/1.1 specification [8]. + -- + -- REQUEST_METHOD = http-method + -- http-method = "GET" | "HEAD" | "POST" | "PUT" | "DELETE" + -- | "OPTIONS" | "TRACE" | extension-method + -- extension-method = token + -- + -- The method is case sensitive. CGI/1.1 servers MAY choose to + -- process some methods directly rather than passing them to + -- scripts. + -- + -- This variable is specific to requests made with HTTP. + -- + -- Servers MUST provide this metavariable to scripts. + do + Result := wgi_request.request_method + end + + script_name: READABLE_STRING_8 + -- The SCRIPT_NAME metavariable is set to a URL path that could + -- identify the CGI script (rather than the script's output). The + -- syntax and semantics are identical to a decoded HTTP URL + -- 'path' token (see RFC 2396 [4]). + -- + -- SCRIPT_NAME = "" | ( "/" [ path ] ) + -- + -- The SCRIPT_NAME string is some leading part of the + -- component of the Script-URI derived in some implementation + -- defined manner. No PATH_INFO or QUERY_STRING segments (see + -- sections 6.1.6 and 6.1.8) are included in the SCRIPT_NAME + -- value. + -- + -- Servers MUST provide this metavariable to scripts. + do + Result := wgi_request.script_name + end + + server_name: READABLE_STRING_8 + -- The SERVER_NAME metavariable is set to the name of the server, + -- as derived from the part of the Script-URI (see section + -- 3.2). + -- + -- SERVER_NAME = hostname | hostnumber + -- + -- Servers MUST provide this metavariable to scripts. + do + Result := wgi_request.server_name + end + + server_port: INTEGER + -- The SERVER_PORT metavariable is set to the port on which the + -- wgi_request was received, as used in the part of the + -- Script-URI. + -- + -- SERVER_PORT = 1*digit + -- + -- If the portion of the script-URI is blank, the actual + -- port number upon which the wgi_request was received MUST be + -- supplied. + -- + -- Servers MUST provide this metavariable to scripts. + do + Result := wgi_request.server_port + end + + server_protocol: READABLE_STRING_8 + -- The SERVER_PROTOCOL metavariable is set to the name and + -- revision of the information protocol with which the wgi_request + -- arrived. This is not necessarily the same as the protocol + -- version used by the server in its response to the client. + -- + -- SERVER_PROTOCOL = HTTP-Version | extension-version + -- | extension-token + -- HTTP-Version = "HTTP" "/" 1*digit "." 1*digit + -- extension-version = protocol "/" 1*digit "." 1*digit + -- protocol = 1*( alpha | digit | "+" | "-" | "." ) + -- extension-token = token + -- + -- 'protocol' is a version of the part of the + -- Script-URI, but is not identical to it. For example, the + -- scheme of a wgi_request may be "https" while the protocol remains + -- "http". The protocol is not case sensitive, but by convention, + -- 'protocol' is in upper case. + -- + -- A well-known extension token value is "INCLUDED", which + -- signals that the current document is being included as part of + -- a composite document, rather than being the direct target of + -- the client wgi_request. + -- + -- Servers MUST provide this metavariable to scripts. + do +-- check not_yet_implemented: False then end + Result := wgi_request.server_protocol + end + + server_software: READABLE_STRING_8 + -- The SERVER_SOFTWARE metavariable is set to the name and + -- version of the information server software answering the + -- wgi_request (and running the gateway). + -- + -- SERVER_SOFTWARE = 1*product + -- product = token [ "/" product-version ] + -- product-version = token + + -- Servers MUST provide this metavariable to scripts. + do +-- check not_yet_implemented: False then end + Result := wgi_request.server_software + end + +feature -- HTTP_* + + http_accept: detachable READABLE_STRING_8 + -- Contents of the Accept: header from the current wgi_request, if there is one. + -- Example: 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' + do + Result := wgi_request.http_accept + end + + http_accept_charset: detachable READABLE_STRING_8 + -- Contents of the Accept-Charset: header from the current wgi_request, if there is one. + -- Example: 'iso-8859-1,*,utf-8'. + do + Result := wgi_request.http_accept_charset + end + + http_accept_encoding: detachable READABLE_STRING_8 + -- Contents of the Accept-Encoding: header from the current wgi_request, if there is one. + -- Example: 'gzip'. + do + Result := wgi_request.http_accept_encoding + end + + http_accept_language: detachable READABLE_STRING_8 + -- Contents of the Accept-Language: header from the current wgi_request, if there is one. + -- Example: 'en'. + do + Result := wgi_request.http_accept_language + end + + http_connection: detachable READABLE_STRING_8 + -- Contents of the Connection: header from the current wgi_request, if there is one. + -- Example: 'Keep-Alive'. + do + Result := wgi_request.http_connection + end + + http_host: detachable READABLE_STRING_8 + -- Contents of the Host: header from the current wgi_request, if there is one. + do + Result := wgi_request.http_host + end + + http_referer: detachable READABLE_STRING_8 + -- The address of the page (if any) which referred the user agent to the current page. + -- This is set by the user agent. + -- Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. + -- In short, it cannot really be trusted. + do + Result := wgi_request.http_referer + end + + http_user_agent: detachable READABLE_STRING_8 + -- Contents of the User-Agent: header from the current wgi_request, if there is one. + -- This is a string denoting the user agent being which is accessing the page. + -- A typical example is: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586). + -- Among other things, you can use this value to tailor your page's + -- output to the capabilities of the user agent. + do + Result := wgi_request.http_user_agent + end + + http_authorization: detachable READABLE_STRING_8 + -- Contents of the Authorization: header from the current wgi_request, if there is one. + do + Result := wgi_request.http_authorization + end + +feature -- Extra CGI environment variables + + request_uri: READABLE_STRING_8 + -- The URI which was given in order to access this page; for instance, '/index.html'. + do + Result := wgi_request.request_uri + end + + orig_path_info: detachable READABLE_STRING_8 + -- Original version of `path_info' before processed by Current environment + do + Result := wgi_request.orig_path_info + end + + request_time: detachable DATE_TIME + -- Request time (UTC) + do + if + attached {WSF_STRING_VALUE} meta_variable ({CGI_META_NAMES}.request_time) as t and then + t.string.is_integer_64 + then + Result := date_time_utilities.unix_time_stamp_to_date_time (t.string.to_integer_64) + end + end + +feature -- Cookies + + cookies: ITERABLE [WSF_VALUE] + do + Result := cookies_table + end + + cookie (a_name: READABLE_STRING_8): detachable WSF_VALUE + -- Field for name `a_name'. + do + Result := cookies_table.item (a_name) + end + +feature {NONE} -- Cookies + + cookies_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_32] + -- Expanded cookies variable + local + i,j,p,n: INTEGER + l_cookies: like internal_cookies_table + k,v,s: STRING + do + l_cookies := internal_cookies_table + if l_cookies = Void then + if attached {WSF_STRING_VALUE} meta_variable ({CGI_META_NAMES}.http_cookie) as val then + s := val.string + create l_cookies.make (5) + l_cookies.compare_objects + from + n := s.count + p := 1 + i := 1 + until + p < 1 + loop + i := s.index_of ('=', p) + if i > 0 then + j := s.index_of (';', i) + if j = 0 then + j := n + 1 + k := s.substring (p, i - 1) + v := s.substring (i + 1, n) + + p := 0 -- force termination + else + k := s.substring (p, i - 1) + v := s.substring (i + 1, j - 1) + p := j + 1 + end + add_value_to_table (k, v, l_cookies) + end + end + else + create l_cookies.make (0) + l_cookies.compare_objects + end + internal_cookies_table := l_cookies + end + Result := l_cookies + end + +feature -- Query parameters + + query_parameters: ITERABLE [WSF_VALUE] + do + Result := query_parameters_table + end + + query_parameter (a_name: READABLE_STRING_32): detachable WSF_VALUE + -- Parameter for name `n'. + do + Result := query_parameters_table.item (a_name) + end + +feature {NONE} -- Query parameters: implementation + + query_parameters_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_32] + -- Variables extracted from QUERY_STRING + local + vars: like internal_query_parameters_table + p,e: INTEGER + rq_uri: like request_uri + s: detachable STRING + do + vars := internal_query_parameters_table + if vars = Void then + s := query_string + if s = Void then + rq_uri := request_uri + p := rq_uri.index_of ('?', 1) + if p > 0 then + e := rq_uri.index_of ('#', p + 1) + if e = 0 then + e := rq_uri.count + else + e := e - 1 + end + s := rq_uri.substring (p+1, e) + end + end + vars := urlencoded_parameters (s) + vars.compare_objects + internal_query_parameters_table := vars + end + Result := vars + end + + urlencoded_parameters (a_content: detachable READABLE_STRING_8): HASH_TABLE [WSF_VALUE, READABLE_STRING_32] + -- Import `a_content' + local + n, p, i, j: INTEGER + s: READABLE_STRING_8 + l_name, l_value: READABLE_STRING_8 + do + if a_content = Void then + create Result.make (0) + else + n := a_content.count + if n = 0 then + create Result.make (0) + else + create Result.make (3) + from + p := 1 + until + p = 0 + loop + i := a_content.index_of ('&', p) + if i = 0 then + s := a_content.substring (p, n) + p := 0 + else + s := a_content.substring (p, i - 1) + p := i + 1 + end + if not s.is_empty then + j := s.index_of ('=', 1) + if j > 0 then + l_name := s.substring (1, j - 1) + l_value := s.substring (j + 1, s.count) + add_value_to_table (l_name, l_value, Result) + end + end + end + end + end + end + + add_value_to_table (a_name: READABLE_STRING_32; a_value: READABLE_STRING_32; a_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]) + local + v: WSF_VALUE + do + v := new_string_value (a_name, a_value) + if a_table.has_key (v.name) and then attached a_table.found_item as l_existing_value then + if attached {WSF_MULTIPLE_STRING_VALUE} l_existing_value as l_multi then + l_multi.add_value (v) + else + a_table.force (create {WSF_MULTIPLE_STRING_VALUE}.make_with_array (<>), v.name) + check replaced: a_table.found and then a_table.found_item ~ l_existing_value end + end + else + a_table.force (v, v.name) + end + end + +feature -- Form fields and related + + form_data_parameters: ITERABLE [WSF_VALUE] + do + Result := form_data_parameters_table + end + + form_data_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE + -- Field for name `a_name'. + do + Result := form_data_parameters_table.item (a_name) + end + + uploaded_files: HASH_TABLE [WGI_UPLOADED_FILE_DATA, STRING] + -- Table of uploaded files information + --| name: original path from the user + --| type: content type + --| tmp_name: path to temp file that resides on server + --| tmp_base_name: basename of `tmp_name' + --| error: if /= 0 , there was an error : TODO ... + --| size: size of the file given by the http request + +feature {NONE} -- Form fields and related + + form_data_parameters_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_32] + -- Variables sent by POST request + local + vars: like internal_form_data_parameters_table + s: STRING + n: NATURAL_64 + l_type: like content_type + do + vars := internal_form_data_parameters_table + if vars = Void then + n := content_length_value + if n > 0 then + l_type := content_type + if + l_type /= Void and then + l_type.starts_with ({HTTP_MIME_TYPES}.multipart_form_data) + then + create vars.make (5) + vars.compare_objects + --| FIXME: optimization ... fetch the input data progressively, otherwise we might run out of memory ... + s := form_input_data (n.to_integer_32) --| FIXME truncated from NAT64 to INT32 + analyze_multipart_form (l_type, s, vars) + else + s := form_input_data (n.to_integer_32) --| FIXME truncated from NAT64 to INT32 + vars := urlencoded_parameters (s) + end + if raw_post_data_recorded then + set_meta_string_variable ("RAW_POST_DATA", s) + end + else + create vars.make (0) + vars.compare_objects + end + internal_form_data_parameters_table := vars + end + Result := vars + end + feature -- Uploaded File Handling is_uploaded_file (a_filename: STRING): BOOLEAN @@ -771,7 +1020,7 @@ feature -- URL Utility feature {NONE} -- Implementation: URL Utility internal_url_base: detachable STRING - -- URL base of potential script + -- URL base of potential script feature -- Element change @@ -1076,7 +1325,7 @@ feature {NONE} -- Implementation: Form analyzer save_uploaded_file (l_content, l_up_file_info) uploaded_files.force (l_up_file_info, l_name) else - vars_post.force (new_string_value (l_name, l_content), l_name) + add_value_to_table (l_name, l_content, vars_post) end else error_handler.add_custom_error (0, "unamed multipart entry", Void) @@ -1144,7 +1393,7 @@ feature {NONE} -- Implementation report_bad_request_error (a_message: detachable STRING) -- Report error local - e: EWF_ERROR + e: WSF_ERROR do create e.make ({HTTP_STATUS_CODE}.bad_request) if a_message /= Void then @@ -1156,7 +1405,7 @@ feature {NONE} -- Implementation analyze -- Extract relevant meta parameters local - s: detachable READABLE_STRING_32 + s: detachable READABLE_STRING_8 do s := request_uri if s.is_empty then @@ -1174,9 +1423,6 @@ feature {NONE} -- Implementation report_bad_request_error ("Missing host header") end end - if not has_error then - update_path_info - end end feature {NONE} -- Implementation: utilities @@ -1227,7 +1473,7 @@ feature {NONE} -- Implementation: utilities one_starting_slash: Result[1] = '/' and (Result.count = 1 or else Result[2] /= '/') end - new_string_value (a_name: READABLE_STRING_GENERAL; a_value: READABLE_STRING_32): WGI_STRING_VALUE + new_string_value (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8): WSF_STRING_VALUE do create Result.make (a_name, a_value) end @@ -1249,14 +1495,5 @@ feature {NONE} -- Implementation: utilities invariant empty_string_unchanged: empty_string.is_empty -note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" + end diff --git a/library/server/wsf/src/wsf_response.e b/library/server/wsf/src/wsf_response.e new file mode 100644 index 00000000..13f6278e --- /dev/null +++ b/library/server/wsf/src/wsf_response.e @@ -0,0 +1,164 @@ +note + description: "[ + Summary description for {WSF_RESPONSE}. + ]" + date: "$Date$" + revision: "$Revision$" + +class + WSF_RESPONSE + +create {WSF_APPLICATION} + make_from_wgi + +convert + make_from_wgi ({WGI_RESPONSE_BUFFER}) + +feature {NONE} -- Initialization + + make_from_wgi (r: WGI_RESPONSE_BUFFER) + do + wgi_response := r + end + + wgi_response: WGI_RESPONSE_BUFFER + +--feature {WSF_APPLICATION} -- Commit + +-- commit +-- -- Commit the current response +-- do +-- wgi_response.commit +-- ensure +-- status_is_set: status_is_set +-- header_committed: header_committed +-- message_committed: message_committed +-- end + +feature -- Status report + + header_committed: BOOLEAN + -- Header committed? + do + Result := wgi_response.header_committed + end + + message_committed: BOOLEAN + -- Message committed? + do + Result := wgi_response.message_committed + end + + message_writable: BOOLEAN + -- Can message be written? + do + Result := wgi_response.message_writable + end + +--feature {WGI_RESPONSE_BUFFER} -- Core output operation + +-- write (s: READABLE_STRING_8) +-- -- Send the string `s' +-- -- this can be used for header and body +-- do +-- wgi_response.write (s) +-- end + +feature -- Status setting + + status_is_set: BOOLEAN + -- Is status set? + do + Result := wgi_response.status_is_set + end + + set_status_code (a_code: INTEGER) + -- Set response status code + -- Should be done before sending any data back to the client + require + status_not_set: not status_is_set + header_not_committed: not header_committed + do + wgi_response.set_status_code (a_code) + ensure + status_code_set: status_code = a_code + status_set: status_is_set + end + + status_code: INTEGER + -- Response status + do + Result := wgi_response.status_code + end + +feature -- Header output operation + + write_headers_string (a_headers: READABLE_STRING_8) + require + status_set: status_is_set + header_not_committed: not header_committed + do + wgi_response.write_headers_string (a_headers) + ensure + status_set: status_is_set + header_committed: header_committed + message_writable: message_writable + end + + write_header (a_status_code: INTEGER; a_headers: detachable ARRAY [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]]) + -- Send headers with status `a_status', and headers from `a_headers' + require + status_not_set: not status_is_set + header_not_committed: not header_committed + do + wgi_response.write_header (a_status_code, a_headers) + ensure + header_committed: header_committed + status_set: status_is_set + message_writable: message_writable + end + +feature -- Output operation + + write_string (s: READABLE_STRING_8) + -- Send the string `s' + require + message_writable: message_writable + do + wgi_response.write_string (s) + end + + write_substring (s: READABLE_STRING_8; a_begin_index, a_end_index: INTEGER) + -- Send the substring `s[a_begin_index:a_end_index]' + require + message_writable: message_writable + do + wgi_response.write_substring (s, a_begin_index, a_end_index) + end + + write_file_content (fn: READABLE_STRING_8) + -- Send the content of file `fn' + require + message_writable: message_writable + do + wgi_response.write_file_content (fn) + end + + flush + -- Flush if it makes sense + do + wgi_response.flush + end + +note + copyright: "2011-2011, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" + +end diff --git a/library/server/ewsgi/tests/test_ewsgi_request.e b/library/server/wsf/tests/test_wsf_request.e similarity index 96% rename from library/server/ewsgi/tests/test_ewsgi_request.e rename to library/server/wsf/tests/test_wsf_request.e index 9f0a7be7..3ddcf576 100644 --- a/library/server/ewsgi/tests/test_ewsgi_request.e +++ b/library/server/wsf/tests/test_wsf_request.e @@ -17,6 +17,11 @@ inherit on_clean end + WSF_APPLICATION + undefine + default_create + end + feature {NONE} -- Events web_app: detachable NINO_APPLICATION @@ -33,7 +38,7 @@ feature {NONE} -- Events do port_number := 8087 base_url := "test/" - create app.make_custom (agent execute, base_url) + create app.make_custom (agent wgi_execute, base_url) web_app := app create wt.make (agent app.listen (port_number)) @@ -43,7 +48,7 @@ feature {NONE} -- Events e.sleep (1_000_000_000 * 5) end - execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute (req: WSF_REQUEST; res: WSF_RESPONSE) local q: detachable STRING_32 do diff --git a/library/server/ewsgi/tests/tests-safe.ecf b/library/server/wsf/tests/tests-safe.ecf similarity index 77% rename from library/server/ewsgi/tests/tests-safe.ecf rename to library/server/wsf/tests/tests-safe.ecf index fa29a674..bf9302f3 100644 --- a/library/server/ewsgi/tests/tests-safe.ecf +++ b/library/server/wsf/tests/tests-safe.ecf @@ -1,5 +1,5 @@ - + @@ -11,11 +11,11 @@ - - + + - + diff --git a/library/server/ewsgi/tests/tests.ecf b/library/server/wsf/tests/tests.ecf similarity index 84% rename from library/server/ewsgi/tests/tests.ecf rename to library/server/wsf/tests/tests.ecf index 7f5a6e87..553a52f7 100644 --- a/library/server/ewsgi/tests/tests.ecf +++ b/library/server/wsf/tests/tests.ecf @@ -1,5 +1,5 @@ - + @@ -11,8 +11,8 @@ - - + + diff --git a/library/server/wsf/wsf-safe.ecf b/library/server/wsf/wsf-safe.ecf new file mode 100644 index 00000000..ac1ee700 --- /dev/null +++ b/library/server/wsf/wsf-safe.ecf @@ -0,0 +1,20 @@ + + + + + + /.git$ + /EIFGENs$ + /.svn$ + + + + + + + + + + + diff --git a/library/server/wsf/wsf.ecf b/library/server/wsf/wsf.ecf new file mode 100644 index 00000000..db6b6daf --- /dev/null +++ b/library/server/wsf/wsf.ecf @@ -0,0 +1,20 @@ + + + + + + /.git$ + /EIFGENs$ + /.svn$ + + + + + + + + + + +