Кодирование составного / смешанного HTTP-ответа (для профилей Android) - PullRequest
0 голосов
/ 20 декабря 2018

Я пытаюсь создать сервер для обслуживания статических файлов, которые являются сертификатами проходных.Этот сервер не нуждается в динамических страницах.Он должен просто обслуживать одни и те же статические ответы снова и снова.

Я сказал файл "XML profile", и я бы хотел его обслужить.Тем не менее, заголовки и структура, с которыми мне необходимо работать, довольно сложны.Это не обычный HTTP GET.https://source.android.com/devices/tech/connect/wifi-passpoint говорит:

Содержимое в кодировке base64 должно состоять из составного содержимого MIME с типом содержимого multipart / mixed.Следующие части составляют отдельные части содержимого, состоящего из нескольких частей:

и

Раздел профиля должен быть передан как base64-кодированный, UTF-8-кодированныйТекст XML

Когда я пытаюсь выдумать его, удаляя составные / смешанные биты, Android-сервер CertInstaller отказывается открывать файл XML из-за недопустимого типа MIME.

Я сделалмного раньше занимался веб-разработкой на всех популярных серверах: Tomcat, NodeJS, NginX, Apache, golang (горилла), Python WSGI и т. д. Но я не уверен, как решить эту проблему.Я мог бы смахнуть эту муху с помощью базуки: запустив динамический сервер и вручную сшивая ответ с соответствующими заголовками.Однако: мое внутреннее чувство говорит мне, что я должен быть в состоянии решить эту проблему с помощью статического веб-сервера, такого как NGINX или Apache (или возможностей статического обслуживания любого из динамических серверов приложений).Есть ли элегантное решение для этого?Кроме того, я не смог найти никаких эталонных реализаций такого сервера-профиля-андроида.Просто взглянув на некоторый тестируемый пример кода, можно решить эту дилемму.

1 Ответ

0 голосов
/ 21 декабря 2018

Глядя на исходный код Android: https://android.googlesource.com/platform/frameworks/base/+/master/wifi/java/android/net/wifi/hotspot2/ConfigParser.java

Оказывается, вам нужно дважды кодировать все в base64.Я закончил тем, что написал для этого небольшую утилиту Python.

Примечание: вам нужно предоставить это с 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...