Skip to content

Commit 3f79829

Browse files
committed
Initial commit
0 parents  commit 3f79829

File tree

7 files changed

+352
-0
lines changed

7 files changed

+352
-0
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/bower_components/
2+
/node_modules/
3+
/output/
4+
/.psci*
5+
/src/.webpack.js

LICENSE

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 DICOM Grid, Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy of
6+
this software and associated documentation files (the "Software"), to deal in
7+
the Software without restriction, including without limitation the rights to
8+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9+
the Software, and to permit persons to whom the Software is furnished to do so,
10+
subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

bower.json

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "purescript-node-http",
3+
"version": "1.0.0",
4+
"moduleType": [
5+
"node"
6+
],
7+
"ignore": [
8+
"**/.*",
9+
"node_modules",
10+
"bower_components",
11+
"output"
12+
],
13+
"devDependencies": {
14+
"purescript-console": "^0.1.0"
15+
},
16+
"dependencies": {
17+
"purescript-maps": "~0.5.0",
18+
"purescript-node-streams": "~0.1.0",
19+
"purescript-unsafe-coerce": "~0.1.0"
20+
}
21+
}

docs/Node/HTTP.md

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
## Module Node.HTTP
2+
3+
This module defines low-level bindings to the Node HTTP module.
4+
5+
#### `Server`
6+
7+
``` purescript
8+
data Server :: *
9+
```
10+
11+
The type of a HTTP server object
12+
13+
#### `Request`
14+
15+
``` purescript
16+
data Request :: *
17+
```
18+
19+
A HTTP request object
20+
21+
#### `Response`
22+
23+
``` purescript
24+
data Response :: *
25+
```
26+
27+
A HTTP response object
28+
29+
#### `HTTP`
30+
31+
``` purescript
32+
data HTTP :: !
33+
```
34+
35+
The effect associated with using the HTTP module.
36+
37+
#### `createServer`
38+
39+
``` purescript
40+
createServer :: forall eff. (Request -> Response -> Eff (http :: HTTP | eff) Unit) -> Eff (http :: HTTP | eff) Server
41+
```
42+
43+
Create a HTTP server, given a function to be executed when a request is received.
44+
45+
#### `listen`
46+
47+
``` purescript
48+
listen :: forall eff. Server -> Int -> Eff (http :: HTTP | eff) Unit -> Eff (http :: HTTP | eff) Unit
49+
```
50+
51+
Listen on the specified port. The specified callback will be run when setup is complete.
52+
53+
#### `httpVersion`
54+
55+
``` purescript
56+
httpVersion :: Request -> String
57+
```
58+
59+
Get the request HTTP version
60+
61+
#### `requestHeaders`
62+
63+
``` purescript
64+
requestHeaders :: Request -> StrMap String
65+
```
66+
67+
Get the request headers as a hash
68+
69+
#### `requestMethod`
70+
71+
``` purescript
72+
requestMethod :: Request -> String
73+
```
74+
75+
Get the request method (GET, POST, etc.)
76+
77+
#### `requestURL`
78+
79+
``` purescript
80+
requestURL :: Request -> String
81+
```
82+
83+
Get the request URL
84+
85+
#### `requestAsStream`
86+
87+
``` purescript
88+
requestAsStream :: forall eff a. Request -> Readable () (http :: HTTP | eff) a
89+
```
90+
91+
Coerce the request object into a readable stream.
92+
93+
#### `setHeader`
94+
95+
``` purescript
96+
setHeader :: forall eff. Response -> String -> String -> Eff (http :: HTTP | eff) Unit
97+
```
98+
99+
Set a header with a single value.
100+
101+
#### `setHeaders`
102+
103+
``` purescript
104+
setHeaders :: forall eff. Response -> String -> Array String -> Eff (http :: HTTP | eff) Unit
105+
```
106+
107+
Set a header with multiple values.
108+
109+
#### `setStatusCode`
110+
111+
``` purescript
112+
setStatusCode :: forall eff. Response -> Int -> Eff (http :: HTTP | eff) Unit
113+
```
114+
115+
Set the status code.
116+
117+
#### `setStatusMessage`
118+
119+
``` purescript
120+
setStatusMessage :: forall eff. Response -> String -> Eff (http :: HTTP | eff) Unit
121+
```
122+
123+
Set the status message.
124+
125+
#### `responseAsStream`
126+
127+
``` purescript
128+
responseAsStream :: forall eff a. Response -> Writable () (http :: HTTP | eff) a
129+
```
130+
131+
Coerce the response object into a writable stream.
132+
133+

src/Node/HTTP.js

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
"use strict";
2+
3+
// module Node.HTTP
4+
5+
var http = require('http');
6+
7+
exports.createServer = function(handleRequest) {
8+
return function() {
9+
return http.createServer(function(req, res) {
10+
handleRequest(req)(res)();
11+
});
12+
};
13+
};
14+
15+
exports.listen = function(server) {
16+
return function(port) {
17+
return function(done) {
18+
return function() {
19+
server.listen(port, function() {
20+
done();
21+
});
22+
};
23+
};
24+
};
25+
};
26+
27+
exports.writeString = function(res) {
28+
return function(s) {
29+
return function() {
30+
res.write(s);
31+
};
32+
};
33+
};
34+
35+
exports.setHeader = function(res) {
36+
return function(key) {
37+
return function(value) {
38+
return function() {
39+
res.setHeader(key, value);
40+
};
41+
};
42+
};
43+
};
44+
45+
exports.setHeaders = function(res) {
46+
return function(key) {
47+
return function(values) {
48+
return function() {
49+
res.setHeader(key, values);
50+
};
51+
};
52+
};
53+
};
54+
55+
exports.setStatusCode = function(res) {
56+
return function(code) {
57+
return function() {
58+
res.statusCode = code;
59+
};
60+
};
61+
};
62+
63+
exports.setStatusMessage = function(res) {
64+
return function(message) {
65+
return function() {
66+
res.statusMessage = message;
67+
};
68+
};
69+
};
70+
71+
exports.end = function(res) {
72+
return function(done) {
73+
return function() {
74+
res.end(null, function() {
75+
done();
76+
});
77+
};
78+
};
79+
};

src/Node/HTTP.purs

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
-- | This module defines low-level bindings to the Node HTTP module.
2+
3+
module Node.HTTP where
4+
5+
import Prelude
6+
7+
import Data.StrMap
8+
import Control.Monad.Eff
9+
import Node.Stream
10+
import Unsafe.Coerce (unsafeCoerce)
11+
12+
-- | The type of a HTTP server object
13+
foreign import data Server :: *
14+
15+
-- | A HTTP request object
16+
foreign import data Request :: *
17+
18+
-- | A HTTP response object
19+
foreign import data Response :: *
20+
21+
-- | The effect associated with using the HTTP module.
22+
foreign import data HTTP :: !
23+
24+
-- | Create a HTTP server, given a function to be executed when a request is received.
25+
foreign import createServer :: forall eff. (Request -> Response -> Eff (http :: HTTP | eff) Unit) -> Eff (http :: HTTP | eff) Server
26+
27+
-- | Listen on the specified port. The specified callback will be run when setup is complete.
28+
foreign import listen :: forall eff. Server -> Int -> Eff (http :: HTTP | eff) Unit -> Eff (http :: HTTP | eff) Unit
29+
30+
-- | Get the request HTTP version
31+
httpVersion :: Request -> String
32+
httpVersion = _.httpVersion <<< unsafeCoerce
33+
34+
-- | Get the request headers as a hash
35+
requestHeaders :: Request -> StrMap String
36+
requestHeaders = _.headers <<< unsafeCoerce
37+
38+
-- | Get the request method (GET, POST, etc.)
39+
requestMethod :: Request -> String
40+
requestMethod = _.method <<< unsafeCoerce
41+
42+
-- | Get the request URL
43+
requestURL :: Request -> String
44+
requestURL = _.url <<< unsafeCoerce
45+
46+
-- | Coerce the request object into a readable stream.
47+
requestAsStream :: forall eff a. Request -> Readable () (http :: HTTP | eff) a
48+
requestAsStream = unsafeCoerce
49+
50+
-- | Set a header with a single value.
51+
foreign import setHeader :: forall eff. Response -> String -> String -> Eff (http :: HTTP | eff) Unit
52+
53+
-- | Set a header with multiple values.
54+
foreign import setHeaders :: forall eff. Response -> String -> Array String -> Eff (http :: HTTP | eff) Unit
55+
56+
-- | Set the status code.
57+
foreign import setStatusCode :: forall eff. Response -> Int -> Eff (http :: HTTP | eff) Unit
58+
59+
-- | Set the status message.
60+
foreign import setStatusMessage :: forall eff. Response -> String -> Eff (http :: HTTP | eff) Unit
61+
62+
-- | Coerce the response object into a writable stream.
63+
responseAsStream :: forall eff a. Response -> Writable () (http :: HTTP | eff) a
64+
responseAsStream = unsafeCoerce

test/Main.purs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module Test.Main where
2+
3+
import Prelude
4+
5+
import Control.Monad.Eff.Console
6+
7+
import Node.HTTP
8+
import Node.Stream
9+
import Node.Encoding
10+
11+
main = do
12+
server <- createServer respond
13+
listen server 8080 do
14+
log "Listening on port 8080."
15+
where
16+
respond req res = do
17+
setStatusCode res 200
18+
let inputStream = requestAsStream req
19+
outputStream = responseAsStream res
20+
log (requestMethod req <> " " <> requestURL req)
21+
case requestMethod req of
22+
"GET" -> do
23+
let html = "<form method='POST' action='/'>"
24+
<> " <input name='text' type='text'>"
25+
<> " <input type='submit'>"
26+
<> "</form>"
27+
setHeader res "Content-Type" "text/html"
28+
writeString outputStream UTF8 html(return unit)
29+
end outputStream (return unit)
30+
"POST" -> void $ pipe inputStream outputStream

0 commit comments

Comments
 (0)