em-http-request 0.2.10 → 0.2.11

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of em-http-request might be problematic. Click here for more details.

@@ -1,51 +1,55 @@
1
1
  module EventMachine
2
2
 
3
- # EventMachine based Multi request client, based on a streaming HTTPRequest class,
3
+ # EventMachine based Multi request client, based on a streaming HTTPRequest class,
4
4
  # which allows you to open multiple parallel connections and return only when all
5
5
  # of them finish. (i.e. ideal for parallelizing workloads)
6
- #
6
+ #
7
7
  # == Example
8
- #
8
+ #
9
9
  # EventMachine.run {
10
- #
10
+ #
11
11
  # multi = EventMachine::MultiRequest.new
12
- #
12
+ #
13
13
  # # add multiple requests to the multi-handler
14
14
  # multi.add(EventMachine::HttpRequest.new('http://www.google.com/').get)
15
15
  # multi.add(EventMachine::HttpRequest.new('http://www.yahoo.com/').get)
16
- #
16
+ #
17
17
  # multi.callback {
18
18
  # p multi.responses[:succeeded]
19
19
  # p multi.responses[:failed]
20
- #
20
+ #
21
21
  # EventMachine.stop
22
22
  # }
23
23
  # }
24
- #
25
-
24
+ #
25
+
26
26
  class MultiRequest
27
27
  include EventMachine::Deferrable
28
28
 
29
29
  attr_reader :requests, :responses
30
-
31
- def initialize
32
- @requests = []
30
+
31
+ def initialize(conns=[], &block)
32
+ @requests = []
33
33
  @responses = {:succeeded => [], :failed => []}
34
+
35
+ conns.each {|conn| add(conn)}
36
+ callback(&block) if block_given?
34
37
  end
35
-
38
+
36
39
  def add(conn)
37
40
  @requests.push(conn)
38
41
 
39
42
  conn.callback { @responses[:succeeded].push(conn); check_progress }
40
43
  conn.errback { @responses[:failed].push(conn); check_progress }
41
44
  end
42
-
45
+
43
46
  protected
44
-
47
+
45
48
  # invoke callback if all requests have completed
46
49
  def check_progress
47
- succeed if (@responses[:succeeded].size + @responses[:failed].size) == @requests.size
50
+ succeed(self) if (@responses[:succeeded].size +
51
+ @responses[:failed].size) == @requests.size
48
52
  end
49
-
53
+
50
54
  end
51
55
  end
@@ -72,6 +72,7 @@ module EventMachine
72
72
  rescue EventMachine::ConnectionError => e
73
73
  conn = EventMachine::HttpClient.new("")
74
74
  conn.on_error(e.message, true)
75
+ conn.uri = @req.uri
75
76
  conn
76
77
  end
77
78
  end
@@ -1,21 +1,20 @@
1
- HTTP/1.0 200 OK
2
- Date: Mon, 16 Nov 2009 20:39:15 GMT
3
- Expires: -1
4
- Cache-Control: private, max-age=0
5
- Content-Type: text/html; charset=ISO-8859-1
6
- Set-Cookie: PREF=ID=9454187d21c4a6a6:TM=1258403955:LM=1258403955:S=2-mf1n5oV5yAeT9-; expires=Wed, 16-Nov-2011 20:39:15 GMT; path=/; domain=.google.ca
7
- Set-Cookie: NID=28=lvxxVdiBQkCetu_WFaUxLyB7qPlHXS5OdAGYTqge_laVlCKVN8VYYeVBh4bNZiK_Oan2gm8oP9GA-FrZfMPC3ZMHeNq37MG2JH8AIW9LYucU8brOeuggMEbLNNXuiWg4; expires=Tue, 18-May-2010 20:39:15 GMT; path=/; domain=.google.ca; HttpOnly
8
- Server: gws
9
- X-XSS-Protection: 0
10
- X-Cache: MISS from .
11
- Via: 1.0 .:80 (squid)
12
- Connection: close
13
-
14
- <!doctype html><html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>window.google={kEI:"eLgBS4LROqCQedKVvfUL",kEXPI:"17259,21329,21516,22107",kCSI:{e:"17259,21329,21516,22107",ei:"eLgBS4LROqCQedKVvfUL"},kHL:"en",time:function(){return(new Date).getTime()},log:function(b,d,c){var a=new Image,e=google,g=e.lc,f=e.li;a.onerror=(a.onload=(a.onabort=function(){delete g[f]}));g[f]=a;c=c||"/gen_204?atyp=i&ct="+b+"&cad="+d+"&zx="+google.time();a.src=c;e.li=f+1},lc:[],li:0};
15
- window.google.sn="webhp";window.google.timers={load:{t:{start:(new Date).getTime()}}};try{}catch(b){}window.google.jsrt_kill=1;
16
- var _gjwl=location;function _gjuc(){var e=_gjwl.href.indexOf("#");if(e>=0){var a=_gjwl.href.substring(e);if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var f=a.substring(d,b);if(f.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(f=="cad=h")return 0;c=b}_gjwl.href="/search?"+a+"&cad=h";return 1}}}return 0}function _gjp(){!(window._gjwl.hash&&
17
- window._gjuc())&&setTimeout(_gjp,500)};
18
- window._gjp && _gjp()</script><style>td{line-height:.8em;}.gac_m td{line-height:17px;}form{margin-bottom:20px;}body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}em{font-weight:bold;font-style:normal}.lst{font:17px arial,sans-serif;margin-bottom:.2em;vertical-align:bottom;}input{font-family:inherit}.lsb,.gac_sb{font-size:15px;height:1.85em!important;margin:.2em;}#gbar{height:22px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#guser{padding-bottom:7px !important;text-align:right}#gbar,#guser{font-size:13px;padding-top:1px !important}@media all{.gb1,.gb3{height:22px;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb3,a.gb4{color:#00c !important}.gb3{text-decoration:none}</style><script>google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo7.png'" topmargin=3 marginheight=3><textarea id=csi style=display:none></textarea><div id=gbar><nobr><b class=gb1>Web</b> <a href="http://images.google.ca/imghp?hl=en&tab=wi" class=gb1>Images</a> <a href="http://video.google.ca/?hl=en&tab=wv" class=gb1>Videos</a> <a href="http://maps.google.ca/maps?hl=en&tab=wl" class=gb1>Maps</a> <a href="http://news.google.ca/nwshp?hl=en&tab=wn" class=gb1>News</a> <a href="http://groups.google.ca/grphp?hl=en&tab=wg" class=gb1>Groups</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.ca/intl/en/options/" class=gb3><u>more</u> &raquo;</a></nobr></div><div id=guser width=100%><nobr><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.ca/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNG2Kt7TgMZuV7Fl3FeeTOmTWMvggA" class=gb4>iGoogle</a> | <a href="/preferences?hl=en" class=gb4>Search settings</a> | <a href="https://www.google.com/accounts/Login?hl=en&continue=http://www.google.ca/" class=gb4>Sign in</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div><center><br clear=all id=lgpd><img alt="Google" height=110 src="/intl/en_ca/images/logo.gif" width=276 id=logo onload="window.lol&&lol()"><br><br><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%>&nbsp;</td><td align=center nowrap><input name=hl type=hidden value=en><input name=source type=hidden value=hp><input type=hidden name=ie value="ISO-8859-1"><input autocomplete="off" maxlength=2048 name=q size=55 class=lst title="Google Search" value=""><br><input name=btnG type=submit value="Google Search" class=lsb><input name=btnI type=submit value="I'm Feeling Lucky" class=lsb></td><td nowrap width=25% align=left><font size=-2>&nbsp;&nbsp;<a href=/advanced_search?hl=en>Advanced Search</a><br>&nbsp;&nbsp;<a href=/language_tools?hl=en>Language Tools</a></font></td></tr><tr><td align=center colspan=3><font size=-1><span style="text-align:left">Search: <input id=all type=radio name=meta value="" checked><label for=all> the web </label> <input id=cty type=radio name=meta value="cr=countryCA"><label for=cty> pages from Canada </label> </span></font></td></tr></table></form><br><font size=-1>Google.ca offered in: <a href="http://www.google.ca/setprefs?sig=0_XtMil90_yvnNEW8dIglASaHCVhU=&hl=fr">fran?ais</a> </font><br><br><br><font size=-1><a href="/intl/en/ads/">Advertising&nbsp;Programs</a> - <a href="/services/">Business Solutions</a> - <a href="/intl/en/about.html">About Google</a> - <a href="http://www.google.com/ncr">Go to Google.com</a></font><p><font size=-2>&copy;2009 - <a href="/intl/en/privacy.html">Privacy</a></font></p></center><div id=xjsd></div><div id=xjsi><script>if(google.y)google.y.first=[];if(google.y)google.y.first=[];google.dstr=[];google.rein=[];window.setTimeout(function(){var a=document.createElement("script");a.src="/extern_js/f/CgJlbhICY2EgACswCjhBQB0sKzAOOAksKzAYOAQsKzAlOMmIASwrMCY4BywrMCc4Aiw/n_sssePDGvc.js";(document.getElementById("xjsd")||document.body).appendChild(a)},0);
19
- ;google.y.first.push(function(){google.ac.b=true;google.ac.i(document.f,document.f.q,'','')});google.xjs&&google.j&&google.j.xi&&google.j.xi()</script></div><script>(function(){
20
- function a(){google.timers.load.t.ol=(new Date).getTime();google.report&&google.timers.load.t.xjs&&google.report(google.timers.load,google.kCSI)}if(window.addEventListener)window.addEventListener("load",a,false);else if(window.attachEvent)window.attachEvent("onload",a);google.timers.load.t.prt=(new Date).getTime();
21
- })();
1
+ HTTP/1.1 200 OK
2
+ Date: Sat, 14 Aug 2010 21:58:26 GMT
3
+ Expires: -1
4
+ Cache-Control: private, max-age=0
5
+ Content-Type: text/html; charset=ISO-8859-1
6
+ Set-Cookie: PREF=ID=11955ae9690fd292:TM=1281823106:LM=1281823106:S=wHdloFqGQ_OLSE92; expires=Mon, 13-Aug-2012 21:58:26 GMT; path=/; domain=.google.ca
7
+ Set-Cookie: NID=37=USTdOsxOSMbLjphkJ3S5Ueua3Yc23COXuK_pbztcHx7JoyhomwQySrvebCf3_u8eyrBiLWssVzaZcEOiKGEJbNdy8lRhnq_mfrdz693LaMjNPh__ccW4sgn1ZO6nQltE; expires=Sun, 13-Feb-2011 21:58:26 GMT; path=/; domain=.google.ca; HttpOnly
8
+ Server: gws
9
+ X-XSS-Protection: 1; mode=block
10
+
11
+ <!doctype html><html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><script>window.google={kEI:"ghFnTJiGG9WhnQf4o9X8BA",kEXPI:"25913,25976,26060",kCSI:{e:"25913,25976,26060",ei:"ghFnTJiGG9WhnQf4o9X8BA",expi:"25913,25976,26060"},ml:function(){},kHL:"en",time:function(){return(new Date).getTime()},log:function(b,d,c){var a=new Image,e=google,g=e.lc,f=e.li;a.onerror=(a.onload=(a.onabort=function(){delete g[f]}));g[f]=a;c=c||"/gen_204?atyp=i&ct="+b+"&cad="+d+"&zx="+google.time();a.src=c;e.li=f+1},lc:[],li:0,Toolbelt:{}};
12
+ window.google.sn="webhp";window.google.timers={load:{t:{start:(new Date).getTime()}}};try{}catch(u){}window.google.jsrt_kill=1;
13
+ var _gjwl=location;function _gjuc(){var e=_gjwl.href.indexOf("#");if(e>=0){var a=_gjwl.href.substring(e);if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var f=a.substring(d,b);if(f.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(f=="cad=h")return 0;c=b}_gjwl.href="/search?"+a+"&cad=h";return 1}}}return 0}function _gjp(){!(window._gjwl.hash&&
14
+ window._gjuc())&&setTimeout(_gjp,500)};
15
+ window._gjp && _gjp()</script><style id=gstyle>body{margin:0}#gog{padding:3px 8px 0}td{line-height:.8em;}.gac_m td{line-height:17px;}form{margin-bottom:20px;}body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}em{font-weight:bold;font-style:normal}.lst{width:496px}.tiah{width:458px}input{font-family:inherit}a.gb1,a.gb2,a.gb3,a.gb4{color:#11c !important}#gbar,#guser{font-size:13px;padding-top:1px !important}#gbar{height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}@media all{.gb1{height:22px;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb4{color:#00c !important}body{background:#fff;color:black}input{-moz-box-sizing:content-box}a{color:#11c;text-decoration:none}a:hover,a:active{text-decoration:underline}.fl a{color:#4272db}a:visited{color:#551a8b}a.gb1,a.gb4{text-decoration:underline}a.gb3:hover{text-decoration:none}#ghead a.gb2:hover{color:#fff!important}.ds{display:-moz-inline-box}.ds{border-bottom:solid 1px #e7e7e7;border-right:solid 1px #e7e7e7;display:inline-block;margin:3px 0 4px;margin-left:4px}.sblc{padding-top:5px}.sblc a{display:block;margin:2px 0;margin-left:13px;font-size:11px;}.lsbb{background:#eee;border:solid 1px;border-color:#ccc #999 #999 #ccc;height:30px;display:block}.lsb{background:url(/images/srpr/nav_logo14.png) bottom;font:15px arial,sans-serif;border:none;color:#000;cursor:pointer;height:30px;margin:0;outline:0;vertical-align:top}.lsb:active{background:#ccc}.lst:focus{outline:none}.ftl,#fll a{margin:0 12px}#addlang a{padding:0 3px}.gac_v div{display:none}.gac_v .gac_v2,.gac_bt{display:block!important}</style><script>google.y={};google.x=function(e,g){google.y[e.id]=[e,g];return false};</script></head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="document.f.q.focus();if(document.images)new Image().src='/images/srpr/nav_logo14.png'" ><textarea id=csi style=display:none></textarea><div id=ghead><div id=gbar><nobr><b class=gb1>Web</b> <a onclick=gbar.qs(this) href="http://www.google.ca/imghp?hl=en&tab=wi" class=gb1>Images</a> <a onclick=gbar.qs(this) href="http://video.google.ca/?hl=en&tab=wv" class=gb1>Videos</a> <a onclick=gbar.qs(this) href="http://maps.google.ca/maps?hl=en&tab=wl" class=gb1>Maps</a> <a onclick=gbar.qs(this) href="http://news.google.ca/nwshp?hl=en&tab=wn" class=gb1>News</a> <a onclick=gbar.qs(this) href="http://books.google.ca/bkshp?hl=en&tab=wp" class=gb1>Books</a> <a href="http://mail.google.com/mail/?hl=en&tab=wm" class=gb1>Gmail</a> <a href="http://www.google.ca/intl/en/options/" class=gb1 style="text-decoration:none"><u>more</u> &raquo;</a></nobr></div><div id=guser width=100%><nobr><span id=gbn class=gbi></span><span id=gbf class=gbf></span><span id=gbe><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.ca/ig%3Fhl%3Den%26source%3Diglk&usg=AFQjCNG2Kt7TgMZuV7Fl3FeeTOmTWMvggA" class=gb4>iGoogle</a> | </span><a href="/preferences?hl=en" class=gb4>Settings</a> | <a href="https://www.google.com/accounts/Login?hl=en&continue=http://www.google.ca/" class=gb4>Sign in</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div></div> <center><br clear=all id=lgpd><div id=lga><table cellpadding=0 cellspacing=0 border=0><tr><td align=right valign=bottom><img src=images/hp0.gif width=158 height=78 alt="Google"></td><td valign=bottom><img src=images/hp1.gif width=50 height=78 alt=""></td><td valign=bottom><img src=images/hp2.gif width=68 height=78 alt=""></td></tr><tr><td class=h align=right valign=top><b></b></td><td valign=top><img src=images/hp3.gif width=50 height=32 alt=""></td><td valign=top class=h><font color=#666666 style=font-size:16px><b>Canada</b></font></td></tr></table><br></div><form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top><td width=25%>&nbsp;</td><td align=center nowrap><input name=hl type=hidden value=en><input name=source type=hidden value=hp><input type=hidden name=ie value="ISO-8859-1"><div class=ds style="height:32px;margin:4px 0"><input autocomplete="off" maxlength=2048 name=q class="lst" title="Google Search" value="" size=57 style="background:#fff;border:1px solid #ccc;border-bottom-color:#999;border-right-color:#999;color:#000;font:18px arial,sans-serif bold;height:25px;margin:0;padding:5px 8px 0 6px;vertical-align:top"></div><br style="line-height:0"><span class=ds><span class=lsbb><input name=btnG type=submit value="Google Search" class=lsb></span></span><span class=ds><span class=lsbb><input name=btnI type=submit value="I&#39;m Feeling Lucky" class=lsb></span></span></td><td nowrap width=25% align=left class=sblc><a href="/advanced_search?hl=en">Advanced Search</a><a href="/language_tools?hl=en">Language Tools</a></td></tr></table></form><div style="font-size:83%;min-height:3.5em"><br><div id=als><font size=-1 id=addlang>Google.ca offered in: <a href="http://www.google.ca/setprefs?sig=0_h3wwdBzWMwIKco5_3UM-S8-NI00=&amp;hl=fr">fran�ais</a></font><br><br></div></div><div id=res></div><span id=footer><center id=fctr><div style="font-size:10pt"><div id=fll style="margin:19px auto 19px auto;text-align:center"><a href="/intl/en/ads/">Advertising&nbsp;Programs</a><a href="/services/">Business Solutions</a><a href="/intl/en/about.html">About Google</a><a href="http://www.google.com/ncr">Go to Google.com</a></div></div><p style="color:#767676;font-size:8pt">&copy; 2010 - <a href="/intl/en/privacy.html">Privacy</a></p></center></span> <div id=xjsd></div><div id=xjsi><script>if(google.y)google.y.first=[];if(google.y)google.y.first=[];google.dstr=[];google.rein=[];window.setTimeout(function(){var a=document.createElement("script");a.src="/extern_js/f/CgJlbhICY2EgACswRTgBLCswWjgDLCswDjgXLCswFzgHLCswJzgELCswPDgDLCswCjhzQB0sKzAlOMqIASwrMEA4EiwrMEE4BSwrMFQ4ACwrMBg4BSwrMCY4DSyAAheQAhY/shQ1OaVztmo.js";(document.getElementById("xjsd")||document.body).appendChild(a);if(google.timers&&google.timers.load.t)google.timers.load.t.xjsls=(new Date).getTime();},0);
16
+ ;google.neegg=1;google.y.first.push(function(){var form=document.f||document.f||document.gs;google.ac.i(form,form.q,'','','',{o:1,sw:1});google.History&&google.History.initialize('/')});if(google.j&&google.j.en&&google.j.xi){window.setTimeout(google.j.xi,0);google.fade=null;}</script></div><script>(function(){
17
+ var b,d,e,f;function g(a,c){if(a.removeEventListener){a.removeEventListener("load",c,false);a.removeEventListener("error",c,false)}else{a.detachEvent("onload",c);a.detachEvent("onerror",c)}}function h(a){f=(new Date).getTime();++d;a=a||window.event;var c=a.target||a.srcElement;g(c,h)}var i=document.getElementsByTagName("img");b=i.length;d=0;for(var j=0,k;j<b;++j){k=i[j];if(k.complete||typeof k.src!="string"||!k.src)++d;else if(k.addEventListener){k.addEventListener("load",h,false);k.addEventListener("error",
18
+ h,false)}else{k.attachEvent("onload",h);k.attachEvent("onerror",h)}}e=b-d;function l(){if(!google.timers.load.t)return;google.timers.load.t.ol=(new Date).getTime();google.timers.load.t.iml=f;google.kCSI.imc=d;google.kCSI.imn=b;google.kCSI.imp=e;google.report&&google.report(google.timers.load,google.kCSI)}if(window.addEventListener)window.addEventListener("load",l,false);else if(window.attachEvent)window.attachEvent("onload",l);google.timers.load.t.prt=(f=(new Date).getTime());
19
+ })();
20
+ </script>
@@ -1,24 +1,24 @@
1
- require 'spec/helper'
2
-
3
- describe Hash do
4
-
5
- describe ".to_params" do
6
- it "should transform a basic hash into HTTP POST Params" do
7
- {:a => "alpha", :b => "beta"}.to_params.split("&").should include "a=alpha"
8
- {:a => "alpha", :b => "beta"}.to_params.split("&").should include "b=beta"
9
- end
10
-
11
- it "should transform a more complex hash into HTTP POST Params" do
12
- {:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "a=a"
13
- {:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "b[0]=c"
14
- {:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "b[1]=d"
15
- {:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "b[2]=e"
16
- end
17
-
18
- it "should transform a very complex hash into HTTP POST Params" do
19
- params = {:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]}.to_params.split("&")
20
- params.should include "a=a"
21
- params.should include "b[0][d]=d"
22
- end
23
- end
24
- end
1
+ require 'spec/helper'
2
+
3
+ describe Hash do
4
+
5
+ describe ".to_params" do
6
+ it "should transform a basic hash into HTTP POST Params" do
7
+ {:a => "alpha", :b => "beta"}.to_params.split("&").should include "a=alpha"
8
+ {:a => "alpha", :b => "beta"}.to_params.split("&").should include "b=beta"
9
+ end
10
+
11
+ it "should transform a more complex hash into HTTP POST Params" do
12
+ {:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "a=a"
13
+ {:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "b[0]=c"
14
+ {:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "b[1]=d"
15
+ {:a => "a", :b => ["c", "d", "e"]}.to_params.split("&").should include "b[2]=e"
16
+ end
17
+
18
+ it "should transform a very complex hash into HTTP POST Params" do
19
+ params = {:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]}.to_params.split("&")
20
+ params.should include "a=a"
21
+ params.should include "b[0][d]=d"
22
+ end
23
+ end
24
+ end
@@ -2,6 +2,7 @@ require 'rubygems'
2
2
  require 'spec'
3
3
  require 'pp'
4
4
 
5
- require 'lib/em-http'
6
- require 'lib/em-http/mock'
5
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+
7
+ require 'em-http'
7
8
  require 'em-websocket'
@@ -2,26 +2,70 @@ require 'spec/helper'
2
2
 
3
3
  describe 'em-http mock' do
4
4
 
5
+ before(:all) do
6
+ EventMachine::MockHttpRequest.activate!
7
+ end
8
+
9
+ after(:all) do
10
+ EventMachine::MockHttpRequest.deactivate!
11
+ end
12
+
5
13
  before(:each) do
6
14
  EventMachine::MockHttpRequest.reset_registry!
7
15
  EventMachine::MockHttpRequest.reset_counts!
8
16
  end
17
+
18
+ it "should serve a fake http request from a proc" do
19
+ EventMachine::HttpRequest.register('http://www.google.ca:80/', :get) { |req|
20
+ req.response_header.http_status = 200
21
+ req.response_header['SOME_WACKY_HEADER'] = 'WACKY_HEADER_VALUE'
22
+ req.response = "Well, now this is fun."
23
+ }
24
+ EM.run {
25
+ http = EventMachine::HttpRequest.new('http://www.google.ca/').get
26
+ http.errback { fail }
27
+ http.callback {
28
+ http.response_header.status.should == 200
29
+ http.response_header['SOME_WACKY_HEADER'].should == 'WACKY_HEADER_VALUE'
30
+ http.response.should == "Well, now this is fun."
31
+ EventMachine.stop
32
+ }
33
+ }
9
34
 
10
- it "should serve a fake http request from a file" do
11
- EventMachine::MockHttpRequest.register_file('http://www.google.ca:80/', :get, {}, File.join(File.dirname(__FILE__), 'fixtures', 'google.ca'))
35
+ EventMachine::HttpRequest.count('http://www.google.ca:80/', :get, {}).should == 1
36
+ end
37
+
38
+ it "should serve a fake http request from a proc with raw data" do
39
+ EventMachine::HttpRequest.register('http://www.google.ca:80/', :get) { |req|
40
+ req.receive_data(File.read(File.join(File.dirname(__FILE__), 'fixtures', 'google.ca')))
41
+ }
12
42
  EM.run {
13
-
14
- http = EventMachine::MockHttpRequest.new('http://www.google.ca/').get
43
+ http = EventMachine::HttpRequest.new('http://www.google.ca/').get
15
44
  http.errback { fail }
16
45
  http.callback {
17
- http.response.should == File.read(File.join(File.dirname(__FILE__), 'fixtures', 'google.ca')).split("\n\n", 2).last
46
+ http.response_header.status.should == 200
47
+ http.response.should == File.read(File.join(File.dirname(__FILE__), 'fixtures', 'google.ca')).split("\r\n\r\n", 2).last
48
+ EventMachine::HttpRequest.count('http://www.google.ca:80/', :get, {}).should == 1
18
49
  EventMachine.stop
19
50
  }
20
51
  }
52
+ end
53
+
54
+ it "should serve a fake http request from a file" do
55
+ EventMachine::HttpRequest.register_file('http://www.google.ca:80/', :get, {}, File.join(File.dirname(__FILE__), 'fixtures', 'google.ca'))
56
+ EM.run {
21
57
 
22
- EventMachine::MockHttpRequest.count('http://www.google.ca:80/', :get, {}).should == 1
58
+ http = EventMachine::HttpRequest.new('http://www.google.ca/').get
59
+ http.errback { fail }
60
+ http.callback {
61
+ http.response_header.status.should == 200
62
+ http.response.should == File.read(File.join(File.dirname(__FILE__), 'fixtures', 'google.ca')).split("\r\n\r\n", 2).last
63
+ EventMachine::HttpRequest.count('http://www.google.ca:80/', :get, {}).should == 1
64
+ EventMachine.stop
65
+ }
66
+ }
23
67
  end
24
-
68
+
25
69
  it "should serve a fake http request from a string" do
26
70
  data = <<-HEREDOC
27
71
  HTTP/1.0 200 OK
@@ -46,70 +90,71 @@ window._gjp && _gjp()</script><style>td{line-height:.8em;}.gac_m td{line-height:
46
90
  function a(){google.timers.load.t.ol=(new Date).getTime();google.report&&google.timers.load.t.xjs&&google.report(google.timers.load,google.kCSI)}if(window.addEventListener)window.addEventListener("load",a,false);else if(window.attachEvent)window.attachEvent("onload",a);google.timers.load.t.prt=(new Date).getTime();
47
91
  })();
48
92
  HEREDOC
49
- EventMachine::MockHttpRequest.register('http://www.google.ca:80/', :get, {}, data)
93
+ EventMachine::HttpRequest.register('http://www.google.ca:80/', :get, {}, data)
50
94
  EventMachine.run {
51
-
52
- http = EventMachine::MockHttpRequest.new('http://www.google.ca/').get
95
+
96
+ http = EventMachine::HttpRequest.new('http://www.google.ca/').get
53
97
  http.errback { fail }
54
98
  http.callback {
55
99
  http.response.should == data.split("\n\n", 2).last
100
+ EventMachine::HttpRequest.count('http://www.google.ca:80/', :get, {}).should == 1
56
101
  EventMachine.stop
57
102
  }
58
103
  }
59
-
60
- EventMachine::MockHttpRequest.count('http://www.google.ca:80/', :get, {}).should == 1
104
+
61
105
  end
62
106
 
63
107
  it "should serve a fake failing http request" do
64
- EventMachine::MockHttpRequest.register('http://www.google.ca:80/', :get, {}, :fail)
108
+ EventMachine::HttpRequest.register('http://www.google.ca:80/', :get, {}, :fail)
65
109
  error = false
66
110
 
67
111
  EventMachine.run {
68
- http = EventMachine::MockHttpRequest.new('http://www.google.ca/').get
112
+ http = EventMachine::HttpRequest.new('http://www.google.ca/').get
113
+ http.callback {
114
+ EventMachine.stop
115
+ fail
116
+ }
69
117
  http.errback {
70
- error = true
118
+ EventMachine::HttpRequest.count('http://www.google.ca:80/', :get, {}).should == 1
71
119
  EventMachine.stop
72
120
  }
73
121
  }
74
122
 
75
- error.should be_true
76
- EventMachine::MockHttpRequest.count('http://www.google.ca:80/', :get, {}).should == 1
77
123
  end
78
-
124
+
79
125
  it "should distinguish the cache by the given headers" do
80
- EventMachine::MockHttpRequest.register_file('http://www.google.ca:80/', :get, {:user_agent => 'BERT'}, File.join(File.dirname(__FILE__), 'fixtures', 'google.ca'))
81
- EventMachine::MockHttpRequest.register_file('http://www.google.ca:80/', :get, {}, File.join(File.dirname(__FILE__), 'fixtures', 'google.ca'))
126
+ EventMachine::HttpRequest.register_file('http://www.google.ca:80/', :get, {:user_agent => 'BERT'}, File.join(File.dirname(__FILE__), 'fixtures', 'google.ca'))
127
+ EventMachine::HttpRequest.register_file('http://www.google.ca:80/', :get, {}, File.join(File.dirname(__FILE__), 'fixtures', 'google.ca'))
82
128
  EM.run {
83
-
84
- http = EventMachine::MockHttpRequest.new('http://www.google.ca/').get
129
+ http = EventMachine::HttpRequest.new('http://www.google.ca/').get
85
130
  http.errback { fail }
86
131
  http.callback {
87
- http.response.should == File.read(File.join(File.dirname(__FILE__), 'fixtures', 'google.ca')).split("\n\n", 2).last
132
+ http.response_header.status.should == 200
133
+ http.response.should == File.read(File.join(File.dirname(__FILE__), 'fixtures', 'google.ca')).split("\r\n\r\n", 2).last
134
+ EventMachine::HttpRequest.count('http://www.google.ca:80/', :get, {}).should == 1
135
+ EventMachine::HttpRequest.count('http://www.google.ca:80/', :get, {:user_agent => 'BERT'}).should == 0
88
136
  EventMachine.stop
89
137
  }
90
138
  }
91
-
92
- EventMachine::MockHttpRequest.count('http://www.google.ca:80/', :get, {}).should == 1
93
- EventMachine::MockHttpRequest.count('http://www.google.ca:80/', :get, {:user_agent => 'BERT'}).should == 0
94
-
139
+
95
140
  EM.run {
96
-
97
- http = EventMachine::MockHttpRequest.new('http://www.google.ca/').get({:head => {:user_agent => 'BERT'}})
141
+ http = EventMachine::HttpRequest.new('http://www.google.ca/').get({:head => {:user_agent => 'BERT'}})
98
142
  http.errback { fail }
99
143
  http.callback {
100
- http.response.should == File.read(File.join(File.dirname(__FILE__), 'fixtures', 'google.ca')).split("\n\n", 2).last
144
+ http.response_header.status.should == 200
145
+ http.response.should == File.read(File.join(File.dirname(__FILE__), 'fixtures', 'google.ca')).split("\r\n\r\n", 2).last
146
+ EventMachine::HttpRequest.count('http://www.google.ca:80/', :get, {:user_agent => 'BERT'}).should == 1
101
147
  EventMachine.stop
102
148
  }
103
149
  }
104
-
105
- EventMachine::MockHttpRequest.count('http://www.google.ca:80/', :get, {:user_agent => 'BERT'}).should == 1
150
+
106
151
  end
107
152
 
108
153
  it "should raise an exception if pass-thru is disabled" do
109
- EventMachine::MockHttpRequest.pass_through_requests = false
154
+ EventMachine::HttpRequest.pass_through_requests = false
110
155
  EventMachine.run {
111
156
  proc {
112
- http = EventMachine::MockHttpRequest.new('http://www.google.ca/').get
157
+ http = EventMachine::HttpRequest.new('http://www.google.ca/').get
113
158
  }.should raise_error
114
159
  EventMachine.stop
115
160
  }
@@ -5,26 +5,43 @@ describe EventMachine::MultiRequest do
5
5
 
6
6
  it "should submit multiple requests in parallel and return once all of them are complete" do
7
7
  EventMachine.run {
8
-
8
+
9
9
  # create an instance of multi-request handler, and the requests themselves
10
10
  multi = EventMachine::MultiRequest.new
11
-
11
+
12
12
  # add multiple requests to the multi-handler
13
13
  multi.add(EventMachine::HttpRequest.new('http://127.0.0.1:8080/').get(:query => {:q => 'test'}))
14
14
  multi.add(EventMachine::HttpRequest.new('http://0.0.0.0:8083/').get(:timeout => 1))
15
-
15
+
16
16
  multi.callback {
17
17
  # verify successful request
18
18
  multi.responses[:succeeded].size.should == 1
19
19
  multi.responses[:succeeded].first.response.should match(/test/)
20
-
20
+
21
21
  # verify invalid requests
22
22
  multi.responses[:failed].size.should == 1
23
23
  multi.responses[:failed].first.response_header.status.should == 0
24
-
24
+
25
25
  EventMachine.stop
26
26
  }
27
- }
27
+ }
28
+ end
29
+
30
+ it "should accept multiple open connections and return once all of them are complete" do
31
+ EventMachine.run {
32
+ http1 = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').get(:query => {:q => 'test'})
33
+ http2 = EventMachine::HttpRequest.new('http://0.0.0.0:8083/').get(:timeout => 1)
34
+
35
+ multi = EventMachine::MultiRequest.new([http1, http2]) do
36
+ multi.responses[:succeeded].size.should == 1
37
+ multi.responses[:succeeded].first.response.should match(/test/)
38
+
39
+ multi.responses[:failed].size.should == 1
40
+ multi.responses[:failed].first.response_header.status.should == 0
41
+
42
+ EventMachine.stop
43
+ end
44
+ }
28
45
  end
29
46
 
30
47
  it "should handle multiple mock requests" do
@@ -32,20 +49,20 @@ describe EventMachine::MultiRequest do
32
49
  EventMachine::MockHttpRequest.register_file('http://0.0.0.0:8083/', :get, {}, File.join(File.dirname(__FILE__), 'fixtures', 'google.ca'))
33
50
 
34
51
  EventMachine.run {
35
-
52
+
36
53
  # create an instance of multi-request handler, and the requests themselves
37
54
  multi = EventMachine::MultiRequest.new
38
-
55
+
39
56
  # add multiple requests to the multi-handler
40
57
  multi.add(EventMachine::MockHttpRequest.new('http://127.0.0.1:8080/').get)
41
58
  multi.add(EventMachine::MockHttpRequest.new('http://0.0.0.0:8083/').get)
42
-
59
+
43
60
  multi.callback {
44
61
  # verify successful request
45
62
  multi.responses[:succeeded].size.should == 2
46
63
 
47
64
  EventMachine.stop
48
65
  }
49
- }
66
+ }
50
67
  end
51
68
  end
@@ -29,16 +29,27 @@ describe EventMachine::HttpRequest do
29
29
  http.errback {
30
30
  http.response_header.status.should == 0
31
31
  http.error.should match(/unable to resolve server address/)
32
+ http.uri.to_s.should match('http://somethinglocal:80/')
32
33
  EventMachine.stop
33
34
  }
34
35
  }
35
36
  end
36
37
 
37
- it "should fail GET on missing path" do
38
+ it "should raise error on invalid URL" do
38
39
  EventMachine.run {
39
40
  lambda {
40
- EventMachine::HttpRequest.new('http://www.google.com').get
41
- }.should raise_error(ArgumentError)
41
+ EventMachine::HttpRequest.new('random?text').get
42
+ }.should raise_error
43
+
44
+ EM.stop
45
+ }
46
+ end
47
+
48
+ it "should succeed GET on missing path" do
49
+ EventMachine.run {
50
+ lambda {
51
+ EventMachine::HttpRequest.new('http://127.0.0.1:8080').get
52
+ }.should_not raise_error(ArgumentError)
42
53
 
43
54
  EventMachine.stop
44
55
  }
@@ -57,6 +68,19 @@ describe EventMachine::HttpRequest do
57
68
  }
58
69
  end
59
70
 
71
+ it "should accept optional host override" do
72
+ EventMachine.run {
73
+ http = EventMachine::HttpRequest.new('http://google.com:8080/').get :host => '127.0.0.1'
74
+
75
+ http.errback { failed }
76
+ http.callback {
77
+ http.response_header.status.should == 200
78
+ http.response.should match(/Hello/)
79
+ EventMachine.stop
80
+ }
81
+ }
82
+ end
83
+
60
84
  it "should perform successfull GET with a URI passed as argument" do
61
85
  EventMachine.run {
62
86
  uri = URI.parse('http://127.0.0.1:8080/')
@@ -272,6 +296,20 @@ describe EventMachine::HttpRequest do
272
296
  }
273
297
  end
274
298
 
299
+ it "should return ETag and Last-Modified headers" do
300
+ EventMachine.run {
301
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/echo_query').get
302
+
303
+ http.errback { failed }
304
+ http.callback {
305
+ http.response_header.status.should == 200
306
+ http.response_header.etag.should match('abcdefg')
307
+ http.response_header.last_modified.should match('Fri, 13 Aug 2010 17:31:21 GMT')
308
+ EventMachine.stop
309
+ }
310
+ }
311
+ end
312
+
275
313
  it "should detect deflate encoding" do
276
314
  EventMachine.run {
277
315
 
@@ -318,58 +356,95 @@ describe EventMachine::HttpRequest do
318
356
  }
319
357
  end
320
358
 
321
- it "should report last_effective_url" do
322
- EventMachine.run {
323
- http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').get
324
- http.errback { failed }
325
- http.callback {
326
- http.response_header.status.should == 200
327
- http.last_effective_url.to_s.should == 'http://127.0.0.1:8080/'
359
+ context "redirect" do
360
+ it "should report last_effective_url" do
361
+ EventMachine.run {
362
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').get
363
+ http.errback { failed }
364
+ http.callback {
365
+ http.response_header.status.should == 200
366
+ http.last_effective_url.to_s.should == 'http://127.0.0.1:8080/'
328
367
 
329
- EM.stop
368
+ EM.stop
369
+ }
330
370
  }
331
- }
332
- end
371
+ end
333
372
 
334
- it "should follow location redirects" do
335
- EventMachine.run {
336
- http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/redirect').get :redirects => 1
337
- http.errback { failed }
338
- http.callback {
339
- http.response_header.status.should == 200
340
- http.response_header["CONTENT_ENCODING"].should == "gzip"
341
- http.response.should == "compressed"
342
- http.last_effective_url.to_s.should == 'http://127.0.0.1:8080/gzip'
343
- http.redirects.should == 1
373
+ it "should follow location redirects" do
374
+ EventMachine.run {
375
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/redirect').get :redirects => 1
376
+ http.errback { failed }
377
+ http.callback {
378
+ http.response_header.status.should == 200
379
+ http.response_header["CONTENT_ENCODING"].should == "gzip"
380
+ http.response.should == "compressed"
381
+ http.last_effective_url.to_s.should == 'http://127.0.0.1:8080/gzip'
382
+ http.redirects.should == 1
344
383
 
345
- EM.stop
384
+ EM.stop
385
+ }
346
386
  }
347
- }
348
- end
387
+ end
349
388
 
350
- it "should default to 0 redirects" do
351
- EventMachine.run {
352
- http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/redirect').get
353
- http.errback { failed }
354
- http.callback {
355
- http.response_header.status.should == 301
356
- http.last_effective_url.to_s.should == 'http://127.0.0.1:8080/gzip'
357
- http.redirects.should == 0
389
+ it "should default to 0 redirects" do
390
+ EventMachine.run {
391
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/redirect').get
392
+ http.errback { failed }
393
+ http.callback {
394
+ http.response_header.status.should == 301
395
+ http.last_effective_url.to_s.should == 'http://127.0.0.1:8080/gzip'
396
+ http.redirects.should == 0
358
397
 
359
- EM.stop
398
+ EM.stop
399
+ }
360
400
  }
361
- }
362
- end
401
+ end
363
402
 
364
- it "should not invoke redirect logic on failed connections" do
365
- EventMachine.run {
366
- http = EventMachine::HttpRequest.new('http://127.0.0.1:8081/').get :timeout => 0.1, :redirects => 5
367
- http.callback { failed }
368
- http.errback {
369
- http.redirects.should == 0
370
- EM.stop
403
+ it "should not invoke redirect logic on failed connections" do
404
+ EventMachine.run {
405
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8081/').get :timeout => 0.1, :redirects => 5
406
+ http.callback { failed }
407
+ http.errback {
408
+ http.redirects.should == 0
409
+ EM.stop
410
+ }
371
411
  }
372
- }
412
+ end
413
+
414
+ it "should normalize redirect urls" do
415
+ EventMachine.run {
416
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/redirect/bad').get :redirects => 1
417
+ http.errback { failed }
418
+ http.callback {
419
+ http.last_effective_url.to_s.should match('http://127.0.0.1:8080/')
420
+ http.response.should match('Hello, World!')
421
+ EM.stop
422
+ }
423
+ }
424
+ end
425
+
426
+ it "should fail gracefully on a missing host in absolute Location header" do
427
+ EventMachine.run {
428
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/redirect/nohost').get :redirects => 1
429
+ http.callback { failed }
430
+ http.errback {
431
+ http.error.should == 'Location header format error'
432
+ EM.stop
433
+ }
434
+ }
435
+ end
436
+
437
+ it "should fail gracefully on an invalid host in Location header" do
438
+ pending "validate tld's?"
439
+ EventMachine.run {
440
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/redirect/badhost').get :redirects => 1
441
+ http.callback { failed }
442
+ http.errback {
443
+ http.error.should == 'Location header format error'
444
+ EM.stop
445
+ }
446
+ }
447
+ end
373
448
  end
374
449
 
375
450
  it "should optionally pass the response body progressively" do
@@ -593,35 +668,93 @@ describe EventMachine::HttpRequest do
593
668
  EventMachine::MockHttpRequest.count('http://www.google.ca:80/', :get, {}).should == 1
594
669
  end
595
670
 
596
- context "connections via proxy" do
671
+ context "connections via" do
672
+ context "direct proxy" do
673
+ it "should default to skip CONNECT" do
674
+ EventMachine.run {
597
675
 
598
- it "should work with proxy servers" do
599
- EventMachine.run {
676
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/?q=test').get :proxy => {
677
+ :host => '127.0.0.1', :port => 8083
678
+ }
679
+
680
+ http.errback { p http.inspect; failed }
681
+ http.callback {
682
+ http.response_header.status.should == 200
683
+ http.response.should match('test')
684
+ EventMachine.stop
685
+ }
686
+ }
687
+ end
600
688
 
601
- http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').get :proxy => {:host => '127.0.0.1', :port => 8082}
689
+ it "should send absolute URIs to the proxy server" do
690
+ EventMachine.run {
602
691
 
603
- http.errback { p http.inspect; failed }
604
- http.callback {
605
- http.response_header.status.should == 200
606
- http.response.should == 'Hello, World!'
607
- EventMachine.stop
692
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/?q=test').get :proxy => {
693
+ :host => '127.0.0.1', :port => 8083
694
+ }
695
+
696
+ http.errback { p http.inspect; failed }
697
+ http.callback {
698
+ http.response_header.status.should == 200
699
+ # The test proxy server gives the requested uri back in this header
700
+ http.response_header['X_THE_REQUESTED_URI'].should == 'http://127.0.0.1:8080/?q=test'
701
+ http.response_header['X_THE_REQUESTED_URI'].should_not == '/?q=test'
702
+ http.response.should match('test')
703
+ EventMachine.stop
704
+ }
608
705
  }
609
- }
706
+ end
707
+
708
+ it "should include query parameters specified in the options" do
709
+ EventMachine.run {
710
+
711
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').get(
712
+ :proxy => { :host => '127.0.0.1', :port => 8083 },
713
+ :query => { 'q' => 'test' }
714
+ )
715
+
716
+ http.errback { p http.inspect; failed }
717
+ http.callback {
718
+ http.response_header.status.should == 200
719
+ http.response.should match('test')
720
+ EventMachine.stop
721
+ }
722
+ }
723
+ end
610
724
  end
611
725
 
612
- it "should proxy POST data" do
613
- EventMachine.run {
726
+ context "CONNECT proxy" do
727
+ it "should work with CONNECT proxy servers" do
728
+ EventMachine.run {
614
729
 
615
- http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').post({
616
- :body => "data", :proxy => {:host => '127.0.0.1', :port => 8082}})
730
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').get({
731
+ :proxy => {:host => '127.0.0.1', :port => 8082, :use_connect => true}
732
+ })
617
733
 
618
- http.errback { failed }
619
- http.callback {
620
- http.response_header.status.should == 200
621
- http.response.should match(/data/)
622
- EventMachine.stop
734
+ http.errback { p http.inspect; failed }
735
+ http.callback {
736
+ http.response_header.status.should == 200
737
+ http.response.should == 'Hello, World!'
738
+ EventMachine.stop
739
+ }
623
740
  }
624
- }
741
+ end
742
+
743
+ it "should proxy POST data" do
744
+ EventMachine.run {
745
+
746
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').post({
747
+ :body => "data", :proxy => {:host => '127.0.0.1', :port => 8082, :use_connect => true}
748
+ })
749
+
750
+ http.errback { failed }
751
+ http.callback {
752
+ http.response_header.status.should == 200
753
+ http.response.should match(/data/)
754
+ EventMachine.stop
755
+ }
756
+ }
757
+ end
625
758
  end
626
759
  end
627
760