编码多部分/混合HTTP响应(适用于Android配置文件)

时间:2018-12-19 23:15:03

标签: node.js rest http nginx http-headers

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

我说过“ XML配置文件”文件,我想提供它。但是,我需要使用它的标头和结构相当复杂。这不是普通的HTTP GET。 https://source.android.com/devices/tech/connect/wifi-passpoint 说:

  

base64编码的内容必须包含MIME多部分内容,并带有   多部分/混合的Content-Type。以下部分组成   多部分内容的各个部分:

  

“个人资料”部分必须以base64编码传输,   UTF-8编码的XML文本

当我尝试捏造它时,通过删除多部分/混合位,Android的CertInstaller会因为无效的mime类型而拒绝打开xml文件。

在使用所有流行的服务器之前,我已经完成了很多Web开发:Tomcat,NodeJS,NginX,Apache,golang(gorilla),Python WSGI等。 但是我不确定如何解决这个问题。我可以用火箭筒拍打这只苍蝇:通过启动动态服务器并手动将响应与适当的标头缝合在一起。 但是:我的直觉告诉我,我应该能够使用静态Web服务器(例如NGINX或Apache)(或任何动态应用程序服务器的静态服务功能)解决此问题。 是否有一个优雅的解决方案? 另外,我还找不到这种android-profile-server的任何参考实现。仅查看一些可测试的示例代码可能有助于我解决这个难题。

1 个答案:

答案 0 :(得分:0)

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

事实证明,您需要对base64中的所有内容进行双重编码。 我最终写了一个小的python实用程序来解决这个问题。

注意:您需要将此服务与HTTPS配合使用,以便Android接受配置文件。另外,您需要使用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