GAE使用urllib2.urlopen出现DownloadError的问题
Jun 18, 2009
2 minutes read

GAE使用urllib2.urlopen出现DownloadError的问题

实验目的: 用flex在GAE上运行python代码 实验器材: pyamf,FLEX3,Python25,IE,GAE SDK 实验准备: GAE代码一份,flex代码一份 见下: python部分 main.py

    # -*- coding:utf-8 -*-   
    import wsgiref.handlers  
    import sys
    import urllib2  
    from google.appengine.ext import webapp  
    from pyamf.remoting.gateway.google import WebAppGateway  
      
    class MainPage(webapp.RequestHandler):  
    def get(self):  
    self.response.headers['Content-Type'] = 'text/plain'  
    self.response.out.write('Hello, webapp World!')  
      
    def echo(data):
    p=urllib2.urlopen("http://www.sina.com.cn")
    return data
      
    services = {  
    'myservice.echo': echo,  
    }  
      
    def main():  
    application_paths = [('/', WebAppGateway(services)), ('/helloworld', MainPage)]  
    application = webapp.WSGIApplication(application_paths, debug=True)  
    wsgiref.handlers.CGIHandler().run(application)  

flex部分

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init();">
    <mx:Script> 
    <![CDATA[ 
    import flash.net.*;
    import mx.controls.Alert;
    
    public function init():void{
    var netConnection:NetConnection = new NetConnection();
    netConnection.connect("http://localhost:8080/");
    var responder:Responder = new Responder(onComplete, onFail);
    netConnection.call("myservice.echo", responder, "Flash talked to PyAMF.  They both say hello.");
    }
    
    function onComplete(results):void {
    //var my:String = String("我就是中文");
    //var aTemp:Array = results as Array;
    //Alert.show(aTemp.toString());
    trace(results.toString());
    
    //trace(sTemp);
    
    /*for each(var thisResult in results){
    trace(thisResult.toString());
    }*/
    }
    
    function onFail(results):void {
    for each (var thisResult in results){
    trace( thisResult);
    }
    }
    ]]> 
    </mx:Script>
    </mx:Application>

实验步骤: 1.打开CMD,用dev_appserver开启GAE服务器 2.在Flex中运行debug命令

实验问题:

    'Traceback (most recent call last):', '  File "c:\\gaedemos\\cake\\pyamf\\remoting\\amf0.py", line 106, in __call__    *args, **kwargs)', 
    '  File "c:\\gaedemos\\cake\\pyamf\\remoting\\amf0.py", line 59, in _getBody    **kwargs)', '
    File "c:\\gaedemos\\cake\\pyamf\\remoting\\gateway\\__init__.py", line 494, in callServiceRequest    return service_request(*args)',
    '  File "c:\\gaedemos\\cake\\pyamf\\remoting\\gateway\\__init__.py", line 224, in __call__    return self.service(self.method, args)',
    '  File "c:\\gaedemos\\cake\\pyamf\\remoting\\gateway\\__init__.py", line 125, in __call__    return func(*params)', ' 
    File "c:\\gaedemos\\cake\\main.py", line 18, in echo    w.login(url)',
    '  File "c:\\gaedemos\\cake\\webspy\\webspy.py", line 42, in login    myHome = urllib2.urlopen(request)',
    '  File "C:\\Python25\\lib\\urllib2.py", line 124, in urlopen    return _opener.open(url, data)', '  
    File "C:\\Python25\\lib\\urllib2.py", line 381, in open    response = self._open(req, data)', ' 
    File "C:\\Python25\\lib\\urllib2.py", line 399, in _open    \'_open\', req)', '  File "C:\\Python25\\lib\\urllib2.py", line 360, in _call_chain    result = func(*args)', '
    File "C:\\Python25\\lib\\urllib2.py", line 1107, in http_open    return self.do_open(httplib.HTTPConnection, req)',
    '  File "C:\\Python25\\lib\\urllib2.py", line 1080, in do_open    r = h.getresponse()', '
    File "C:\\Program Files\\Google\\google_appengine\\google\\appengine\\dist\\httplib.py", line 200, in getresponse    self._allow_truncated, self._follow_redirects)', '
    File "C:\\Program Files\\Google\\google_appengine\\google\\appengine\\api\\urlfetch.py", line 241, in fetch    return rpc.get_result(allow_truncated)'
    , '  File "C:\\Program Files\\Google\\google_appengine\\google\\appengine\\api\\urlfetch.py", line 388, in get_result    self.check_success(allow_truncated)',
    '  File "C:\\Program Files\\Google\\google_appengine\\google\\appengine\\api\\urlfetch.py", line 356, in check_success    raise DownloadError(str(e))'
    , "DownloadError: ApplicationError: 2 nonnumeric port: ''"
    DownloadError
    ApplicationError: 2 nonnumeric port: ''

问题初步分析: 最后给出的结果是非数字端口,于是我想是不是没写端口号啊。加上:80后依旧。python代码在Eclipse+pydev的环境下跑的好好的,怎么到了gae就不行了呢?在网上查了好久,看到如下链接:http://groups.google.co.jp/group/google-appengine/browse_thread/thread/07f418a36888c937 其中提到 This is a known incompatibility in App Engine. The GData APIs send an absolute URL to the httplib library where it expects a relative one (since the host and port was specified in the constructor); the Python httplib handles this properly, but the App Engine replacement currently does not. 奇怪的是python和GAE不是都用的一样的内核吗?我把python25的httplib文件复制过来以后还是这个问题。

实验小结: 问题期待继续调查。 发现一个解决的方法参见 http://nodex.iteye.com/blog/360733 参考了CPYUG组织,发现这是GAE的一个限制socket的行为,所以不管怎么改都没有用。可以用urlfetch代替,不过还困惑于cookie的处理。 可以参考: https://groups.google.com/group/python-cn/browse_thread/thread/4b94c4ae8eb8d41c/54f2628668af75a0?lnk=gst&q=urlfetch#54f2628668af75a0

以后要多关注关注CPyUG了,真的好强啊。


Back to posts