em-http-request 0.2.10 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

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