comparison modules/http.tp @ 157:55e0dca7d3d7

Partial implementation of HTTP get requests
author Mike Pavone <pavone@retrodev.com>
date Sat, 10 Aug 2013 15:06:56 -0700
parents 075b1e71feff
children d81de309a51f
comparison
equal deleted inserted replaced
156:d6e79885bd3b 157:55e0dca7d3d7
1 #{ 1 {
2 client:usingPort <- :address :port{ 2 response <- :_headers _status _sock _data {
3 _open? <- true
4 _body <- ""
5 _length <- int32: (_headers get: "Content-Length" withDefault: "-1")
6 _chunked? <- (_headers get: "Transfer-Encoding" withDefault: "") = "chunked"
7 _code <- int32: _status
3 #{ 8 #{
4 get <- :path { 9 headers <- { _headers }
5 sock <- socket connectTo: address onPort: port 10 status <- { _status }
6 sock send: "GET " . path . " HTTP/1.1\r\nHost: " . address . "\r\n\r\n" 11 statusCode <- { _code }
7 resp <- "" 12 body <- {
8 waiting <- true 13 if: _open? {
9 headerText <- "" 14 if: _chunked? {
10 rest <- "" 15
11 while: { waiting } do: { 16 } else: {
12 data <- sock recv 4096 17 if: _length >= 0 {
13 resp <- resp . data 18 _body <- _data . (_sock recvAll: (_length - (_data byte_length)))
14 pos <- resp find: "\r\n\r\n" else: { -1 } 19 } else: {
15 if: pos >= 0 { 20 chunk <- ""
16 waiting <- false 21 while: {
17 headerText <- resp from: 0 withLength: pos 22 chunk <- _sock recv: 4096
18 rest <- resp from: pos + 4 23 (chunk length) > 0
24 } do: {
25 _data <- _data . chunk
26 }
27 _body <- _data
28 }
19 } 29 }
30 _data <- ""
31 close
20 } 32 }
21 print: "Headers:\n" . headerText . "\n" 33 _body
22 print: "Rest:\n" . rest . "\n" 34 }
23 _headers <- (headerText split: "\r\n") fold: (dict linear) with: :acc curLine{ 35 close <- {
24 //TODO: support multiple headers with the same name 36 if: _open? {
25 part <- curLine partitionOn: ":" 37 _sock close
26 acc set: (part before) (trim: (part after)) 38 _open? <- false
27 } 39 }
28 _closed <- false
29 #{
30
31 }
32 sock close
33 rest
34 } 40 }
35 } 41 }
36 } 42 }
43 #{
44 client:usingPort <- :address :port{
45 #{
46 get <- :path {
47 sock <- socket connectTo: address onPort: port
48 sock send: "GET " . path . " HTTP/1.1\r\nHost: " . address . "\r\n\r\n"
49 resp <- ""
50 waiting <- true
51 headerText <- ""
52 rest <- ""
53 status <- ""
54 while: { waiting } do: {
55 data <- sock recv 4096
56 resp <- resp . data
57 pos <- resp find: "\r\n\r\n" else: { -1 }
58 if: pos >= 0 {
59 waiting <- false
60 statusEnd <- resp find: "\r\n" else: { 0 }
61 statusStart <- (resp find: " " else: { 0 }) + 1
62 status <- resp from: statusStart withLength: (statusEnd - statusStart)
63 headerText <- resp from: statusEnd + 2 withLength: pos - (statusEnd + 2)
64 rest <- resp from: pos + 4
65 }
66 }
67 headers <- (headerText splitOn: "\r\n") fold: (dict linear) with: :acc curLine{
68 //TODO: support multiple headers with the same name
69 part <- curLine partitionOn: ":"
70 acc set: (trim: (part before)) (trim: (part after))
71 }
37 72
38 client <- :address { 73
39 client: address usingPort: 80 74 response: headers status sock rest
75 }
76 }
77 }
78
79 client <- :address {
80 client: address usingPort: 80
81 }
40 } 82 }
41 } 83 }