[racket] HTTP request problem

260 views
Skip to first unread message

Mikko Tiihonen

unread,
Oct 5, 2012, 3:49:52 AM10/5/12
to us...@racket-lang.org
Hi all!

I'm trying to write a simple HTTP client, but I haven't been able to figure out why I get a "malformed request" exception from the server. I have tried to modify the request and verified that it conforms to the web-server/http request-struct. Server throws this exception after having processed the request and having sent the response:

../../../../../Applications/Racket v5.3/collects/web-server/private/util.rkt:34:0: read-request: malformed request (request #"GET" #<url> (list (header #"Host" #"localhost:8080") (header #"Connection" #"keep-alive") (header #"User-Agent" #"Mozilla/5.0 (testClient.rkt 0.1)") (header #"Accept-Encoding" #"gzip") (header #"Accept" #"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") (header #"Accept-Language" #"en-us") (header #"Accept-Charset" #"ISO-8859-1,UTF-8;q=0.7,*;q=0.7") (header #"Cache-control" #"no-cache")) #<promise:...cheme/testClient.rkt:34:17> #"" "127.0.0.1" 8080 "127.0.0.1")

The code is at the end of this message. Could you, please, give me a pointer in the right direction? Thanks for your help!

Regards,

Mikko Tiihonen


The client code is here:

#lang racket

(require web-server/http net/url)

(define (display-request req)
(display (format "~s\n~s\n" (request-method req) (request-uri req)))
(for ((r (request-headers/raw req)))
(displayln r))
(for ((b (request-bindings/raw req)))
(displayln b))
(display (format "~s\n" (request-post-data/raw req))))

(define (connect host port)
(define main-cust (make-custodian))
(parameterize ((current-custodian main-cust))
(define-values (in out)(tcp-connect host port))
(define-values (ip-in port-in ip-out port-out) (tcp-addresses in #t))
(define method #"GET")
(define uri (string->url "http://localhost:8080/resources/data"))
(define headers (list (make-header #"Host" #"localhost:8080")
(make-header #"Connection" #"keep-alive")
(make-header #"User-Agent" #"Mozilla/5.0 (testClient.rkt 0.1)")
(make-header #"Accept-Encoding" #"gzip")
(make-header #"Accept" #"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
(make-header #"Accept-Language" #"en-us")
(make-header #"Accept-Charset" #"ISO-8859-1,UTF-8;q=0.7,*;q=0.7")
(make-header #"Cache-control" #"no-cache")
))

(define req (make-request
method
uri
headers
(delay empty)
#""
"127.0.0.1"
8080
"127.0.0.1"))
(display (format "Client: ~a:~s\nServer: ~a:~s\n" ip-in port-in ip-out port-out))
(print req out)
(for ([i (in-range 10000000)])
i)
(display (format "Response:\n~s" (port->string (get-impure-port (string->url "http://localhost:8080")))))
(close-input-port in)
(close-output-port out)
(custodian-shutdown-all main-cust)))

(connect "127.0.0.1" 8080)

And the server:

#lang web-server

(require web-server/servlet-env)

(provide interface-version stuffer start)
(define interface-version 'stateless)

(define (display-request req)
(display (format "Method: ~s\nURL: ~s\n" (request-method req) (url->string (request-uri req))))
(displayln "Headers:\n")
(for ((r (request-headers/raw req)))
(displayln r))
(displayln "Bindings:\n")
(for ((b (request-bindings/raw req)))
(displayln (format "Bindings: ~s\n" b)))
(display (format "POST-data:\n~s\n" (request-post-data/raw req))))

(define stuffer
(stuffer-chain
serialize-stuffer
(md5-stuffer (build-path (find-system-path 'home-dir) ".urls"))))

(define (start req)
; handle request
(fprintf (current-output-port) "\n\n**** new request ****\n~s" req)
(display "\n---\n\n")
(display-request req)
(display "**** sending response ...")
; send response
(begin0
(response/xexpr
`(html (body (h2 "Servlet response..."))))
(displayln "sent! ****\n")))

(serve/servlet start
#:stateless? #t
#:servlet-regexp #rx""
#:port 8080)




____________________
Racket Users list:
http://lists.racket-lang.org/users

Danny Yoo

unread,
Oct 5, 2012, 10:47:47 AM10/5/12
to Mikko Tiihonen, us...@racket-lang.org
> I'm trying to write a simple HTTP client, but I haven't been able to figure out why I get a "malformed request" exception from the server. I have tried to modify the request and verified that it conforms to the web-server/http request-struct. Server throws this exception after having processed the request and having sent the response:


On the client side of things, can you use the functions provided in net/url?

http://docs.racket-lang.org/net/url.html

get-pure-port and post-pure-port, in particular, may be applicable here.




The request structure that you were working with in the client code
is, to my knowledge, intended for use by the server side, not the
client side. Printing it to the port doesn't write it in the format
expected by the HTTP protocol.

Mikko Tiihonen

unread,
Oct 5, 2012, 11:06:16 AM10/5/12
to Danny Yoo, us...@racket-lang.org
Thanks, Danny - I will look closer into that!

Cheers,
-Mikko

Danny Yoo

unread,
Oct 5, 2012, 11:44:03 AM10/5/12
to Mikko Tiihonen, us...@racket-lang.org
On Fri, Oct 5, 2012 at 9:06 AM, Mikko Tiihonen
<mikko.t...@tmtiihonen.fi> wrote:
> Thanks, Danny - I will look closer into that!

No problem! Here's a small example of grabbing content from a certain web site:


#lang racket

(require net/url)
(define web-page-content
(port->string
(get-pure-port (string->url "http://racket-lang.org/"))))

Mikko Tiihonen

unread,
Oct 6, 2012, 2:23:21 AM10/6/12
to Danny Yoo, us...@racket-lang.org
Thank you, Danny, with net/url and net/head utilities the client works like a charm!

Have a nice weekend!

Cheers,
-MIkko
Reply all
Reply to author
Forward
0 new messages