AWS - Lookup by ISBN

di il
1 risposte

AWS - Lookup by ISBN

Ciao a tutti,
sto provando a sviluppare uno script con le API di AWS che, dato il codice ISBN di un libro, restituisca i relativi dettagli (Titolo, Autore etc...).
Come sicuramente saprete, Amazon richiede la firma delle GET Request, che io eseguo tramite questa Funzione PHP:

$q="CODICE_ISBN";
$private_key = "LAMIAPKEY";
$params["AWSAccessKeyId"] = "LAMIAKEY";
$params["AssociateTag"] = "REFTAG";
$params["Timestamp"] = gmdate("Y-m-d\TH:i:s\Z");

function signAmazonUrl($url, $secret_key)
{
    $original_url = $url;
    // Decode anything already encoded
    $url = urldecode($url);
    // Parse the URL into $urlparts
    $urlparts  = parse_url($url);
    // Build $params with each name/value pair
    foreach (explode('&', $urlparts['query']) as $part) {
        if (strpos($part, '=')) {
            list($name, $value) = explode('=', $part, 2);
        } else {
            $name = $part;
            $value = '';
        }
        $params[$name] = $value;
    }
    // Include a timestamp if none was provided
    if (empty($params['Timestamp'])) {
        $params['Timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
    }
    // Sort the array by key
    ksort($params);
    // Build the canonical query string
    $canonical       = '';
    foreach ($params as $key => $val) {
        $canonical  .= "$key=".rawurlencode(utf8_encode($val))."&";
    }
    // Remove the trailing ampersand
    $canonical       = preg_replace("/&$/", '', $canonical);
    // Some common replacements and ones that Amazon specifically mentions
    $canonical       = str_replace(array(' ', '+', ',', ';'), array('%20', '%20', urlencode(','), urlencode(':')), $canonical);
    // Build the sign
    $string_to_sign             = "GET\n{$urlparts['host']}\n{$urlparts['path']}\n$canonical";
    // Calculate our actual signature and base64 encode it
    $signature            = base64_encode(hash_hmac('sha256', $string_to_sign, $secret_key, true));
    // Finally re-build the URL with the proper string and include the Signature
    $url = "{$urlparts['scheme']}://{$urlparts['host']}{$urlparts['path']}?$canonical&Signature=".rawurlencode($signature);
    return $url;
}

	$amazon_request=signAmazonUrl('http://webservices.amazon.com/onca/xml?Service=AWSECommerceService&Operation=ItemLookup&ResponseGroup=Large&SearchIndex=All&IdType=ISBN&ItemId='.$q.'&AWSAccessKeyId='.$params["AWSAccessKeyId"].'&AssociateTag='.$params["AssociateTag"].'&Timestamp='.$params["Timestamp"], $private_key);
echo "$amazon_request";
L'URL che viene generato però pare non andare bene ad AWS, in quanto mi viene restituito il seguente errore, quando in realtà sto eseguendo una sola richiesta:

<Error>
<Code>RequestThrottled</Code>
<Message>
AWS Access Key ID: *LAMIAKEY*. You are submitting requests too quickly. Please retry your requests at a slower rate.
</Message>
</Error>
Sapreste aiutarmi a risolvere il problema?

Grazie Mille

1 Risposte

  • Re: AWS - Lookup by ISBN

    Non conosco il codice del progetto di cui tu parli ma urlencode va usato dopo aver suddiviso la url in due parti , la seconda parte é la query string.
    rawurlencode dalla cartella root al nome file. (più specificatamente devi sostiure lo spazio bianco in %20 la funzione rawurlencode fa questo , successivamente %2F in / (é ovvio non potrai mai usare caratteri come %/#?=& o qualunque separatore usato dal proprio web server arg_separator input output etc. poiché fanno parte del dopo di una cartella) e se vuoi essere conforme la url deve essere equivalente a UTF-8 così puoi adottare il percent enconding sul singolo byte e nel browser vedrai i caratteri utf-8... La cartella deve esistere e avere il pieno controllo con quei caratteri ma molti webser hanno problemi con caratteri al di fuori di US-ASCII) Dai nuovi Browser che interpretano qualsiasi carattere al di fuori di US-ASCII a UTF-8 .
    Questo é vero la maggior parte delle volte e va applicato se il proprio applicativo non indica come trattare le url.
    Stai usando parse_url con schema, host, porta etc, la query string é presente lì, inoltre quando da PHP recuperi il valore di GET, POST (REQUEST) o COOKIE (con setcookie viene trasformato con urlencode) verrà applicato urldecode.
    Devi applicare urldecode alla query string se la stringa (url) é nel giusto output.
    Referenza sintassi IRI che con regole severe può essere trasformata in URI https://tools.ietf.org/html/rfc398
    Segue un esempio surreale (lascio inalterato = e & poiché la query string inizia da ? ed é composta dai caratteri citati)
    Non va usato é qui per completezza.
    <?php
    function my_func( $url ) {
    $var = parse_url( $url );
    // https://, default http://
    $var['scheme'] = $var['scheme'] ? ( ( substr( strtolower( $var['scheme'] ), 0, 5 ) === 'https' ) ? 'https://' : ( substr( strtolower( $var['scheme'] ), 0, 4 ) === 'http' ) ? 'http://' : 'http://' ) : 'http://';
    $var['path'] = rawurldecode( $var['path'] );
    $arg_output = '&';
    $char = urlencode( $arg_output );
    $var['query'] = urldecode( str_replace( array( '%25', $char, $arg_output, '%3D', '%3d', '=' ), array( '%25%25', '%25' . $char, $char, '%25%3D', '%25%3d', '%3D' ), $var['query'] ) );
    $var['query'] = str_replace( array( '%25', '%%', '%' . $arg_output, '%=' ), array( '%25%25', '%25', $char, '%3D' ), $var['query'] );
    $var['query'] = strtr( $var['query'], array( '%25%25' => '%25', '%25' => '%' ) );
    return $var;
    }
    $url = 'http://example.com/test%201/file.php?a=Hello+friend+%25&b=how+are+you%3Fyou%26me';
    // Output http://example.com/test 1/file.php?a=Hello friend %&b=how are you?you%26me';
    $output = my_func( $url );
    var_dump( $output );
    Nella url originale hai caratteri ? = & (%3F (%3D %26 o &amp; o &#38; dentro la query) ) al di fuori della query string?
Devi accedere o registrarti per scrivere nel forum
1 risposte