Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

HTTP Call to Google Geocode

Former Member
0 Kudos

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?

11 REPLIES 11

Former Member
0 Kudos

(a little bit late I know) but I think this is what you are searching for:

0 Kudos

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)

0 Kudos

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.

0 Kudos

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?

0 Kudos

Hi Hendrik,

Please find my reply to James question.

Best regards,

Binil

Former Member
0 Kudos

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

Former Member
0 Kudos

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.

http://youtu.be/uDgTxiR00cY

Note also the source ABAP code is out on Github.

0 Kudos

James I am facing this EXACT same situation. Cuuld you kindly share your solution it would be GREATLY appreciated !

0 Kudos

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

0 Kudos

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 !!

0 Kudos

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