Ketchup 0.1.1 → 0.1.2
raw patch · 67 files changed
+205/−78 lines, 67 filesdep +regex-posixbinary-addedPVP ok
version bump matches the API change (PVP)
Dependencies added: regex-posix
API changes (from Hackage documentation)
Files
- .git/COMMIT_EDITMSG +0/−1
- .git/FETCH_HEAD +1/−0
- .git/ORIG_HEAD +1/−0
- .git/config +1/−1
- .git/hooks/pre-rebase.sample +1/−1
- .git/hooks/prepare-commit-msg.sample +2/−2
- .git/index binary
- .git/logs/HEAD +2/−12
- .git/logs/refs/heads/master +2/−12
- .git/logs/refs/remotes/origin/HEAD +1/−0
- .git/logs/refs/remotes/origin/master +1/−11
- .git/objects/02/ffa07f6990f74dafd8c9ce6d8fa39b0976d598 binary
- .git/objects/10/93f2858a4572a7a141c96f251f273da4d55c89 binary
- .git/objects/11/c683f96aaed8fc5cad03cb58c5d1a5cec5f501 binary
- .git/objects/23/8fd86cd3c476d75eec0d7ae736adb96dd1cc60 binary
- .git/objects/24/e1f1b0b0f51b252eebca5b168a4e17b4700a4c binary
- .git/objects/2c/b647573d63d84667f629ea1e26e53bd3f16e44 binary
- .git/objects/2d/d01b33323df8fd6ac686cc492d77822e040e1f binary
- .git/objects/32/4d07aa12666c2f03139f626361d1a810c45bc1 +0/−1
- .git/objects/35/3e50d70c86a2ab186edac1c205561befde3dc7 binary
- .git/objects/36/d1bfaedb400023ee2b6ced7d3847183c454838 +0/−2
- .git/objects/45/3bd93c26a9e271a06ba2646d2fed80284a3d7e binary
- .git/objects/45/fa42399476a801f23b96599909ab8939757cd4 binary
- .git/objects/49/c47bca8a7edae0d0851b71284aa6b39a400cc4 binary
- .git/objects/56/2c5d11641eeb9f7ae77cd0d177fd8c947ed1e9 binary
- .git/objects/58/4b0ea086479c87718b10715c5375a4715e6965 binary
- .git/objects/5c/ad4e38d5d9795fd867fe17bdc34c18ac26dfc6 binary
- .git/objects/62/2888f76a4bd37398710e1590463719c2129297 +0/−2
- .git/objects/63/3f2583dc912547dc4bbb06de8bd1a7c275fcf2 binary
- .git/objects/66/5fba0e7ceccafda2b2a4e92e342ff2cbfe8247 +0/−2
- .git/objects/69/367db2a6835d21762b09eec97395dd0f1d503e binary
- .git/objects/6d/d1040ce0fbc93348725498c912f0e19175d433 binary
- .git/objects/70/8b4d9119f776f28cc85a2a0f58b4bf1c1e7b43 +0/−2
- .git/objects/72/2f61d1774f7fbd456a5ab611c54408e61f2cc6 binary
- .git/objects/81/ef35d79e1603434714aaa57410da0fa9f71e6e binary
- .git/objects/85/2ae7db61bff45b972b9a21023e162f5003d74d +0/−1
- .git/objects/85/d7f3da362229792ee03571c10da871b205a69f binary
- .git/objects/85/df8a78c3966d87d24b5e8eac0a2bdcbf243c47 binary
- .git/objects/8a/4e26e09c96d9bd95bbefa4c2cde4fbf8087382 +0/−1
- .git/objects/93/ac39e13883ec31ab749f768d790b6b14a0193d binary
- .git/objects/a4/52888e3b29d25f2f4b06e3f1cae1ddba210add +0/−1
- .git/objects/b1/97449e22aa6e00dcbb765294c13b957ad35207 +0/−3
- .git/objects/b6/3279c85b76f94cc28de65c1a8c2f65c1814e7e binary
- .git/objects/c1/ef5202b4e0351ba9c95229c0edf7dfbfb9bb33 +0/−2
- .git/objects/c6/56325a56d86c044bb5136b9e8dafa421c4f758 binary
- .git/objects/cf/34a7265591f7c3f2d241bd7a554e96c85c68d5 binary
- .git/objects/cf/ed5d601e7c6661a4c95c652d865834a2960cc4 +0/−1
- .git/objects/d7/52cbde2090cf51b382e0060e0d13a90ef9dfa8 +0/−1
- .git/objects/de/16c2da1cc71609774e151a4e6034c07965db8c binary
- .git/objects/df/0eddb596d9d9aff78156e3cae6300250de9155 binary
- .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 binary
- .git/objects/e8/7a4422a7db2bee721ce1a88d5286ca1570d36a binary
- .git/objects/ed/eeef90bd35a9192643cb4fd5f6e108171fadb4 binary
- .git/objects/f3/073c846e4efaa3a1997750b01c078c36a14718 binary
- .git/objects/fb/f8eefabf8c61b21569f198ed873cc8558acd68 +0/−3
- .git/objects/pack/pack-5ae4b09f7084bd1231ef67774ae0cc24689625e4.idx binary
- .git/objects/pack/pack-5ae4b09f7084bd1231ef67774ae0cc24689625e4.pack binary
- .git/packed-refs +2/−0
- .git/refs/remotes/origin/HEAD +1/−0
- Ketchup.cabal +3/−2
- Ketchup.cabal~ +4/−3
- Ketchup/.Routing.hs.swp binary
- Ketchup/Httpd.hs +1/−1
- Ketchup/Httpd.hs~ +138/−0
- Ketchup/Routing.hs +3/−2
- Ketchup/Routing.hs~ +41/−0
- Makefile~ +0/−8
@@ -1,1 +0,0 @@-Removed SERVER header and set to 0.1.1
@@ -0,0 +1,1 @@+2e95147d7a2c86bb224527a5624c118b53f9c736 branch 'master' of github.com:Hamcha/Ketchup
@@ -0,0 +1,1 @@+6dd1040ce0fbc93348725498c912f0e19175d433
@@ -4,7 +4,7 @@ bare = false logallrefupdates = true [remote "origin"]- url = git@github.com:Hamcha/ketchup.git+ url = git@github.com:Hamcha/Ketchup.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin
@@ -65,7 +65,7 @@ fi else not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`- /usr/local/bin/perl -e '+ /usr/bin/perl -e ' my $topic = $ARGV[0]; my $msg = "* $topic has commits already merged to public branch:\n"; my (%not_in_next) = map {
@@ -22,10 +22,10 @@ case "$2,$3" in merge,)- /usr/local/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;+ /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; # ,|template,)-# /usr/local/bin/perl -i.bak -pe '+# /usr/bin/perl -i.bak -pe ' # print "\n" . `git diff --cached --name-status -r` # if /^#/ && $first++ == 0' "$1" ;;
binary file changed (896 → 896 bytes)
@@ -1,12 +1,2 @@-0000000000000000000000000000000000000000 c1ef5202b4e0351ba9c95229c0edf7dfbfb9bb33 Hamcha <zikyky@gmail.com> 1400868061 +0200 commit (initial): Base commit (most code from httpd)-c1ef5202b4e0351ba9c95229c0edf7dfbfb9bb33 b197449e22aa6e00dcbb765294c13b957ad35207 Hamcha <zikyky@gmail.com> 1400868225 +0200 commit: Took some useless stuff out-b197449e22aa6e00dcbb765294c13b957ad35207 622888f76a4bd37398710e1590463719c2129297 Hamcha <zikyky@gmail.com> 1400868258 +0200 commit: .gitignore to avoid commiting binaries or object files-622888f76a4bd37398710e1590463719c2129297 d752cbde2090cf51b382e0060e0d13a90ef9dfa8 Hamcha <zikyky@gmail.com> 1400871180 +0200 commit: Basic routing should work-d752cbde2090cf51b382e0060e0d13a90ef9dfa8 708b4d9119f776f28cc85a2a0f58b4bf1c1e7b43 Hamcha <zikyky@gmail.com> 1400871591 +0200 commit: Added types-708b4d9119f776f28cc85a2a0f58b4bf1c1e7b43 722f61d1774f7fbd456a5ab611c54408e61f2cc6 Hamcha <zikyky@gmail.com> 1400872235 +0200 commit: Replaced incorrect 400 errors with 404 ones-722f61d1774f7fbd456a5ab611c54408e61f2cc6 1093f2858a4572a7a141c96f251f273da4d55c89 Hamcha <zikyky@gmail.com> 1400884141 +0200 commit: Removed some oleg sauce-1093f2858a4572a7a141c96f251f273da4d55c89 cf34a7265591f7c3f2d241bd7a554e96c85c68d5 Hamcha <zikyky@gmail.com> 1400935032 +0200 commit: Hackage stuff-cf34a7265591f7c3f2d241bd7a554e96c85c68d5 6dd1040ce0fbc93348725498c912f0e19175d433 Hamcha <zikyky@gmail.com> 1400936077 +0200 commit: README-6dd1040ce0fbc93348725498c912f0e19175d433 691816444999b3c2b424bdcef7eeb977fa8b18a5 Hamcha <zikyky@gmail.com> 1400953254 +0200 commit: Chunked encoding-691816444999b3c2b424bdcef7eeb977fa8b18a5 ab41fa19ef0fbeb0088d8f325b1dc4280cbe9817 Hamcha <zikyky@gmail.com> 1400953623 +0200 commit: Forgot to make it visible-ab41fa19ef0fbeb0088d8f325b1dc4280cbe9817 2e95147d7a2c86bb224527a5624c118b53f9c736 Hamcha <zikyky@gmail.com> 1400960297 +0200 commit: Removed SERVER header and set to 0.1.1+0000000000000000000000000000000000000000 6dd1040ce0fbc93348725498c912f0e19175d433 hamcha <hamcha@localhost.localdomain> 1400936747 +0200 clone: from git@github.com:Hamcha/Ketchup.git+6dd1040ce0fbc93348725498c912f0e19175d433 2e95147d7a2c86bb224527a5624c118b53f9c736 hamcha <hamcha@localhost.localdomain> 1400972318 +0200 pull: Fast-forward
@@ -1,12 +1,2 @@-0000000000000000000000000000000000000000 c1ef5202b4e0351ba9c95229c0edf7dfbfb9bb33 Hamcha <zikyky@gmail.com> 1400868061 +0200 commit (initial): Base commit (most code from httpd)-c1ef5202b4e0351ba9c95229c0edf7dfbfb9bb33 b197449e22aa6e00dcbb765294c13b957ad35207 Hamcha <zikyky@gmail.com> 1400868225 +0200 commit: Took some useless stuff out-b197449e22aa6e00dcbb765294c13b957ad35207 622888f76a4bd37398710e1590463719c2129297 Hamcha <zikyky@gmail.com> 1400868258 +0200 commit: .gitignore to avoid commiting binaries or object files-622888f76a4bd37398710e1590463719c2129297 d752cbde2090cf51b382e0060e0d13a90ef9dfa8 Hamcha <zikyky@gmail.com> 1400871180 +0200 commit: Basic routing should work-d752cbde2090cf51b382e0060e0d13a90ef9dfa8 708b4d9119f776f28cc85a2a0f58b4bf1c1e7b43 Hamcha <zikyky@gmail.com> 1400871591 +0200 commit: Added types-708b4d9119f776f28cc85a2a0f58b4bf1c1e7b43 722f61d1774f7fbd456a5ab611c54408e61f2cc6 Hamcha <zikyky@gmail.com> 1400872235 +0200 commit: Replaced incorrect 400 errors with 404 ones-722f61d1774f7fbd456a5ab611c54408e61f2cc6 1093f2858a4572a7a141c96f251f273da4d55c89 Hamcha <zikyky@gmail.com> 1400884141 +0200 commit: Removed some oleg sauce-1093f2858a4572a7a141c96f251f273da4d55c89 cf34a7265591f7c3f2d241bd7a554e96c85c68d5 Hamcha <zikyky@gmail.com> 1400935032 +0200 commit: Hackage stuff-cf34a7265591f7c3f2d241bd7a554e96c85c68d5 6dd1040ce0fbc93348725498c912f0e19175d433 Hamcha <zikyky@gmail.com> 1400936077 +0200 commit: README-6dd1040ce0fbc93348725498c912f0e19175d433 691816444999b3c2b424bdcef7eeb977fa8b18a5 Hamcha <zikyky@gmail.com> 1400953254 +0200 commit: Chunked encoding-691816444999b3c2b424bdcef7eeb977fa8b18a5 ab41fa19ef0fbeb0088d8f325b1dc4280cbe9817 Hamcha <zikyky@gmail.com> 1400953623 +0200 commit: Forgot to make it visible-ab41fa19ef0fbeb0088d8f325b1dc4280cbe9817 2e95147d7a2c86bb224527a5624c118b53f9c736 Hamcha <zikyky@gmail.com> 1400960297 +0200 commit: Removed SERVER header and set to 0.1.1+0000000000000000000000000000000000000000 6dd1040ce0fbc93348725498c912f0e19175d433 hamcha <hamcha@localhost.localdomain> 1400936747 +0200 clone: from git@github.com:Hamcha/Ketchup.git+6dd1040ce0fbc93348725498c912f0e19175d433 2e95147d7a2c86bb224527a5624c118b53f9c736 hamcha <hamcha@localhost.localdomain> 1400972318 +0200 pull: Fast-forward
@@ -0,0 +1,1 @@+0000000000000000000000000000000000000000 6dd1040ce0fbc93348725498c912f0e19175d433 hamcha <hamcha@localhost.localdomain> 1400936747 +0200 clone: from git@github.com:Hamcha/Ketchup.git
@@ -1,11 +1,1 @@-0000000000000000000000000000000000000000 c1ef5202b4e0351ba9c95229c0edf7dfbfb9bb33 Hamcha <zikyky@gmail.com> 1400868072 +0200 update by push-c1ef5202b4e0351ba9c95229c0edf7dfbfb9bb33 622888f76a4bd37398710e1590463719c2129297 Hamcha <zikyky@gmail.com> 1400868261 +0200 update by push-622888f76a4bd37398710e1590463719c2129297 d752cbde2090cf51b382e0060e0d13a90ef9dfa8 Hamcha <zikyky@gmail.com> 1400871184 +0200 update by push-d752cbde2090cf51b382e0060e0d13a90ef9dfa8 708b4d9119f776f28cc85a2a0f58b4bf1c1e7b43 Hamcha <zikyky@gmail.com> 1400871595 +0200 update by push-708b4d9119f776f28cc85a2a0f58b4bf1c1e7b43 722f61d1774f7fbd456a5ab611c54408e61f2cc6 Hamcha <zikyky@gmail.com> 1400872238 +0200 update by push-722f61d1774f7fbd456a5ab611c54408e61f2cc6 1093f2858a4572a7a141c96f251f273da4d55c89 Hamcha <zikyky@gmail.com> 1400884145 +0200 update by push-1093f2858a4572a7a141c96f251f273da4d55c89 cf34a7265591f7c3f2d241bd7a554e96c85c68d5 Hamcha <zikyky@gmail.com> 1400935037 +0200 update by push-cf34a7265591f7c3f2d241bd7a554e96c85c68d5 6dd1040ce0fbc93348725498c912f0e19175d433 Hamcha <zikyky@gmail.com> 1400936080 +0200 update by push-6dd1040ce0fbc93348725498c912f0e19175d433 691816444999b3c2b424bdcef7eeb977fa8b18a5 Hamcha <zikyky@gmail.com> 1400953258 +0200 update by push-691816444999b3c2b424bdcef7eeb977fa8b18a5 ab41fa19ef0fbeb0088d8f325b1dc4280cbe9817 Hamcha <zikyky@gmail.com> 1400953627 +0200 update by push-ab41fa19ef0fbeb0088d8f325b1dc4280cbe9817 2e95147d7a2c86bb224527a5624c118b53f9c736 Hamcha <zikyky@gmail.com> 1400960301 +0200 update by push+6dd1040ce0fbc93348725498c912f0e19175d433 2e95147d7a2c86bb224527a5624c118b53f9c736 hamcha <hamcha@localhost.localdomain> 1400972318 +0200 pull: fast-forward
binary file changed (34 → absent bytes)
binary file changed (167 → absent bytes)
binary file changed (1791 → absent bytes)
binary file changed (1770 → absent bytes)
binary file changed (115 → absent bytes)
binary file changed (116 → absent bytes)
binary file changed (40 → absent bytes)
@@ -1,1 +0,0 @@-xÅRÁn1Í:»í¡AÑ Ò(¨)4"ôPE²«zmÇ7 (ÿÞ1¹¥×ø`Ù~3OïÍóJÛ\|ÎO{§ð}4»ù9º¹Ñk+ª{òÙ8í½´[íVmUÔSYx*Ñcz¬jg=Ácºú]¡¯d¼#lºA¿U6.áÓW^×-Òº®?!rê?øÜFbIJ)b}¥Qàñô²ðm·o@£æèôn_ò)ÏááL\YCh¨·Ø9]x[ÊJªµXvL5&ët<Ì?î¯YKâæbÍ\è¿lL"â«!SG¯» l5,²CX6¼1OôUjJV6Þ×Iùq8©uof²F0¼±EÆÐQù<ûÁ¶Ã6¶§#2³Tr@ÀkvµA45ß§}míè@Ä^Ksð.z.ÙR^+jît¯ûIeûFÖæÖá©òoMß4 ºâÌd±¸q.`òÏÿ°mé
binary file changed (67 → absent bytes)
@@ -1,2 +0,0 @@-x¥TÁn@íxr"$¶RUU¨¸MR5vªÄU³.(K%¶[÷ß;kÔHå`Ïî̼y3oà^È{¼~óêíÃ\M/¿]~ÄÍWB²wZEÉ÷'Ã_¶e[±rÁñëe§ÞÌ5¹mË"ÛuȶũT9Ñ*â>0ͼóæ¨7zaÜ<aiáÔ~Ô¡p¥uñO¹^KõP)©a4ÂÜ7êàÜÉå×¾ÇÕlöå?æ<+ÎÄ+j7Ã[·ÈùtÇuÝ m¬è¦°5\æº%MTíkûÈxL¥¾y ò4GÊ^2wï0ibFºÀÉUd<.µ¤\øp2B$ë ä)R¦XÏ3ÐR®ë(ã5ó?_©_ýføåÚ¼HÖ@i`çs)mY+ÍãT0ÍáW<hX8Å(ýéKu¤AÇiiTÁûM,xÈ ¶¯¸ÜaßǶ°ÛÊiÍíRa>ö\lD»´6êY+tì KØýQß`Pè_ 3mÖÍùT6KE¤ÑÙ/z®ø ¿é7+Æ¿×÷óÿÇÚ×PÇ´x+%ãëÖí«Hh®à$RÃ3óò@»è6T>/üé9-Ö¡vãôz^ÏmªØ- }4Jq7®½§×©ÿ*ý¡X,
binary file changed (122 → absent bytes)
binary file changed (156 → absent bytes)
binary file changed (505 → absent bytes)
binary file changed (116 → absent bytes)
binary file changed (156 → absent bytes)
binary file changed (116 → absent bytes)
@@ -1,2 +0,0 @@-xMJ1F]çµêt~AĥרTjzÊt$ ñô6x·ï}<îéë×§9DÏR} ¸HäÂB³çàmMÁ§ÕÍù¤!û²äè\k V.%óìxYKöêê-FC_óÒ¼SãÁË^×ÇÛÖHo'îíB²>Á3ZDsÐ#mÊ¿$sÚtê¶÷!0;Ðw×-OºoPt§¡r#¥á g½ÉÝü|7Q,
binary file changed (1874 → absent bytes)
@@ -1,2 +0,0 @@-x+)JMU041c040031QÐKÏ,ÉLÏË/Je`ú¿ >sÂwßõ7NËí_<³ìê PðN-IÎ(-`¼Æò¡EóÃÕ%óËz+¹³EHÚBÍñMÌNMËÌIeh|oz}³³»Èª¥%·øW~˪IHÌ-ÈIÕË(f0òe_%£Ï,<?)9ñâ-#ÑÍ:
binary file changed (1759 → absent bytes)
binary file changed (158 → absent bytes)
@@ -1,2 +0,0 @@-xÎM-Â0@a×9Åìü5Ñ×&[jl©qQOo¯àöÁ/͵ ÆC[EÀùÂÎX":¨±=u¸d)ø²S¯òj7©Ïb0¯{ v(µeB)GÅ6Ì+ܹ¦áü§mÚ®ÊãóæzícÐ4Ñ ª½îkMþBê³dhÛ"oõÌP@Ú
binary file changed (181 → absent bytes)
binary file changed (82 → absent bytes)
@@ -1,1 +0,0 @@-x ±jÃ0;ü?dIi H!vKv¡³b"m9'¹¥¾{%7vª¶Ó}Ü}ÿ[Ärµºù3<mwíî/oÄWô>²ëO3ñUeÑy=¶Gy® e1G¢º²XàÝS]7x8ªuÆÆ½JV~&BTÿc²¶o3\_a\ß43»°TC¼[d1±o¢ó=çɰKQ¢2þ¥Së5ªßâîO}¡600eU¦ÌécZ2¥ËJÍZjöëué\¹okßsð
binary file changed (281 → absent bytes)
binary file changed (248 → absent bytes)
@@ -1,1 +0,0 @@-xKÊÉOR0·`HÌɱRHHÌ-ÈIååâå2x¹8Ó3a2zÅ ÉäÔÄ<TQ®^¾>ÔËÈ332Ißå
binary file changed (116 → absent bytes)
@@ -1,1 +0,0 @@-xEÐAKÃ0`Ïþ좲vUAv¨ UeÎÒæÓ²¤K¿¨Cüï&ÛÔBÞäÉÔÊÔpv~rðávz7{ήáþ2\ x"+õ[Ãø;DN!,¸ÔðѢŰ(W±ÿã©i]Ì:ñ¯WòU¢+N<)6;xEZ® ×[-Àâ.@hصxÄNm¶ÙiByÈ.&Ô/7²QÉ?iÜÒJ±ê¨ò@ßÝûØw ÓßÀóEÒÝpe§Ðæ/Æ »öäfuÎFÎªËÆu÷XµS}âge8²ýð/¡6(é=_.3¤vÏû}«q1
@@ -1,3 +0,0 @@-xÎM-Â0@a×9ÅìN~ÚKà&ÉDK&]èéõ-n|ðb-eî@äv}cuH^Grì ÆÑ&g\¢,iBë4zñ*Ïql )AmÀ>zKä#JÊcÊ!Ö·~¯+\¸Ä;Ãñ3/ïå}¾XË 8¹È QýêoË_H]k] Õ"°5yHkÐú3Ô«/THg
binary file changed (156 → absent bytes)
@@ -1,2 +0,0 @@-xA-Â0E]ç³T1i¸òcÚRH;.êé xïÃã¿TDFÍFç¡·lÎg{fËÔ¶!4xGJb²Éß:n,i`8}ÆiÖËCx|R3C>¢'ØãÑÔµ^iþK2W^2üTØJY´BW;ç"0¨¾ºù¢;U
binary file changed (557 → absent bytes)
binary file changed (158 → absent bytes)
@@ -1,1 +0,0 @@-x+)JMU041c040031QÐKÏ,ÉLÏË/Je`ú¿ >sÂwßõ7NËí_<³ìê PðN-IÎ(-`xûîý½¦+%ÕOû_ýöC\~í¨9¾Ù©i9©ïM¯ÏcvvYµ´DàÿÊïryP5©¹9©zÅK:ú¬5/Åë{³=þxêáÝ]\w]>¿
@@ -1,1 +0,0 @@-xÎMjÃ0@á®uÙÊh¬èB Yõãñ(¢¢Èôôõº}ðÁVk@äÞFWïOyfÔ *Âya&ÒÉQÎ$sÖH.oîúàb9xvó2 )Å`Qí)¡óS°IÈR¢ïcm¾¸ÊÊpþ-Ûk{]nËýCZýël#Â;¢9ê±6ô_È\ùYzÛGyÜ๶ý¾ÀOëù:©F¤
binary file changed (424 → absent bytes)
binary file changed (675 → absent bytes)
binary file changed (15 → absent bytes)
binary file changed (560 → absent bytes)
binary file changed (116 → absent bytes)
binary file changed (122 → absent bytes)
@@ -1,3 +0,0 @@-x¥SMOÜ0í9RþÃÓ´ié©BÊÒJe[ Zõ8ìm,9qðìÒíg¬Ó %R¥ú<oß¼±o¾ÁÑÑÛ7¯~îáüäËÙ÷³øz/Ò~é¬Zìþ£8ª4÷Jà³p·¥o²í¥ã(¡PÄQR-âHV6w)¹ã=s,;];ÑfEÉÌ;0b-¼`M_y+Høä\ÃÛã:¸º%«9i5âÎëÃ2~±Ýèó¡01ÇM1.£qQÏH¼2E²$bwbkÞFãZì£aUöåº@yö ´ÿ òÞÙþkñw#éty£àDÕ(æòú'²ù!][]BÒßY¸ªé¼[{p@®°îsíæ+ä9Öm<^9¾O»h«"«½RX`®É¦LÙ´ÈJÁ8Ñ÷üx8úéI#Ò¡¹µó×ó¶ç^_èøwóÁ¹ÖÏíÀ^2t-®Î% }K©0Hjí &3ÐHw\7¸ÿÛè3ß§ÝLf³Ù,ݵ~ÚϤÈÝDV£©ÛGzÿ?} ¹Cn
binary file changed (absent → 2304 bytes)
binary file changed (absent → 8124 bytes)
@@ -0,0 +1,2 @@+# pack-refs with: peeled fully-peeled +6dd1040ce0fbc93348725498c912f0e19175d433 refs/remotes/origin/master
@@ -0,0 +1,1 @@+ref: refs/remotes/origin/master
@@ -1,5 +1,5 @@ Name: Ketchup -Version: 0.1.1 +Version: 0.1.2 Cabal-Version: >= 1.6 Build-Type: Simple License: MIT @@ -21,9 +21,10 @@ Build-Depends: base ==4.*, + bytestring >=0.9 && <0.11, containers >=0.2 && <0.6, network <2.5, - bytestring >=0.9 && <0.11 + regex-posix <1.0 Source-Repository head type: git
@@ -1,5 +1,5 @@ Name: Ketchup -Version: 0.1.0 +Version: 0.1.1 Cabal-Version: >= 1.6 Build-Type: Simple License: MIT @@ -14,16 +14,17 @@ Exposed-Modules: Ketchup.Httpd, Ketchup.Routing - Ketchup.Chunked + Ketchup.Chunked Other-Modules: Ketchup.Utils Build-Depends: base ==4.*, + bytestring >=0.9 && <0.11, containers >=0.2 && <0.6, network <2.5, - bytestring >=0.9 && <0.11 + regex-posix <1.0 Source-Repository head type: git
binary file changed (absent → 12288 bytes)
@@ -134,4 +134,4 @@ NS.bindSocket sock addr NS.listen sock 128 createAcceptorPool sock 128 cback - sClose sock+ sClose sock
@@ -0,0 +1,138 @@+{-# LANGUAGE OverloadedStrings #-} + +module Ketchup.Httpd +( HTTPRequest +, method, uri, httpver, headers +, statusMsg +, sendReply +, listenHTTP +, sendBadRequest +, sendNotFound +) where + +import Control.Concurrent (forkIO) +import qualified Data.ByteString as B +import qualified Data.ByteString.Char8 as C +import qualified Data.Map as Map +import qualified Data.List as List +import Network +import qualified Network.Socket as NS +import Network.Socket.ByteString +import Ketchup.Utils +import System.IO + +-- HTTP Request type +data HTTPRequest = HTTPRequest { method :: B.ByteString + , uri :: B.ByteString + , httpver :: B.ByteString + , headers :: Map.Map B.ByteString [B.ByteString] + } deriving (Show) + +-- Returns status message from status id +statusMsg :: Int -> B.ByteString +statusMsg stat + -- 200 Success + | stat == 200 = "200 OK" + | stat == 201 = "201 Created" + | stat == 204 = "204 No Content" + -- 400 Client Errors + | stat == 400 = "400 Bad Request" + | stat == 403 = "403 Forbidden" + | stat == 404 = "404 Not Found" + | stat == 405 = "405 Method Not Allowed" + | stat == 410 = "410 Gone" + -- 500 Server Errors + | stat == 500 = "500 Internal Server Error" + | stat == 501 = "501 Not Implemented" + | stat == 502 = "502 Bad Gateway" + | stat == 503 = "503 Service Unavailable" + | otherwise = "500 Internal Server Error" + +sendBadRequest :: Socket -> IO () +sendBadRequest client = do + sendReply client 400 [("Content-Type",["text/plain"])] "400 Bad Request!\n" + +sendNotFound :: Socket -> IO () +sendNotFound client = do + sendReply client 404 [("Content-Type",["text/plain"])] "404 Not Found!\n" + +-- Sends HTTP reply +sendReply :: Socket -> Int -> [(B.ByteString, [B.ByteString])] -> B.ByteString -> IO () +sendReply client status headers body = do + sendAll client reply + where + reply = B.concat ["HTTP/1.1 ", statusMsg status,"\r\n\ + \Content-Length: ", C.pack $ show $ C.length body, "\r\n\ + \Connection: close\r\n",heads,"\r\n",body] + -- Turn ("a", ["b", "c"]) headers into "a: b,c" + heads = B.concat $ map (\x -> B.concat [fst x, ": ", B.concat $ List.intersperse "," $ snd x, "\r\n"]) headers + +-- Parses header lines +parseRequestLine :: B.ByteString -> (B.ByteString, [B.ByteString]) +parseRequestLine line = + (property, values) + where + property = head items + values = C.split ',' $ (trim . last) items + items = C.split ':' line + +-- Gets all request lines +getRequest :: Socket -> IO [B.ByteString] +getRequest client = do + content <- recv client 1024 + return $ C.lines content + +-- Parses requests +parseRequest :: [B.ByteString] -> HTTPRequest +parseRequest reqlines = + HTTPRequest { method=met, uri=ur, httpver=ver, headers=heads } + where + [met, ur, ver] = (C.words . head) reqlines -- First line is METHOD URI VERSION + heads = Map.fromList $ map parseRequestLine $ tail reqlines + +-- Handles each client request +handleRequest :: Socket -> (Socket -> HTTPRequest -> IO ()) -> IO () +handleRequest client cback = do + reqlines <- getRequest client + case length reqlines of + 0 -> sendBadRequest client + _ -> cback client $ parseRequest reqlines + sClose client + +-- Acceptor +acceptAll :: Socket -> (Socket -> HTTPRequest -> IO ()) -> IO () +acceptAll sock cback = do + (client, _) <- NS.accept sock + handleRequest client cback + acceptAll sock cback + +-- Creates Acceptor pools +createAcceptorPool :: Socket -> Int -> (Socket -> HTTPRequest -> IO ()) -> IO () +createAcceptorPool sock max cback = + case max of + 0 -> acceptAll sock cback + x -> do + forkIO $ acceptAll sock cback + createAcceptorPool sock (x-1) cback + +-- Gets host from hostname string +getHostaddr :: String -> IO NS.HostAddress +getHostaddr "*" = return NS.iNADDR_ANY +getHostaddr host = NS.inet_addr host + +-- Listens for incoming HTTP request +listenHTTP :: String -> PortNumber -> (Socket -> HTTPRequest -> IO ()) -> IO () +listenHTTP hostname port cback = withSocketsDo $ do + -- Get hostname + host <- getHostaddr hostname + let addr = NS.SockAddrInet port host + putStr $ concat ["{* Listening on ", show addr, " (POOL SIZE ", show 128, "*}"] + -- Prepare Socket + sock <- NS.socket NS.AF_INET NS.Stream 0 + NS.setSocketOption sock NS.ReuseAddr 1 + NS.setSocketOption sock NS.NoDelay 1 + -- Bind socket to address and listen + NS.bindSocket sock addr + NS.listen sock 128 + createAcceptorPool sock 128 cback + sClose sock
@@ -8,6 +8,7 @@ import qualified Data.Map as M import Ketchup.Httpd import Network +import qualified Text.Regex.Posix as R route :: [(C.ByteString, (Socket -> HTTPRequest -> (M.Map C.ByteString C.ByteString) -> IO ()))] -> (Socket -> HTTPRequest -> IO ()) @@ -21,7 +22,7 @@ and $ zipWith compare urlparts tmpparts where compare x y - | x == y = True + | x R.=~ y = True | or [C.null y, C.null x] = False | C.head y == ':' = True | otherwise = False @@ -37,4 +38,4 @@ | C.head y == ':' = (C.tail y, x) | otherwise = ("","") urlparts = C.split '/' url - tmpparts = C.split '/' template+ tmpparts = C.split '/' template
@@ -0,0 +1,41 @@+{-# LANGUAGE OverloadedStrings #-} + +module Ketchup.Routing +( route +) where + +import qualified Data.ByteString.Char8 as C +import qualified Data.Map as M +import Ketchup.Httpd +import Network +import qualified Text.Regex.Posix + +route :: [(C.ByteString, (Socket -> HTTPRequest -> (M.Map C.ByteString C.ByteString) -> IO ()))] + -> (Socket -> HTTPRequest -> IO ()) +route [] handle request = sendNotFound handle +route (r:routes) handle request + | match (uri request) (fst r) = (snd r) handle request $ params (uri request) (fst r) + | otherwise = route routes handle request + +match :: C.ByteString -> C.ByteString -> Bool +match url template = + and $ zipWith compare urlparts tmpparts + where + compare x y + | x =~ y = True + | or [C.null y, C.null x] = False + | C.head y == ':' = True + | otherwise = False + urlparts = C.split '/' url + tmpparts = C.split '/' template + +params :: C.ByteString -> C.ByteString -> M.Map C.ByteString C.ByteString +params url template = + M.fromList $ filter (not . C.null . fst) $ zipWith retrieve urlparts tmpparts + where + retrieve x y + | or [C.null y, C.null x] = ("","") + | C.head y == ':' = (C.tail y, x) + | otherwise = ("","") + urlparts = C.split '/' url + tmpparts = C.split '/' template
@@ -1,8 +0,0 @@-all: example - -example: - ghc example.hs - -clean: - rm -rf ./example - rm -rf *.o */*.o *.hi */*.hi