[racket] HTTP POST: curl vs racket net library

From: David Vanderson (david.vanderson at gmail.com)
Date: Mon Nov 3 22:15:54 EST 2014

A tiny addition - if you know that the base64 encoding will be less than 
one line, you can use the optional second argument to 'base64-encode':

(define (authcode key)
   (base64-encode (string->bytes/utf-8 key) #""))

Thanks,
Dave

On 11/03/2014 07:19 PM, Jay McCarthy wrote:
> It did not work because
>
> (authcode "sk_test_BQokikJOvBiI2HlWgH4olfQ2:")
>
> is
>
> #"c2tfdGVzdF9CUW9raWtKT3ZCaUkySGxXZ0g0b2xmUTI6\r\n"
>
> which contains "\r\n" which are illegal characters in an HTTP header,
> so your HTTP request was messed up. Specifically, it ended in
> "\r\n\r\n\r\n". The first "\r\n" ended the last header. The second
> "\r\n" ended the HTTP header segment. And the third "\r\n" was
> correctly parsed as POST data on the server side.
>
> You really want something like this:
>
> (define (subbytes* b st en)
>    (subbytes b st (+ (bytes-length b) en)))
> (subbytes* (authcode "sk_test_BQokikJOvBiI2HlWgH4olfQ2:") 0 -2)
>
> As far as a less verbose way to do it, the Racket code has exactly one
> expression for each argument to CURL. I think the only thing I would
> do differently is turn this into a function that I call with various
> arguments for each of the stripe API URLs.
>
> Jay
>
> On Mon, Nov 3, 2014 at 12:31 PM, pior neer <pior.neer at gmail.com> wrote:
>> Here is an example (which worked once) I am trying to replicate in Racket.
>>
>> curl https://api.stripe.com/v1/customers \
>>     -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
>>     -d "description=Customer for test at example.com" \
>>     -d card=tok_14unJi2eZvKYlo2C804uRph5
>>
>> Here is my Racket code that does a "similar" thing.
>>
>> #lang racket
>>
>> (require net/http-client)
>> (require net/url)
>> (require net/uri-codec)
>> (require net/base64)
>> (require json)
>>
>> (define (authcode key)
>>    (base64-encode (string->bytes/utf-8 key)))
>>
>> (define (make-customer #:email email #:token token)
>>
>>    (define-values (status-code header inport)
>>      (http-sendrecv
>>       "api.stripe.com"
>>       "/v1/customers"
>>       #:ssl? #t
>>       #:method "POST"
>>       #:data (alist->form-urlencoded
>>               (list (cons 'card "token")))
>>       #:headers (list (format "Authorization: Basic ~a"
>>                               (authcode
>> "sk_test_BQokikJOvBiI2HlWgH4olfQ2:")))))
>>    (read-json inport))
>>
>> (make-customer #:email "jondo at example.com"
>>                 #:token "tok_14unJi2eZvKYlo2C804uRph5" )
>>
>> The above results in
>>
>> '#hasheq((error
>>            .
>>            #hasheq((param . "\r\ncard")
>>                    (message
>>                     .
>>                     "Received unknown parameter: \r\ncard")
>>                    (type . "invalid_request_error"))))
>>
>> Questions:
>>
>> 1) Why does the server parses \r\nkey instead of just key when using Racket?
>>
>> 2) Is there a less verbose way to express the same thing?
>>
>>
>>
>> ____________________
>>    Racket Users list:
>>    http://lists.racket-lang.org/users
>>
>
>


Posted on the users mailing list.