Mercurial > repos > tabletprog
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 } |