summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Gregorio <jcgregorio@google.com>2012-07-23 14:45:17 -0400
committerJoe Gregorio <jcgregorio@google.com>2012-07-23 14:45:17 -0400
commitb30ed37f0c2209a7f2397c8e7b8d4d252fa16262 (patch)
tree011c79385c9d239d8927a6c8295ff215e9ecf85d
parent9f1f9ede0faf3f36b8f463f781b9860d8c56009a (diff)
downloadhttplib2-b30ed37f0c2209a7f2397c8e7b8d4d252fa16262.tar.gz
Add control so that Authorization: headers aren't forwarded on a 3xx response by default.
-rw-r--r--doc/html/_sources/libhttplib2.txt9
-rw-r--r--doc/html/genindex.html10
-rw-r--r--doc/html/index.html2
-rw-r--r--doc/html/libhttplib2.html12
-rw-r--r--doc/html/objects.invbin1700 -> 667 bytes
-rw-r--r--doc/html/search.html2
-rw-r--r--doc/html/searchindex.js2
-rw-r--r--doc/libhttplib2.rst9
-rw-r--r--libhttplib2.tex8
-rw-r--r--python2/httplib2/__init__.py7
-rwxr-xr-xpython2/httplib2test.py14
-rw-r--r--python3/httplib2/__init__.py5
12 files changed, 72 insertions, 8 deletions
diff --git a/doc/html/_sources/libhttplib2.txt b/doc/html/_sources/libhttplib2.txt
index 53cb746..fc72bbf 100644
--- a/doc/html/_sources/libhttplib2.txt
+++ b/doc/html/_sources/libhttplib2.txt
@@ -307,6 +307,15 @@ Http Objects
'follow_redirects' must be True.
+.. attribute:: Http.forward_authorization_headers
+
+ If ``False``, which is the default, then Authorization: headers are
+ stripped from redirects. If ``True`` then Authorization: headers are left
+ in place when following redirects. This parameter only applies if following
+ redirects is turned on. Note that turning this on could cause your credentials
+ to leak, so carefully consider the consequences.
+
+
.. attribute:: Http.force_exception_to_status_code
If ``True`` then no :mod:`httplib2` exceptions will be
diff --git a/doc/html/genindex.html b/doc/html/genindex.html
index 9d54153..8e41809 100644
--- a/doc/html/genindex.html
+++ b/doc/html/genindex.html
@@ -124,17 +124,21 @@
<dt><a href="libhttplib2.html#httplib2.Http.follow_all_redirects">follow_all_redirects (httplib2.Http attribute)</a>
</dt>
- </dl></td>
- <td style="width: 33%" valign="top"><dl>
<dt><a href="libhttplib2.html#httplib2.Http.follow_redirects">follow_redirects (httplib2.Http attribute)</a>
</dt>
+ </dl></td>
+ <td style="width: 33%" valign="top"><dl>
<dt><a href="libhttplib2.html#httplib2.Http.force_exception_to_status_code">force_exception_to_status_code (httplib2.Http attribute)</a>
</dt>
+ <dt><a href="libhttplib2.html#httplib2.Http.forward_authorization_headers">forward_authorization_headers (httplib2.Http attribute)</a>
+ </dt>
+
+
<dt><a href="libhttplib2.html#httplib2.Response.fromcache">fromcache (httplib2.Response attribute)</a>
</dt>
@@ -330,7 +334,7 @@
</div>
<div class="footer">
&copy; Copyright 2008, Joe Gregorio.
- Last updated on Apr 17, 2012.
+ Last updated on Jul 23, 2012.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
</div>
</body>
diff --git a/doc/html/index.html b/doc/html/index.html
index 40d4b9f..606200b 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -145,7 +145,7 @@ caching, keep-alive, compression, redirects and many kinds of authentication.</p
</div>
<div class="footer">
&copy; Copyright 2008, Joe Gregorio.
- Last updated on Apr 17, 2012.
+ Last updated on Jul 23, 2012.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
</div>
</body>
diff --git a/doc/html/libhttplib2.html b/doc/html/libhttplib2.html
index 8c18816..12301a4 100644
--- a/doc/html/libhttplib2.html
+++ b/doc/html/libhttplib2.html
@@ -296,6 +296,16 @@ Another way of saying that is for &#8216;follow_all_redirects&#8217; to have any
</dd></dl>
<dl class="attribute">
+<dt id="httplib2.Http.forward_authorization_headers">
+<tt class="descclassname">Http.</tt><tt class="descname">forward_authorization_headers</tt><a class="headerlink" href="#httplib2.Http.forward_authorization_headers" title="Permalink to this definition">¶</a></dt>
+<dd><p>If <tt class="docutils literal"><span class="pre">False</span></tt>, which is the default, then Authorization: headers are
+stripped from redirects. If <tt class="docutils literal"><span class="pre">True</span></tt> then Authorization: headers are left
+in place when following redirects. This parameter only applies if following
+redirects is turned on. Note that turning this on could cause your credentials
+to leak, so carefully consider the consequences.</p>
+</dd></dl>
+
+<dl class="attribute">
<dt id="httplib2.Http.force_exception_to_status_code">
<tt class="descclassname">Http.</tt><tt class="descname">force_exception_to_status_code</tt><a class="headerlink" href="#httplib2.Http.force_exception_to_status_code" title="Permalink to this definition">¶</a></dt>
<dd><p>If <tt class="docutils literal"><span class="pre">True</span></tt> then no <a class="reference internal" href="#module-httplib2" title="httplib2"><tt class="xref py py-mod docutils literal"><span class="pre">httplib2</span></tt></a> exceptions will be
@@ -515,7 +525,7 @@ request.</p>
</div>
<div class="footer">
&copy; Copyright 2008, Joe Gregorio.
- Last updated on Apr 17, 2012.
+ Last updated on Jul 23, 2012.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
</div>
</body>
diff --git a/doc/html/objects.inv b/doc/html/objects.inv
index 31ac672..5b3e2fd 100644
--- a/doc/html/objects.inv
+++ b/doc/html/objects.inv
Binary files differ
diff --git a/doc/html/search.html b/doc/html/search.html
index e01c727..92973d7 100644
--- a/doc/html/search.html
+++ b/doc/html/search.html
@@ -99,7 +99,7 @@
</div>
<div class="footer">
&copy; Copyright 2008, Joe Gregorio.
- Last updated on Apr 17, 2012.
+ Last updated on Jul 23, 2012.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
</div>
</body>
diff --git a/doc/html/searchindex.js b/doc/html/searchindex.js
index 1c76b54..e71997e 100644
--- a/doc/html/searchindex.js
+++ b/doc/html/searchindex.js
@@ -1 +1 @@
-Search.setIndex({objects:{"":{httplib2:[1,0,1,""]},"httplib2.Response":{status:[1,3,1,""],reason:[1,3,1,""],version:[1,3,1,""],previous:[1,3,1,""],fromcache:[1,3,1,""]},"httplib2.Cache":{get:[1,2,1,""],set:[1,2,1,""],"delete":[1,2,1,""]},"httplib2.Http":{follow_redirects:[1,3,1,""],request:[1,2,1,""],force_exception_to_status_code:[1,3,1,""],clear_credentials:[1,2,1,""],optimistic_concurrency_methods:[1,3,1,""],follow_all_redirects:[1,3,1,""],add_certificate:[1,2,1,""],ignore_etag:[1,3,1,""],add_credentials:[1,2,1,""]},httplib2:{HttpLib2Error:[1,4,1,""],RETRIES:[1,5,1,""],Http:[1,1,1,""],FileCache:[1,1,1,""],UnimplementedHmacDigestAuthOptionError:[1,4,1,""],FailedToDecompressContent:[1,4,1,""],Response:[1,1,1,""],ServerNotFoundError:[1,4,1,""],RedirectMissingLocation:[1,4,1,""],debuglevel:[1,5,1,""],RedirectLimit:[1,4,1,""],RelativeURIError:[1,4,1,""],ProxyInfo:[1,1,1,""],UnimplementedDigestAuthOptionError:[1,4,1,""]}},terms:{all:1,code:1,chain:1,proxy_type_xxx:1,follow:1,privat:1,readabl:1,those:1,sent:1,liter:1,everi:1,string:1,fals:1,unfamiliar:1,proxy_typ:1,veri:1,affect:1,tri:1,force_exception_to_status_cod:1,level:1,list:1,"try":1,item:1,second:1,pass:1,"13t18":1,append:1,index:0,section:1,current:1,delet:1,version:1,"new":1,method:1,funtion:1,xml:1,deriv:1,gener:1,here:1,bodi:1,proxy_us:1,address:1,redirectmissingloc:1,ignore_etag:1,modifi:1,valu:1,search:0,respon:1,proxy_rdn:1,memcach:1,amount:1,connection_typ:1,implement:1,extra:1,appli:1,modul:[0,1],keyfil:1,filenam:1,"boolean":1,from:1,call:1,type:1,more:1,flat:1,trail:1,flag:1,cach:[0,1],must:1,none:1,hmacdigest:1,optimistic_concurrency_method:1,unimplementedhmacdigestauthoptionerror:1,can:1,aliv:[0,1],control:1,claim:1,process:1,challeng:1,indic:[0,1],aaaa:1,occur:1,multipl:1,anoth:1,instead:1,simpl:1,updat:1,map:1,mar:0,resourc:1,proxy_info:1,tact:1,befor:1,mai:1,httpconnect:1,data:1,unreserv:1,attempt:1,nativ:1,credenti:1,robot:1,inform:1,preced:1,allow:1,shadi:1,over:1,report:1,through:1,still:1,mainli:1,digest:1,paramet:1,uuid:1,complex:1,comprehens:[0,1],them:1,failedtodecompresscont:1,"return":1,thei:1,handl:[0,1],safe:1,httplib2:[0,1],gregorio:0,"80da344efa6a":1,httplib:1,name:1,authent:[0,1],timeout:1,each:1,debug:1,mean:1,compil:1,domain:1,follow_redirect:1,connect:1,our:1,variabl:1,proxy_pass:1,urlencod:1,publish:1,content:[0,1],etag:1,rel:1,debuglevel:1,print:1,proxi:1,fred:1,reason:1,base:1,dictionari:1,put:1,org:1,thrown:1,keep:[0,1],turn:1,unabl:1,caprici:1,first:1,oper:1,certfil:1,number:1,restrict:1,date:0,alreadi:1,done:1,messag:1,oppos:1,open:1,given:1,disable_ssl_certificate_valid:1,construct:1,attach:1,john:1,"final":1,store:1,xmln:1,option:1,specifi:1,cfb8:1,checkout:1,httplib2error:1,kind:0,provid:1,remov:1,proxy_type_http:1,were:1,pre:1,sai:1,ani:1,manner:1,have:1,tabl:0,mypasswd:1,note:1,also:1,client:[0,1],take:1,which:1,singl:1,begin:1,ca_cert:1,normal:1,previou:1,compress:[0,1],gzip:1,"class":1,urn:1,request:1,uri:1,doe:1,determin:1,text:1,unimplementeddigestauthoptionerror:1,redirect:[0,1],absolut:1,onli:1,locat:1,should:1,dict:1,bitwork:1,get:1,filecach:1,ssl:1,"3xx":1,requir:1,patch:1,contain:1,mynam:1,where:1,certif:1,set:1,see:1,respons:[0,1],fail:1,statu:1,detect:1,urllib:1,"import":1,"02z":1,attribut:1,kei:1,numer:1,proxy_port:1,entir:1,joe:0,come:1,popul:1,both:1,last:1,etc:1,instanc:1,mani:0,com:1,point:1,servernotfounderror:1,colon:1,suppli:1,ultim:1,three:1,compon:1,basic:1,addit:1,assert:1,understand:1,present:1,"case":1,plain:1,defin:1,error:1,"4ebb":1,dir_nam:1,need:1,follow_all_redirect:1,author:[0,1],perform:1,satisfi:1,cert:1,same:1,add_certif:1,html:1,complet:1,http:[0,1],rfc822:1,decompress:1,rais:1,chang:1,lower:1,entri:1,without:1,exampl:[0,1],add_credenti:1,thi:1,entiti:1,protocol:1,just:1,resp:1,human:1,httprespons:1,proxy_host:1,except:1,proxyinfo:1,add:1,match:1,applic:1,format:1,safenam:1,password:1,presum:1,amok:1,redirectlimit:1,lost:1,header:1,docutil:1,resolv:1,server:1,collect:1,either:1,page:0,encount:1,exceed:1,deal:1,some:1,back:1,librari:[0,1],clear_credenti:1,subclass:1,pem:1,retri:1,condit:1,localhost:1,object:[0,1],run:1,power:1,reach:1,broken:1,host:1,post:1,deflat:1,socket:1,default_max_redirect:1,fromcach:1,constructor:1,processor:1,own:1,www:1,automat:1,your:1,span:1,wai:1,support:1,sock:1,avail:1,interfac:1,includ:1,head:1,form:1,tupl:1,atom:1,"true":1,info:1,made:1,possibl:1,"default":1,wish:1,maximum:1,problem:1,"1225c695":1,featur:1,constant:1,creat:1,"abstract":0,repres:1,chap:1,exist:1,file:1,relativeurierror:1,titl:1,when:1,valid:1,you:1,lane:1,algorithm:1,directori:1,wsse:1,ignor:1,time:1},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:exception","5":"py:data"},titles:["The httplib2 Library","<tt class=\"docutils literal docutils literal\"><span class=\"pre\">httplib2</span></tt> A comprehensive HTTP client library."],objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","exception","Python exception"],"5":["py","data","Python data"]},filenames:["index","libhttplib2"]}) \ No newline at end of file
+Search.setIndex({objects:{"":{httplib2:[1,0,1,""]},"httplib2.Response":{status:[1,3,1,""],reason:[1,3,1,""],version:[1,3,1,""],previous:[1,3,1,""],fromcache:[1,3,1,""]},"httplib2.Cache":{get:[1,2,1,""],set:[1,2,1,""],"delete":[1,2,1,""]},"httplib2.Http":{forward_authorization_headers:[1,3,1,""],follow_redirects:[1,3,1,""],request:[1,2,1,""],force_exception_to_status_code:[1,3,1,""],clear_credentials:[1,2,1,""],optimistic_concurrency_methods:[1,3,1,""],follow_all_redirects:[1,3,1,""],add_certificate:[1,2,1,""],ignore_etag:[1,3,1,""],add_credentials:[1,2,1,""]},httplib2:{HttpLib2Error:[1,4,1,""],RETRIES:[1,5,1,""],Http:[1,1,1,""],FileCache:[1,1,1,""],UnimplementedHmacDigestAuthOptionError:[1,4,1,""],FailedToDecompressContent:[1,4,1,""],Response:[1,1,1,""],ServerNotFoundError:[1,4,1,""],RedirectMissingLocation:[1,4,1,""],debuglevel:[1,5,1,""],RedirectLimit:[1,4,1,""],RelativeURIError:[1,4,1,""],ProxyInfo:[1,1,1,""],UnimplementedDigestAuthOptionError:[1,4,1,""]}},terms:{all:1,code:1,chain:1,proxy_type_xxx:1,follow:1,privat:1,readabl:1,those:1,sent:1,liter:1,everi:1,string:1,fals:1,unfamiliar:1,proxy_typ:1,veri:1,affect:1,tri:1,force_exception_to_status_cod:1,level:1,list:1,"try":1,item:1,consequ:1,second:1,pass:1,"13t18":1,append:1,index:0,section:1,current:1,delet:1,version:1,"new":1,method:1,funtion:1,redirect:[0,1],deriv:1,gener:1,here:1,bodi:1,proxy_us:1,address:1,redirectmissingloc:1,ignore_etag:1,modifi:1,valu:1,search:0,respon:1,proxy_rdn:1,memcach:1,amount:1,implement:1,extra:1,appli:1,modul:[0,1],keyfil:1,filenam:1,"boolean":1,from:1,call:1,type:1,more:1,flat:1,trail:1,flag:1,cach:[0,1],must:1,none:1,hmacdigest:1,optimistic_concurrency_method:1,unimplementedhmacdigestauthoptionerror:1,can:1,aliv:[0,1],control:1,claim:1,process:1,challeng:1,indic:[0,1],aaaa:1,occur:1,multipl:1,anoth:1,instead:1,simpl:1,updat:1,follow_redirect:1,mar:0,resourc:1,proxy_info:1,tact:1,befor:1,date:0,httpconnect:1,data:1,unreserv:1,attempt:1,ssl:1,credenti:1,robot:1,caus:1,inform:1,preced:1,allow:1,shadi:1,over:1,"3xx":1,through:1,still:1,mainli:1,digest:1,paramet:1,uuid:1,complex:1,comprehens:[0,1],them:1,failedtodecompresscont:1,"return":1,thei:1,handl:[0,1],safe:1,httplib2:[0,1],gregorio:0,"80da344efa6a":1,httplib:1,name:1,authent:[0,1],timeout:1,each:1,debug:1,mean:1,compil:1,domain:1,map:1,connect:1,our:1,variabl:1,proxy_pass:1,urlencod:1,publish:1,content:[0,1],etag:1,rel:1,debuglevel:1,print:1,proxi:1,fred:1,reason:1,base:1,dictionari:1,put:1,org:1,thrown:1,could:1,keep:[0,1],turn:1,place:1,unabl:1,caprici:1,first:1,oper:1,certfil:1,number:1,restrict:1,mai:1,alreadi:1,done:1,messag:1,oppos:1,open:1,given:1,disable_ssl_certificate_valid:1,construct:1,attach:1,john:1,"final":1,store:1,xmln:1,option:1,specifi:1,cfb8:1,httplib2error:1,kind:0,provid:1,remov:1,proxy_type_http:1,were:1,pre:1,sai:1,ani:1,manner:1,have:1,tabl:0,mypasswd:1,note:1,also:1,client:[0,1],take:1,which:1,singl:1,begin:1,ca_cert:1,normal:1,object:[0,1],compress:[0,1],gzip:1,"class":1,urn:1,request:1,uri:1,doe:1,determin:1,carefulli:1,text:1,unimplementeddigestauthoptionerror:1,xml:1,absolut:1,onli:1,locat:1,should:1,dict:1,bitwork:1,get:1,filecach:1,nativ:1,report:1,requir:1,patch:1,contain:1,mynam:1,where:1,certif:1,set:1,see:1,respons:[0,1],fail:1,statu:1,detect:1,urllib:1,"import":1,"02z":1,attribut:1,kei:1,numer:1,proxy_port:1,entir:1,joe:0,come:1,addit:1,both:1,last:1,etc:1,instanc:1,mani:0,com:1,point:1,header:1,colon:1,suppli:1,ultim:1,three:1,compon:1,basic:1,popul:1,wish:1,assert:1,understand:1,present:1,"case":1,plain:1,defin:1,error:1,"4ebb":1,dir_nam:1,applic:1,need:1,follow_all_redirect:1,author:[0,1],perform:1,satisfi:1,cert:1,same:1,add_certif:1,html:1,complet:1,http:[0,1],rfc822:1,decompress:1,rais:1,chang:1,lower:1,entri:1,without:1,exampl:[0,1],add_credenti:1,thi:1,entiti:1,left:1,protocol:1,just:1,resp:1,human:1,password:1,proxy_host:1,except:1,proxyinfo:1,add:1,match:1,connection_typ:1,format:1,safenam:1,httprespons:1,you:1,amok:1,redirectlimit:1,lost:1,servernotfounderror:1,docutil:1,resolv:1,server:1,collect:1,either:1,page:0,encount:1,exceed:1,deal:1,some:1,back:1,librari:[0,1],clear_credenti:1,leak:1,subclass:1,pem:1,retri:1,condit:1,localhost:1,previou:1,run:1,power:1,reach:1,broken:1,host:1,post:1,deflat:1,socket:1,default_max_redirect:1,fromcach:1,constructor:1,processor:1,own:1,www:1,automat:1,strip:1,your:1,span:1,wai:1,support:1,sock:1,avail:1,interfac:1,includ:1,head:1,form:1,tupl:1,atom:1,"true":1,info:1,made:1,possibl:1,"default":1,checkout:1,maximum:1,forward_authorization_head:1,problem:1,"1225c695":1,featur:1,constant:1,creat:1,"abstract":0,repres:1,chap:1,exist:1,file:1,relativeurierror:1,titl:1,when:1,valid:1,presum:1,consid:1,lane:1,algorithm:1,directori:1,wsse:1,ignor:1,time:1},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:exception","5":"py:data"},titles:["The httplib2 Library","<tt class=\"docutils literal docutils literal\"><span class=\"pre\">httplib2</span></tt> A comprehensive HTTP client library."],objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","exception","Python exception"],"5":["py","data","Python data"]},filenames:["index","libhttplib2"]}) \ No newline at end of file
diff --git a/doc/libhttplib2.rst b/doc/libhttplib2.rst
index 53cb746..fc72bbf 100644
--- a/doc/libhttplib2.rst
+++ b/doc/libhttplib2.rst
@@ -307,6 +307,15 @@ Http Objects
'follow_redirects' must be True.
+.. attribute:: Http.forward_authorization_headers
+
+ If ``False``, which is the default, then Authorization: headers are
+ stripped from redirects. If ``True`` then Authorization: headers are left
+ in place when following redirects. This parameter only applies if following
+ redirects is turned on. Note that turning this on could cause your credentials
+ to leak, so carefully consider the consequences.
+
+
.. attribute:: Http.force_exception_to_status_code
If ``True`` then no :mod:`httplib2` exceptions will be
diff --git a/libhttplib2.tex b/libhttplib2.tex
index ee04dd6..100de7a 100644
--- a/libhttplib2.tex
+++ b/libhttplib2.tex
@@ -263,6 +263,14 @@ Another way of saying that is for 'follow_all_redirects' to have any affect, 'fo
must be True.
\end{memberdesc}
+\begin{memberdesc}[Http]{forward_authorization_headers}
+If \code{False}, which is the default, then Authorization: headers are
+stripped from redirects. If \code{True} then Authorization: headers are left
+in place when following redirects. This parameter only applies if following
+redirects is turned on. Note that turning this on could cause your credentials
+to leak, so carefully consider the consequences.
+\end{memberdesc}
+
\begin{memberdesc}[Http]{follow_all_redirects}
If \code{False}, which is the default, only safe redirects are followed, where
safe means that the client is only doing a \code{GET} or \code{HEAD} on the
diff --git a/python2/httplib2/__init__.py b/python2/httplib2/__init__.py
index 6737da0..597df48 100644
--- a/python2/httplib2/__init__.py
+++ b/python2/httplib2/__init__.py
@@ -472,7 +472,7 @@ class Authentication(object):
def request(self, method, request_uri, headers, content):
"""Modify the request headers to add the appropriate
- Authorization header. Over-rise this in sub-classes."""
+ Authorization header. Over-ride this in sub-classes."""
pass
def response(self, response, content):
@@ -1231,6 +1231,9 @@ and more.
self.timeout = timeout
+ # Keep Authorization: headers on a redirect.
+ self.forward_authorization_headers = False
+
def _auth_from_challenge(self, host, request_uri, headers, response, content):
"""A generator that creates Authorization objects
that can be applied to requests.
@@ -1364,6 +1367,8 @@ and more.
del headers['if-none-match']
if headers.has_key('if-modified-since'):
del headers['if-modified-since']
+ if 'authorization' in headers and not self.forward_authorization_headers:
+ del headers['authorization']
if response.has_key('location'):
location = response['location']
old_response = copy.deepcopy(response)
diff --git a/python2/httplib2test.py b/python2/httplib2test.py
index b2cbb02..344f9ba 100755
--- a/python2/httplib2test.py
+++ b/python2/httplib2test.py
@@ -566,6 +566,20 @@ class HttpTest(unittest.TestCase):
(response, content) = self.http.request(uri, method, body=" ")
self.assertEqual(response['x-method'], method_on_303)
+ def test303AndForwardAuthorizationHeader(self):
+ # Test that all methods can be used
+ uri = urlparse.urljoin(base, "303/redirect-to-header-reflector.cgi")
+ headers = {'authorization': 'Bearer foo'}
+ response, content = self.http.request(uri, 'GET', body=" ",
+ headers=headers)
+ # self.assertTrue('authorization' not in content)
+ self.http.follow_all_redirects = True
+ self.http.forward_authorization_headers = True
+ response, content = self.http.request(uri, 'GET', body=" ",
+ headers=headers)
+ # Oh, how I wish Apache didn't eat the Authorization header.
+ # self.assertTrue('authorization' in content)
+
def testGet304(self):
# Test that we use ETags properly to validate our cache
uri = urlparse.urljoin(base, "304/test_etag.txt")
diff --git a/python3/httplib2/__init__.py b/python3/httplib2/__init__.py
index 3ab36a6..5608baa 100644
--- a/python3/httplib2/__init__.py
+++ b/python3/httplib2/__init__.py
@@ -858,6 +858,9 @@ and more.
self.timeout = timeout
+ # Keep Authorization: headers on a redirect.
+ self.forward_authorization_headers = False
+
def _auth_from_challenge(self, host, request_uri, headers, response, content):
"""A generator that creates Authorization objects
that can be applied to requests.
@@ -990,6 +993,8 @@ and more.
del headers['if-none-match']
if 'if-modified-since' in headers:
del headers['if-modified-since']
+ if 'authorization' in headers and not self.forward_authorization_headers:
+ del headers['authorization']
if 'location' in response:
location = response['location']
old_response = copy.deepcopy(response)