Net-WURFL-ScientiaMobile

 view release on metacpan or  search on metacpan

lib/Net/WURFL/ScientiaMobile.pm  view on Meta::CPAN

    
    if (!$self->_http_success) {
        # The capability is not in the cache (http_client was not called) - query the Cloud
        # to see if we even have the capability
        $self->_source(SOURCE_CLOUD);
        $self->callWurflCloud;
        $self->validateCache;
        if ($self->_source eq SOURCE_CLOUD) {
            $self->cache->setDevice($self->_user_agent, $self->capabilities);
            return $self->capabilities->{$capability} if exists $self->capabilities->{$capability};
        }
    }
    Net::WURFL::ScientiaMobile::Exception::InvalidCapability->throw
        ("The requested capability ($capability) is invalid or you are not subscribed to it.");
}

sub getUserAgent {
    my $self = shift;
    my ($env) = @_;
    
    $env ||= \%ENV;
    $env = $env->to_hash if ref $env eq 'Mojo::Headers';
    if (ref $env eq 'HTTP::Headers') {
        my $headers = {};
        $env->scan(sub { $headers->{$_[0]} = $_[1] });
        $env = $headers;
    }
    
    my $user_agent;
    if (defined $env->{QUERY_STRING} && $env->{QUERY_STRING} =~ /\bUA=([^&]+)/) {
        $user_agent = uri_unescape($1);
    } else {
        $user_agent = first { $_ } @$env{@user_agent_headers};
    }
    return substr $user_agent || '', 0, 255;
}

sub _callWurflCloud {
    my $self = shift;
    
    my %headers = ();
    
    # If the reportInterval is enabled and past the report age, include the report data
    # in the next request
    if ($self->report_interval > 0 && $self->cache->getReportAge >= $self->report_interval) {
        $self->addReportDataToRequest;
        
        $self->_report_data($self->cache->getCounters);
        $headers{'X-Cloud-Counters'} = join ',',
            map "$_:" . $self->_report_data->{$_},
            keys %{$self->report_data};
        
        $self->cache->resetReportAge;
        $self->cache->resetCounters;
    }
    
    # Add HTTP Headers to pending request
    $headers{'User-Agent'} = $self->_user_agent;
    $headers{'X-Cloud-Client'} = __PACKAGE__ . " $VERSION";
    
    # Add X-Forwarded-For
    {
        my $ip = $self->_http_request->{REMOTE_ADDR};
        my $fwd = $self->_http_request->{HTTP_X_FORWARDED_FOR};
        if ($ip) {
            $headers{'X-Forwarded-For'} = "$ip" . ($fwd ? ", $fwd" : "");
        }
    }
    
    # We use 'X-Accept' so it doesn't stomp on our deflate/gzip header
    $headers{'X-Accept'} = $self->_http_request->{HTTP_ACCEPT} if $self->_http_request->{HTTP_ACCEPT};
    {
        my $wap_profile = first { $_ } @{$self->_http_request}{qw(HTTP_X_WAP_PROFILE HTTP_PROFILE)};
        $headers{'X-Wap-Profile'} = $wap_profile if $wap_profile;
    }
    
    my $request_path = @{$self->_search_capabilities} == 0
        ? '/v1/json/'
        : '/v1/json/search:(' . join(',', @{$self->_search_capabilities}) . ')';
    
    # Prepare request
    my $url = sprintf 'http://%s%s', $self->getCloudServer, $request_path;
    my $request = HTTP::Request->new(GET => $url);
    $request->header($_ => $headers{$_}) for keys %headers;
    $request->authorization_basic($self->_api_username, $self->_api_password);
    
    # Execute call
    $self->_http_client->timeout($self->http_timeout / 1000);
    my $response = $self->_http_client->request($request);
    $self->_http_success($response->is_success);
    if (!$response->is_success) {
        my %exceptions_by_status = qw(
            API_KEY_INVALID         ApiKeyInvalid
            AUTHENTICATION_REQUIRED NoAuthProvided
            API_KEY_EXPIRED         ApiKeyExpired
            API_KEY_REVOKED         ApiKeyRevoked
            INVALID_SIGNATURE       InvalidSignature
        );
        if (exists $exceptions_by_status{$response->message}) {
            ("Net::WURFL::ScientiaMobile::Exception::" . $exceptions_by_status{$response->message})->throw
                (error => $response->status_line, response => $response);
        } else {
            Net::WURFL::ScientiaMobile::Exception::HTTP->throw(
                error    => "Unable to contact server: " . $response->status_line,
                response => $response,
            );
        }
    }
    try {
        $self->_json(decode_json($response->content));
    } catch {
        Net::WURFL::ScientiaMobile::Exception::HTTP->throw(
            error    => "Unable to parse JSON response from server: $_",
            response => $response,
            code     => ERROR_BAD_RESPONSE,
        );
    };
    
    $self->_errors($self->_json->{errors});
    $self->_api_version($self->_json->{apiVersion} || '');
    $self->_loaded_date($self->_json->{mtime} || '');
    $self->capabilities->{id} = $self->_json->{id} || '';
    $self->capabilities->{$_} = $self->_json->{capabilities}{$_}
        for keys %{$self->_json->{capabilities}};
}



( run in 3.713 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )