http_functions.py 3.67 KB
Newer Older
Thilo Molitor's avatar
Thilo Molitor committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# -*- coding: utf-8 -*-
##
## This file is part of Gajim.
##
## Gajim is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 3 only.
##
## Gajim is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Gajim.  If not, see <http://www.gnu.org/licenses/>.
##

import urllib.request as urllib2
import socket
20
import ssl
21 22
import logging
import os
Thilo Molitor's avatar
Thilo Molitor committed
23 24

from gajim.common import app
Philipp Hörist's avatar
Philipp Hörist committed
25
from gajim.plugins.plugins_i18n import _
26 27


Thilo Molitor's avatar
Thilo Molitor committed
28 29 30
if os.name == 'nt':
    import certifi

Philipp Hörist's avatar
Philipp Hörist committed
31
log = logging.getLogger('gajim.p.preview.http_functions')
Thilo Molitor's avatar
Thilo Molitor committed
32

33 34
def get_http_head(account, url, verify):
    return _get_http_head_direct(url, verify)
Thilo Molitor's avatar
Thilo Molitor committed
35 36

def get_http_file(account, attrs):
37
    return _get_http_direct(attrs)
Thilo Molitor's avatar
Thilo Molitor committed
38

39
def _get_http_head_direct(url, verify):
Philipp Hörist's avatar
Philipp Hörist committed
40
    log.info('Head request direct for URL: %s', url)
Thilo Molitor's avatar
Thilo Molitor committed
41 42 43 44
    try:
        req = urllib2.Request(url)
        req.get_method = lambda: 'HEAD'
        req.add_header('User-Agent', 'Gajim %s' % app.version)
45 46 47 48 49
        if not verify:
            context = ssl.create_default_context()
            context.check_hostname = False
            context.verify_mode = ssl.CERT_NONE
            log.warning('CERT Verification disabled')
Daniel Brötzmann's avatar
Daniel Brötzmann committed
50
            file_ = urllib2.urlopen(req, timeout=30, context=context)
Thilo Molitor's avatar
Thilo Molitor committed
51
        else:
52
            if os.name == 'nt':
Daniel Brötzmann's avatar
Daniel Brötzmann committed
53
                file_ = urllib2.urlopen(req, cafile=certifi.where())
54
            else:
Daniel Brötzmann's avatar
Daniel Brötzmann committed
55
                file_ = urllib2.urlopen(req)
Thilo Molitor's avatar
Thilo Molitor committed
56
    except Exception as ex:
Philipp Hörist's avatar
Philipp Hörist committed
57
        log.debug('Error', exc_info=True)
Thilo Molitor's avatar
Thilo Molitor committed
58
        return ('', 0)
Daniel Brötzmann's avatar
Daniel Brötzmann committed
59 60
    ctype = file_.headers['Content-Type']
    clen = file_.headers['Content-Length']
Thilo Molitor's avatar
Thilo Molitor committed
61 62
    try:
        clen = int(clen)
63
    except (TypeError, ValueError):
Thilo Molitor's avatar
Thilo Molitor committed
64 65 66 67
        pass
    return (ctype, clen)

def _get_http_direct(attrs):
Daniel Brötzmann's avatar
Daniel Brötzmann committed
68
    '''
Thilo Molitor's avatar
Thilo Molitor committed
69 70
    Download a file. This function should
    be launched in a separated thread.
Daniel Brötzmann's avatar
Daniel Brötzmann committed
71
    '''
Philipp Hörist's avatar
Philipp Hörist committed
72
    log.info('Get request direct for URL: %s', attrs['src'])
Thilo Molitor's avatar
Thilo Molitor committed
73 74 75 76 77 78
    mem, alt, max_size = b'', '', 2 * 1024 * 1024
    if 'max_size' in attrs:
        max_size = attrs['max_size']
    try:
        req = urllib2.Request(attrs['src'])
        req.add_header('User-Agent', 'Gajim ' + app.version)
79 80 81 82 83
        if not attrs['verify']:
            context = ssl.create_default_context()
            context.check_hostname = False
            context.verify_mode = ssl.CERT_NONE
            log.warning('CERT Verification disabled')
Daniel Brötzmann's avatar
Daniel Brötzmann committed
84
            file_ = urllib2.urlopen(req, timeout=30, context=context)
Thilo Molitor's avatar
Thilo Molitor committed
85
        else:
86
            if os.name == 'nt':
Daniel Brötzmann's avatar
Daniel Brötzmann committed
87
                file_ = urllib2.urlopen(req, cafile=certifi.where())
88
            else:
Daniel Brötzmann's avatar
Daniel Brötzmann committed
89
                file_ = urllib2.urlopen(req)
Thilo Molitor's avatar
Thilo Molitor committed
90
    except Exception as ex:
Philipp Hörist's avatar
Philipp Hörist committed
91
        log.debug('Error', exc_info=True)
Thilo Molitor's avatar
Thilo Molitor committed
92 93 94 95 96
        pixbuf = None
        alt = attrs.get('alt', 'Broken image')
    else:
        while True:
            try:
Daniel Brötzmann's avatar
Daniel Brötzmann committed
97
                temp = file_.read(100)
Thilo Molitor's avatar
Thilo Molitor committed
98
            except socket.timeout as ex:
Philipp Hörist's avatar
Philipp Hörist committed
99
                log.debug('Timeout loading image %s', attrs['src'] + str(ex))
Thilo Molitor's avatar
Thilo Molitor committed
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
                alt = attrs.get('alt', '')
                if alt:
                    alt += '\n'
                alt += _('Timeout loading image')
                break
            if temp:
                mem += temp
            else:
                break
            if len(mem) > max_size:
                alt = attrs.get('alt', '')
                if alt:
                    alt += '\n'
                alt += _('Image is too big')
                break
    return (mem, alt)