02-03-2011 4:01 PM
Hi,
I'm trying to make an HTTP call to the Google geocode service in an 6.20 client.
The URL for the call is http://maps.googleapis.com/maps/api/geocode/xml?address=1,STREET,CITY,POSTCODE,&client=gme-ourclient...
(I've change the client and the signature to rubbish for the example)
I've put this URL (with the correct client and signature) in a web browser or a SAP html viewer it works fine and returns the required geocode.
However, If I run it as a HTTP client call in a program it fails as google doesn't understand the client/signature pairing. The signature is getting changed somewhere in the call.
My code is
* Creation of new IF_HTTP_Client object
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = l_http_url
IMPORTING
client = l_http_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4.
* Check this was successful
CHECK : sy-subrc IS INITIAL.
* Set the request method
l_http_client->request->set_header_field( name = '~request_method'
value = 'GET' ).
* Set the header
l_http_client->request->set_header_field( name = 'Content-Type'
value = 'text/xml; charset=utf-8' ).
* Send the request
l_http_client->send( ).
* Reterive the result
CALL METHOD l_http_client->receive
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 4.
content = l_http_client->response->get_cdata( ).
I've tried turing of encoding and compression, passing the parameters individually into the object but nothing works.
However, if I try the public geocode URL ( http://maps.google.com/maps/api/geocode/xml?address=1,STREET,CITY,POSTCODE,&sensor=false) it works fine.
Any ideas how to use the URL with the signature?
09-01-2011 7:27 PM
03-27-2013 9:42 AM
Hi Ewald,
I've got the same probleme here like Mr.MacDonald had. We're on NetWeaver 7.0 SPS 26 and I generate the signature properly (the URL works in the browser), but unfortunately the problem is, that somewhere in the cl_http_client the URL is changed or modified during the request.
The error message we receive from Google is "Unable to authenticate the supplied URL. Please check your client and signature parameters." (HTTP 403).
Do you have a solution for this problem?
Kind regards
Hendrik Behrens
(P.S.: Sorry for digging out this old thread)
03-27-2013 4:00 PM
Use Wireshark or similar on the AS ABAP server to find out what actual URL is being accessed. If the signature in fact gets altered it is a program error in the system.
03-27-2013 7:05 PM
How are you constructing the URL, especially it's parameters? Are you using methods FIELDS_TO_STRING and SET_QUERY of ABAP class CL_HTTP_UTILITY?
04-30-2013 12:07 PM
Hi Hendrik,
Please find my reply to James question.
Best regards,
Binil
04-30-2013 12:06 PM
Hi James,
Please URL encode the address part of your URL. In your browser this is automatically done. But in SAP http client you have to expcitly do it.
You can use the static method ESCAPE_URL of class CL_HTTP_UTILITY for the same.
Careful: Only the address part!! Passing the entire URL will not work.
After that sign the URL with kryptokey and call HTTP client.
Check whether this works!!
Best regards,
Binil
12-24-2013 6:58 PM
Hi
we have successfully interfaced from SAP ABAP to the Google API's using OAuth2 tokens. Here's a short 8 minute high level video of our project.
Note also the source ABAP code is out on Github.
04-09-2014 9:15 PM
James I am facing this EXACT same situation. Cuuld you kindly share your solution it would be GREATLY appreciated !
04-10-2014 10:43 AM
This is an example that works like our current solution:
DATA: lr_conv TYPE REF TO cl_abap_conv_in_ce,
plaintext TYPE string.
DATA: lv_sign_key_x TYPE xstring,
lv_sign_key TYPE string,
lv_hmac_result TYPE string,
lv_sign_string TYPE string.
TYPE-POOLS: abap.
lv_sign_string = url.
lv_sign_key = 'your_sign_key'.
* String to SafeBase64
REPLACE ALL OCCURRENCES OF '_' IN lv_sign_key WITH '/'.
REPLACE ALL OCCURRENCES OF '-' IN lv_sign_key WITH '+'.
* Do not sign the protocol/domain
REPLACE 'http://maps.googleapis.com' IN lv_sign_string WITH ''.
*Convert key from String to xString (hex)
CALL FUNCTION 'SSFC_BASE64_DECODE'
EXPORTING
b64data = lv_sign_key
IMPORTING
bindata = lv_sign_key_x.
* Generate signature
cl_abap_hmac=>calculate_hmac_for_char(
EXPORTING
if_algorithm = 'SHA1'
if_key = lv_sign_key_x
if_data = lv_sign_string
IMPORTING
ef_hmacb64string = lv_hmac_result
).
* SafeBase64 -> Base64 again
REPLACE ALL OCCURRENCES OF '/' IN lv_hmac_result WITH '_'.
REPLACE ALL OCCURRENCES OF '+' IN lv_hmac_result WITH '-'.
* Concatenate final URL
CONCATENATE url '&signature=' lv_hmac_result INTO url.
Best regards,
Hendrik Behrens
04-17-2014 5:14 PM
I wanted to let you all know we had this EXACT same problem and we solved it so we would like to share with you all !!
Our solution was to remove the Client and Signature from the URL and use the following code/methods to set the Client and Signature:
http_client->request->set_header_field(
name = 'client'
value = L_GOOGLE_CLIENT_ID
).
http_client->request->set_header_field(
name = 'signature'
value = L_GOOGLE_SIGNATURE
).
This works for us!! No more 403 error !!
11-18-2014 9:24 AM
Hello Christopher,
Thank you for sharing your solution!
I have the same problem: The URL is working in a web browser but in ABAP I always get this error:
"Unable to authenticate the request. Provided 'signature' is not valid for the provided client ID, or the provided 'client' is not valid..."
I tried your solution (with set_header_field) and it worked. After that I debugged my program and changed the signature to "test" to have a look if I will get the error message from google. So I would be sure that the client and signature is passed correct. Unfortunately I don't get the error message instead I get the correct Geolocation.
If you call the webservice without the parameters client and signature you always get correct response messages. So I guess the http_client doesn't pass the "set_header_field" parameters correct to google. I also added the address parameter as a "set_header_field" and got a "ZERO_RESULTS" back.
I think your solution is working, but it doesn't send the client ID and signature to google...
Maybe someoneelse has any solution or experiance with that who wants to share this with us?
Best Regards
Markus