Example #1
0
def report_monitor_complete(task, retval, **kwargs):
    if not SENTRY_DSN or not API_ROOT:
        return

    monitor_id = task.request.headers.get('X-Sentry-Monitor')
    if not monitor_id:
        return

    try:
        checkin_id, start_time = task.request.headers.get(
            'X-Sentry-Monitor-CheckIn')
    except (ValueError, TypeError):
        return

    duration = int((time() - start_time) * 1000)

    session = SafeSession()
    session.put(u'{}/api/0/monitors/{}/checkins/{}/'.format(
        API_ROOT, monitor_id, checkin_id),
                headers={
                    'Authorization': u'DSN {}'.format(SENTRY_DSN)
                },
                json={
                    'status':
                    'error' if isinstance(retval, Exception) else 'ok',
                    'duration': duration,
                }).raise_for_status()
Example #2
0
def report_monitor_complete(task, retval, **kwargs):
    if not SENTRY_DSN or not API_ROOT:
        return

    headers = task.request.headers
    if not headers:
        return

    monitor_id = headers.get("X-Sentry-Monitor")
    if not monitor_id:
        return

    try:
        checkin_id, start_time = headers.get("X-Sentry-Monitor-CheckIn")
    except (ValueError, TypeError):
        return

    duration = int((time() - start_time) * 1000)

    session = SafeSession()
    session.put(
        u"{}/api/0/monitors/{}/checkins/{}/".format(API_ROOT, monitor_id,
                                                    checkin_id),
        headers={
            "Authorization": u"DSN {}".format(SENTRY_DSN)
        },
        json={
            "status": "error" if isinstance(retval, Exception) else "ok",
            "duration": duration
        },
    ).raise_for_status()
Example #3
0
def safe_urlopen(
    url,
    method=None,
    params=None,
    data=None,
    json=None,
    headers=None,
    allow_redirects=False,
    timeout=30,
    verify_ssl=True,
    user_agent=None,
):
    """
    A slightly safer version of ``urlib2.urlopen`` which prevents redirection
    and ensures the URL isn't attempting to hit a blacklisted IP range.
    """
    if user_agent is not None:
        warnings.warn("user_agent is no longer used with safe_urlopen")

    session = SafeSession()

    kwargs = {}

    if json:
        kwargs["json"] = json
        if not headers:
            headers = {}
        headers.setdefault("Content-Type", "application/json")

    if data:
        kwargs["data"] = data

    if params:
        kwargs["params"] = params

    if headers:
        kwargs["headers"] = headers

    if method is None:
        method = "POST" if (data or json) else "GET"

    response = session.request(method=method,
                               url=url,
                               allow_redirects=allow_redirects,
                               timeout=timeout,
                               verify=verify_ssl,
                               **kwargs)

    return response
Example #4
0
def report_monitor_begin(task, **kwargs):
    if not SENTRY_DSN or not API_ROOT:
        return

    monitor_id = task.request.headers.get('X-Sentry-Monitor')
    if not monitor_id:
        return

    with configure_scope() as scope:
        scope.set_context('monitor', {'id': monitor_id})

    session = SafeSession()
    req = session.post(u'{}/api/0/monitors/{}/checkins/'.format(API_ROOT, monitor_id), headers={
        'Authorization': u'DSN {}'.format(SENTRY_DSN)
    }, json={
        'status': 'in_progress',
    })
    req.raise_for_status()
    # HACK:
    task.request.headers['X-Sentry-Monitor-CheckIn'] = (req.json()['id'], time())
Example #5
0
def report_monitor_begin(task, **kwargs):
    if not SENTRY_DSN or not API_ROOT:
        return

    monitor_id = task.request.headers.get('X-Sentry-Monitor')
    if not monitor_id:
        return

    with configure_scope() as scope:
        scope.set_context('monitor', {'id': monitor_id})

    session = SafeSession()
    req = session.post(u'{}/api/0/monitors/{}/checkins/'.format(API_ROOT, monitor_id), headers={
        'Authorization': u'DSN {}'.format(SENTRY_DSN)
    }, json={
        'status': 'in_progress',
    })
    req.raise_for_status()
    # HACK:
    task.request.headers['X-Sentry-Monitor-CheckIn'] = (req.json()['id'], time())
Example #6
0
def report_monitor_begin(task, **kwargs):
    if not SENTRY_DSN or not API_ROOT:
        return

    monitor_id = task.request.headers.get("X-Sentry-Monitor")
    if not monitor_id:
        return

    with configure_scope() as scope:
        scope.set_context("monitor", {"id": monitor_id})

    session = SafeSession()
    req = session.post(
        u"{}/api/0/monitors/{}/checkins/".format(API_ROOT, monitor_id),
        headers={"Authorization": u"DSN {}".format(SENTRY_DSN)},
        json={"status": "in_progress"},
    )
    req.raise_for_status()
    # HACK:
    task.request.headers["X-Sentry-Monitor-CheckIn"] = (req.json()["id"], time())
Example #7
0
def report_monitor_complete(task, retval, **kwargs):
    if not SENTRY_DSN or not API_ROOT:
        return

    monitor_id = task.request.headers.get('X-Sentry-Monitor')
    if not monitor_id:
        return

    try:
        checkin_id, start_time = task.request.headers.get('X-Sentry-Monitor-CheckIn')
    except (ValueError, TypeError):
        return

    duration = int((time() - start_time) * 1000)

    session = SafeSession()
    session.put(u'{}/api/0/monitors/{}/checkins/{}/'.format(API_ROOT, monitor_id, checkin_id), headers={
        'Authorization': u'DSN {}'.format(SENTRY_DSN)
    }, json={
        'status': 'error' if isinstance(retval, Exception) else 'ok',
        'duration': duration,
    }).raise_for_status()
Example #8
0
def report_monitor_begin(task, **kwargs):
    if not SENTRY_DSN or not API_ROOT:
        return

    headers = task.request.headers
    if not headers:
        return

    monitor_id = headers.get("X-Sentry-Monitor")
    if not monitor_id:
        return

    with configure_scope() as scope:
        scope.set_context("monitor", {"id": monitor_id})

    with SafeSession() as session:
        req = session.post(
            f"{API_ROOT}/api/0/monitors/{monitor_id}/checkins/",
            headers={"Authorization": f"DSN {SENTRY_DSN}"},
            json={"status": "in_progress"},
        )
        req.raise_for_status()
        # HACK:
        headers["X-Sentry-Monitor-CheckIn"] = (req.json()["id"], time())
Example #9
0
def fetch_file(
    url,
    domain_lock_enabled=True,
    outfile=None,
    headers=None,
    allow_redirects=True,
    verify_ssl=False,
    timeout=settings.SENTRY_SOURCE_FETCH_SOCKET_TIMEOUT,
    **kwargs,
):
    """
    Pull down a URL, returning a UrlResult object.
    """
    # lock down domains that are problematic
    if domain_lock_enabled:
        domain = urlparse(url).netloc
        domain_key = "source:blacklist:v2:%s" % (
            md5_text(domain).hexdigest(), )
        domain_result = cache.get(domain_key)
        if domain_result:
            domain_result["url"] = url
            raise CannotFetch(domain_result)

    logger.debug("Fetching %r from the internet", url)

    with SafeSession() as http_session:
        response = None

        try:
            try:
                start = time.time()
                response = http_session.get(
                    url,
                    allow_redirects=allow_redirects,
                    verify=verify_ssl,
                    headers=headers,
                    timeout=timeout,
                    stream=True,
                    **kwargs,
                )

                try:
                    cl = int(response.headers["content-length"])
                except (LookupError, ValueError):
                    cl = 0
                if cl > settings.SENTRY_SOURCE_FETCH_MAX_SIZE:
                    raise OverflowError()

                return_body = False
                if outfile is None:
                    outfile = six.BytesIO()
                    return_body = True

                cl = 0

                # Only need to even attempt to read the response body if we
                # got a 200 OK
                if response.status_code == 200:
                    for chunk in response.iter_content(16 * 1024):
                        if time.time(
                        ) - start > settings.SENTRY_SOURCE_FETCH_TIMEOUT:
                            raise Timeout()
                        outfile.write(chunk)
                        cl += len(chunk)
                        if cl > settings.SENTRY_SOURCE_FETCH_MAX_SIZE:
                            raise OverflowError()

            except Exception as exc:
                logger.debug("Unable to fetch %r", url, exc_info=True)
                if isinstance(exc, RestrictedIPAddress):
                    error = {
                        "type": EventError.RESTRICTED_IP,
                        "url": expose_url(url)
                    }
                elif isinstance(exc, SuspiciousOperation):
                    error = {
                        "type": EventError.SECURITY_VIOLATION,
                        "url": expose_url(url)
                    }
                elif isinstance(exc, (Timeout, ReadTimeout)):
                    error = {
                        "type": EventError.FETCH_TIMEOUT,
                        "url": expose_url(url),
                        "timeout": settings.SENTRY_SOURCE_FETCH_TIMEOUT,
                    }
                elif isinstance(exc, OverflowError):
                    error = {
                        "type":
                        EventError.FETCH_TOO_LARGE,
                        "url":
                        expose_url(url),
                        # We want size in megabytes to format nicely
                        "max_size":
                        float(settings.SENTRY_SOURCE_FETCH_MAX_SIZE) / 1024 /
                        1024,
                    }
                elif isinstance(
                        exc,
                    (RequestException, ZeroReturnError, OpenSSLError)):
                    error = {
                        "type": EventError.FETCH_GENERIC_ERROR,
                        "value": six.text_type(type(exc)),
                        "url": expose_url(url),
                    }
                else:
                    logger.exception(six.text_type(exc))
                    error = {
                        "type": EventError.UNKNOWN_ERROR,
                        "url": expose_url(url)
                    }

                # TODO(dcramer): we want to be less aggressive on disabling domains
                if domain_lock_enabled:
                    cache.set(domain_key, error or "", 300)
                    logger.warning("source.disabled", extra=error)
                raise CannotFetch(error)

            headers = {k.lower(): v for k, v in response.headers.items()}
            encoding = response.encoding

            body = None
            if return_body:
                body = outfile.getvalue()
                outfile.close()  # we only want to close StringIO

            result = (headers, body, response.status_code, encoding)
        finally:
            if response is not None:
                response.close()

        return UrlResult(url, result[0], result[1], result[2], result[3])