http-sendrecv with Google geocode

77 views
Skip to first unread message

George Neuner

unread,
Apr 20, 2015, 8:39:30 PM4/20/15
to racket users
Hi all,

I'm having trouble accessing the Google geocode API using http-sendrecv.

Code is:

(define (lookup address) 
  (let [
        (form-data  (alist->form-urlencoded
                     (list (cons 'address address)
                           )))
        
        (response #f)
        (lat  #f)
        (long #f)
       ]
   
    (printf "Looking up ~s~n" address)
    (printf "=> ~s~n" form-data)
   
    (with-handlers [
                    (exn:fail?
                     (lambda (e)
                       (fprintf (ferr) "~n~n%%~n~a~n%%~n" (format "Error: ~a" (exn-message e)))
                       ))
                   ]
      (let-values [
                   ((errcode header port)
                    (http-sendrecv "maps.googleapis.com"
                                   "http://maps.googleapis.com/maps/api/geocode/json"
                                   ;#:ssl? ssl?     
                                   ;#:port port     
                                   #:version #"1.1"     
                                   #:method  #"GET"     
                                   #:headers (list "Content-Type: application/x-www-form-urlencoded")     
                                   #:data form-data
                                   ;#:content-decode decodes
                                   ))
                  ]
        (set! response (port->string port))
        ;(set! response (read-json port))
        (printf "=> ~s~n" response)
        ))
     
    (fprintf (ferr) "lat:~s long:~s~n"  lat long )
    (values lat long)
    ))

It doesn't yet extract relevant data because I haven't yet successfully gotten any data8-(


As a test I lookup the State House in Boston:

   (lookup "24 Beacon St, Boston, MA, 01233")

Looking up "24 Beacon St, Boston, MA, 01233"
=> "address=24+Beacon+St%2C+Boston%2C+MA%2C+01233"
=> "<!DOCTYPE html>\n<html lang=en>\n  <meta charset=utf-8>\n  <meta name=viewport content=\"initial-scale=1, minimum-scale=1, width=device-width\">\n  <title>Error 400 (Bad Request)!!1</title>\n  <style>\n    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/errors/logo_sm_2.png) no-repeat}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/errors/logo_sm_2_hr.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/errors/logo_sm_2_hr.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/errors/logo_sm_2_hr.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:55px;width:150px}\n  </style>\n  <a href=//www.google.com/><span id=logo aria-label=Google></span></a>\n  <p><b>400.</b> <ins>That’s an error.</ins>\n  <p>Your client has issued a malformed or illegal request.  <ins>That’s all we know.</ins>\n"
lat:#f long:#f
#f
#f

Totally unhelpful.
However if I paste the URI and urlencoded data into a browser:

    http://maps.googleapis.com/maps/api/geocode/json?address=24+Beacon+St%2C+Boston%2C+MA%2C+01233

then I get a good return.  It also works from an HTML form, e.g.,

      <form action="http://maps.googleapis.com/maps/api/geocode/json" method="GET">
         <label>address</label>
         <input type="text" name="address" size="128" />
         <button type="submit" >
             GEOCODE
             </button>
         </form> <!-- login -->


I'm using http-sendrecv successfully with other web APIs - I just can't figure out what I'm doing wrong with Google.  Number and/or frequency of requests is not an issue - I'm very far from the daily limit and many minutes elapse between tests as I'm trying to figure out what's wrong.

The documentation is at   https://developers.google.com/maps/documentation/geocoding/#GeocodingRequests

Any clues to pierce the veil of stupidity would be appreciated.
Thanks,
George

Sean Kanaley

unread,
Apr 21, 2015, 1:46:45 AM4/21/15
to George Neuner, racket users
Just comment out #:data and append it to the url:

 (http-sendrecv "maps.googleapis.com"

                                   (string-append "http://maps.googleapis.com/maps/api/geocode/json?" form-data)
                                   ;#:ssl? ssl?     
                                   ;#:port port     
                                   #:version #"1.1"     
                                   #:method  #"GET"     
                                   #:headers (list "Content-Type: application/x-www-form-urlencoded")     
                                   ;#:data form-data
                                   ;#:content-decode decodes
                                   ))

--
You received this message because you are subscribed to the Google Groups "Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

George Neuner

unread,
Apr 21, 2015, 2:25:31 AM4/21/15
to Sean Kanaley, racket users
Hi Sean,


On 4/21/2015 1:46 AM, Sean Kanaley wrote:
Just comment out #:data and append it to the url:

 (http-sendrecv "maps.googleapis.com"

                                   (string-append "http://maps.googleapis.com/maps/api/geocode/json?" form-data)
                                   ;#:ssl? ssl?     
                                   ;#:port port     
                                   #:version #"1.1"     
                                   #:method  #"GET"     
                                   #:headers (list "Content-Type: application/x-www-form-urlencoded")     
                                   ;#:data form-data
                                   ;#:content-decode decodes
                                   ))


Doesn't work - I get the same error back:
  blah, blah ... Your client has issued a malformed or illegal request. That’s all we know ...

I've tried appending the data as you suggest.  I've tried adding "?" deliberately to the URI.  I've tried with and without #:headers.  #:version #"1.0" and #"1.1".  #:method #"GET" vs #"POST".  Everything produces the same error.

But perversely the result of (string-append "http://maps.googleapis.com/maps/api/geocode/json?" form-data) works if I paste it into a browser.

George

Sean Kanaley

unread,
Apr 21, 2015, 3:39:24 AM4/21/15
to George Neuner, racket users
Hi George,

I'm not sure then -- I am in Racket 6.1.1. Here is the source that worked for me:

#lang racket
(require net/http-client
         net/uri-codec)

(define (lookup address)  
  (let [
        (form-data  (alist->form-urlencoded
                     (list (cons 'address address)
                           )))
         
        (response #f)
        (lat  #f)
        (long #f)
       ]
    
    (printf "Looking up ~s~n" address)
    (printf "=> ~s~n" form-data)
    
    (with-handlers [
                    (exn:fail?
                     (lambda (e)
                      3; (fprintf (ferr) "~n~n%%~n~a~n%%~n" (format "Error: ~a" (exn-message e)))
                       ))
                   ]
      (let-values [
                   ((errcode header port)
                    (http-sendrecv "maps.googleapis.com"
                                   (string-append "http://maps.googleapis.com/maps/api/geocode/json?" form-data)
                                   ;#:ssl? ssl?     
                                   ;#:port port     
                                   #:version #"1.1"     
                                   #:method  #"GET"     
                                   #:headers (list "Content-Type: application/x-www-form-urlencoded")     
                                   ;#:data form-data
                                   ;#:content-decode decodes
                                   ))
                  ]
        (set! response (port->string port))
        ;(set! response (read-json port))
        (printf "=> ~s~n" response)
        ))
      
    ;(fprintf (ferr) "lat:~s long:~s~n"  lat long )
    (values lat long)
    ))

----------------------------------------------------------------------------

(I commented out the fprintfs to avoid dealing with ferr.)

It won't work if #:data is uncommented. I hope that helps, otherwise I'm stuck too.

George Neuner

unread,
Apr 21, 2015, 10:32:28 AM4/21/15
to Sean Kanaley, racket users
Hi Sean,

Even weirder .... when I tried this morning your string-append solution - which I had left in place - worked immediately with no changes from last night.  The only thing different is I had closed DrRacket before going to bed and reopened it this morning.  Maybe something was wonky in DrRacket?  It had been running about ~14 hours yesterday at the point I started having trouble and I fought with it a couple more hours before quitting?  But AFAICR, I've never seen that before.

However, as you discovered also, passing the data as #:data doesn't work and now I'm interested in why.  ISTM that the URI + #:data should be identical to the string-append with "?" and #:method #"GET".

Also, Google recommends using POST if the data is sensitive, but I can't get POST to work even from a pure HTML form in a browser.

So now I'm really curious as to what's going on.

Thanks for your help,
George
Reply all
Reply to author
Forward
0 new messages