代码之家  ›  专栏  ›  技术社区  ›  eshalev

编码多部分/混合http响应(用于android配置文件)

  •  0
  • eshalev  · 技术社区  · 6 年前

    我正在尝试构建一个服务器来提供碰巧是passpoint证书的静态文件。此服务器不需要任何动态页。它应该一次又一次地提供相同的静态回复。

    我已经说了“xml profile”文件,我想提供它。不过,要求我提供服务的标题和结构相当复杂。这不是普通的http get。 https://source.android.com/devices/tech/connect/wifi-passpoint 说:

    base64编码的内容必须包含mime多部分内容 多部分/混合的内容类型。以下部分构成 多部分内容的各个部分:

    配置文件部分必须以base64编码方式传输, utf-8编码的xml文本

    当我试图通过删除多部分/混合位来篡改它时,android的certinstaller拒绝打开xml文件,因为mime类型无效。

    我以前用过很多流行的服务器做过web开发:tomcat、nodejs、nginx、apache、golang(gorilla)、python wsgi等等…… 但我不知道如何解决这个问题。我可以用火箭筒拍下这只苍蝇:启动一个动态服务器,用适当的标题手工缝合响应。 然而:我的直觉告诉我,我应该能够用一个静态web服务器(比如nginx或apache)来解决这个问题(或者任何动态应用服务器的静态服务功能)。 有什么好的解决办法吗? 另外,我还没有找到这样一个android配置文件服务器的任何参考实现。只要看看一些可测试的示例代码就可以帮助我解决这个难题。

    1 回复  |  直到 6 年前
        1
  •  0
  •   eshalev    6 年前

    查看Android源代码: https://android.googlesource.com/platform/frameworks/base/+/master/wifi/java/android/net/wifi/hotspot2/ConfigParser.java

    原来你需要用Base64对所有内容进行双重编码。 最后我编写了一个小的python实用程序来实现这一点。

    注意:为了让android接受这个配置文件,您需要使用https来提供这个服务。另外,你需要使用chrome浏览器。stock/firefox不能在我的手机上使用

    @app.route('/profiles/<filename>')
    def multipart(filename):
        if("/" in filename):
            raise "ilegal name: "+filename
        with open(filename, 'r') as myfile:
            profileData = myfile.read()
            #print data
        b64Profile=b64encode(profileData).decode('ascii')
        with open("cert.crt", 'r') as myfile:
            caCertData = myfile.read()
            #print data
        b64CaCert=b64encode(caCertData).decode('ascii')
        withHeaders='''Content-Type: multipart/mixed; boundary=f6d6201be73d4e46988f789237cffb00
    Content-Transfer-Encoding: base64
    
    --f6d6201be73d4e46988f789237cffb00
    Content-Type: application/x-passpoint-profile
    Content-Transfer-Encoding: base64
    
    '''+ b64Profile+'''
    
    --f6d6201be73d4e46988f789237cffb00
    Content-Type: application/x-x509-ca-cert
    Content-Transfer-Encoding: base64
    
    '''+b64CaCert+'''
    --f6d6201be73d4e46988f789237cffb00--'''
        b64withHeaders=b64encode(withHeaders).decode('ascii')
    
        resp = make_response(b64withHeaders) #here you could use make_response(render_template(...)) too
        resp.headers['Content-Type'] = 'application/x-wifi-config'
        resp.headers['Content-Transfer-Encoding'] = 'base64'
        #resp.headers['Content-Type'] = 'multipart/mixed; boundary=f6d6201be73d4e46988f789237cffb00'
        return resp