Skip to content
This repository was archived by the owner on Jul 30, 2024. It is now read-only.

Commit e58ef62

Browse files
author
exoego
committed
Overhaul http and https module
This also requires some changes in tls module
1 parent c952308 commit e58ef62

34 files changed

+532
-489
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ The following core Node.js modules (v8.7.0+) have been implemented:
3030
| [dns](https://nodejs.org/api/dns.html) | :heavy_check_mark: |
3131
| [events](https://nodejs.org/api/events.html) | :heavy_check_mark: |
3232
| [fs](https://nodejs.org/api/fs.html) | :heavy_check_mark: |
33-
| [http](https://nodejs.org/api/http.html) | |
33+
| [http](https://nodejs.org/api/http.html) | :heavy_check_mark: |
3434
| [http2](https://nodejs.org/api/http2.html) | |
35-
| [https](https://nodejs.org/api/https.html) | |
35+
| [https](https://nodejs.org/api/https.html) | :heavy_check_mark: |
3636
| [net](https://nodejs.org/api/net.html) | |
3737
| [os](https://nodejs.org/api/os.html) | :heavy_check_mark: |
3838
| [path](https://nodejs.org/api/path.html) | :heavy_check_mark: |

app/current/src/main/scala/io/scalajs/nodejs/http/Agent.scala

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import io.scalajs.util.PromiseHelper._
55

66
import scala.concurrent.Future
77
import scala.scalajs.js
8+
import scala.scalajs.js.annotation.JSImport
89

910
/**
1011
* The HTTP Agent is used for pooling sockets used in HTTP client requests.
@@ -14,7 +15,8 @@ import scala.scalajs.js
1415
* require developers to manually close the HTTP clients using KeepAlive.
1516
*/
1617
@js.native
17-
trait Agent extends js.Object {
18+
@JSImport("http", "Agent")
19+
class Agent(options: AgentOptions = js.native) extends js.Object {
1820

1921
/////////////////////////////////////////////////////////////////////////////////
2022
// Properties
@@ -56,7 +58,7 @@ trait Agent extends js.Object {
5658
* @example agent.sockets
5759
*/
5860
// TODO what is the underlying object?
59-
def sockets: js.Array[js.Any] = js.native
61+
def sockets: js.Object = js.native
6062

6163
/////////////////////////////////////////////////////////////////////////////////
6264
// Methods
@@ -75,6 +77,10 @@ trait Agent extends js.Object {
7577
*/
7678
def createConnection(options: ConnectionOptions, callback: js.Function): Unit = js.native
7779

80+
def keepSocketAlive(socket: net.Socket): Unit = js.native
81+
82+
def reuseSocket(socket: net.Socket, request: ClientRequest): Unit = js.native
83+
7884
/**
7985
* Destroy any sockets that are currently in use by the agent.
8086
*
@@ -85,6 +91,7 @@ trait Agent extends js.Object {
8591
*/
8692
def destroy(): Unit = js.native
8793

94+
def getName(options: GetNameOptions): String = js.native
8895
}
8996

9097
/**
@@ -95,7 +102,7 @@ object Agent {
95102
/**
96103
* Agent Extensions
97104
*/
98-
implicit class AgentExtensions(val agent: Agent) extends AnyVal {
105+
implicit final class AgentExtensions(val agent: Agent) extends AnyVal {
99106

100107
/**
101108
* Produces a socket/stream to be used for HTTP requests. By default, this function is the same
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package io.scalajs.nodejs.http
2+
3+
import scala.scalajs.js
4+
5+
class AgentOptions(
6+
var keepAlive: js.UndefOr[Boolean] = js.undefined,
7+
var keepAliveMsecs: js.UndefOr[Int] = js.undefined,
8+
var maxSockets: js.UndefOr[Double] = js.undefined,
9+
var maxFreeSockets: js.UndefOr[Int] = js.undefined,
10+
var timeout: js.UndefOr[Int] = js.undefined
11+
) extends js.Object
Lines changed: 42 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package io.scalajs.nodejs
22
package http
33

4+
import com.thoughtworks.enableIf
45
import io.scalajs.nodejs.buffer.Buffer
56
import io.scalajs.nodejs.net.Socket
6-
import io.scalajs.nodejs.stream.Readable
77
import io.scalajs.util.PromiseHelper._
88

99
import scala.concurrent.Future
1010
import scala.scalajs.js
1111
import scala.scalajs.js.annotation.JSImport
12+
import scala.scalajs.js.typedarray.Uint8Array
13+
import scala.scalajs.js.{Any, |}
1214

1315
/**
1416
* http.ClientRequest - This object is created internally and returned from http.request(). It represents an in-progress
@@ -31,11 +33,25 @@ import scala.scalajs.js.annotation.JSImport
3133
*/
3234
@js.native
3335
@JSImport("http", "ClientRequest")
34-
class ClientRequest extends Readable {
36+
class ClientRequest extends stream.Writable {
3537

36-
def headers: js.Dictionary[String] = js.native
38+
def aborted: Int | Boolean = js.native
3739

38-
def socket: Socket = js.native
40+
def connection: net.Socket = js.native
41+
42+
def finished: Boolean = js.native
43+
44+
var maxHeadersCount: Int | Null = js.native
45+
46+
def path: String = js.native
47+
48+
def socket: net.Socket = js.native
49+
50+
@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs12)
51+
def writableEnded: Boolean = js.native
52+
53+
@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs12)
54+
def writableFinished: Boolean = js.native
3955

4056
/////////////////////////////////////////////////////////////////////////////////
4157
// Methods
@@ -48,34 +64,6 @@ class ClientRequest extends Readable {
4864
*/
4965
def abort(): Unit = js.native
5066

51-
/**
52-
* Finishes sending the request. If any parts of the body are unsent, it will flush them to the stream.
53-
* If the request is chunked, this will send the terminating '0\r\n\r\n'.
54-
* @see [[https://nodejs.org/api/http.html#http_request_end_data_encoding_callback]]
55-
*/
56-
def end(data: js.Any, encoding: String, callback: js.Function): Unit = js.native
57-
58-
/**
59-
* Finishes sending the request. If any parts of the body are unsent, it will flush them to the stream.
60-
* If the request is chunked, this will send the terminating '0\r\n\r\n'.
61-
* @see [[https://nodejs.org/api/http.html#http_request_end_data_encoding_callback]]
62-
*/
63-
def end(data: js.Any, encoding: String): Unit = js.native
64-
65-
/**
66-
* Finishes sending the request. If any parts of the body are unsent, it will flush them to the stream.
67-
* If the request is chunked, this will send the terminating '0\r\n\r\n'.
68-
* @see [[https://nodejs.org/api/http.html#http_request_end_data_encoding_callback]]
69-
*/
70-
def end(data: js.Any): Unit = js.native
71-
72-
/**
73-
* Finishes sending the request. If any parts of the body are unsent, it will flush them to the stream.
74-
* If the request is chunked, this will send the terminating '0\r\n\r\n'.
75-
* @see [[https://nodejs.org/api/http.html#http_request_end_data_encoding_callback]]
76-
*/
77-
def end(): Unit = js.native
78-
7967
/**
8068
* Flush the request headers.
8169
*
@@ -90,39 +78,27 @@ class ClientRequest extends Readable {
9078
*/
9179
def flushHeaders(): Unit = js.native
9280

93-
/**
94-
* Once a socket is assigned to this request and is connected socket.setNoDelay() will be called.
95-
*/
96-
def setNoDelay(noDelay: Int): Unit = js.native
81+
def getHeader[T <: js.Any](name: String): T = js.native
9782

98-
/**
99-
* Once a socket is assigned to this request and is connected socket.setNoDelay() will be called.
100-
*/
101-
def setNoDelay(): Unit = js.native
83+
def removeHeader(name: String): Unit = js.native
10284

103-
/**
104-
* Once a socket is assigned to this request and is connected socket.setKeepAlive() will be called.
105-
* @see [[https://nodejs.org/api/http.html#http_request_setsocketkeepalive_enable_initialdelay]]
106-
*/
107-
def setSocketKeepAlive(enable: Boolean, initialDelay: Int): Unit = js.native
85+
def setHeader(name: String, value: js.Any): Unit = js.native
10886

10987
/**
110-
* Once a socket is assigned to this request and is connected socket.setKeepAlive() will be called.
111-
* @see [[https://nodejs.org/api/http.html#http_request_setsocketkeepalive_enable_initialdelay]]
88+
* Once a socket is assigned to this request and is connected socket.setNoDelay() will be called.
11289
*/
113-
def setSocketKeepAlive(enable: Boolean): Unit = js.native
90+
def setNoDelay(noDelay: Int): Unit = js.native
11491

11592
/**
116-
* Once a socket is assigned to this request and is connected socket.setKeepAlive() will be called.
117-
* @see [[https://nodejs.org/api/http.html#http_request_setsocketkeepalive_enable_initialdelay]]
93+
* Once a socket is assigned to this request and is connected socket.setNoDelay() will be called.
11894
*/
119-
def setSocketKeepAlive(initialDelay: Int): Unit = js.native
95+
def setNoDelay(noDelay: Boolean = js.native): Unit = js.native
12096

12197
/**
12298
* Once a socket is assigned to this request and is connected socket.setKeepAlive() will be called.
12399
* @see [[https://nodejs.org/api/http.html#http_request_setsocketkeepalive_enable_initialdelay]]
124100
*/
125-
def setSocketKeepAlive(): Unit = js.native
101+
def setSocketKeepAlive(enable: Boolean = js.native, initialDelay: Int = js.native): Unit = js.native
126102

127103
/**
128104
* Once a socket is assigned to this request and is connected socket.setTimeout() will be called.
@@ -132,53 +108,7 @@ class ClientRequest extends Readable {
132108
* Same as binding to the timeout event.</li>
133109
* </ul>
134110
*/
135-
def setTimeout(timeout: Int, callback: js.Function): Unit = js.native
136-
137-
/**
138-
* Once a socket is assigned to this request and is connected socket.setTimeout() will be called.
139-
* <ul>
140-
* <li>timeout {Number} Milliseconds before a request is considered to be timed out.</li>
141-
* <li>callback {Function} Optional function to be called when a timeout occurs.
142-
* Same as binding to the timeout event.</li>
143-
* </ul>
144-
*/
145-
def setTimeout(timeout: Int): Unit = js.native
146-
147-
/**
148-
* Sends a chunk of the body. By calling this method many times, the user can stream a
149-
* request body to a server--in that case it is suggested to use the ['Transfer-Encoding', 'chunked']
150-
* header line when creating the request.
151-
*
152-
* The chunk argument should be a Buffer or a string.
153-
* The encoding argument is optional and only applies when chunk is a string. Defaults to 'utf8'.
154-
* The callback argument is optional and will be called when this chunk of data is flushed.
155-
* Returns request.
156-
*/
157-
def write(chunk: js.Any, encoding: String, callback: js.Function): Unit = js.native
158-
159-
/**
160-
* Sends a chunk of the body. By calling this method many times, the user can stream a
161-
* request body to a server--in that case it is suggested to use the ['Transfer-Encoding', 'chunked']
162-
* header line when creating the request.
163-
*
164-
* The chunk argument should be a Buffer or a string.
165-
* The encoding argument is optional and only applies when chunk is a string. Defaults to 'utf8'.
166-
* The callback argument is optional and will be called when this chunk of data is flushed.
167-
* Returns request.
168-
*/
169-
def write(chunk: js.Any, encoding: String): Unit = js.native
170-
171-
/**
172-
* Sends a chunk of the body. By calling this method many times, the user can stream a
173-
* request body to a server--in that case it is suggested to use the ['Transfer-Encoding', 'chunked']
174-
* header line when creating the request.
175-
*
176-
* The chunk argument should be a Buffer or a string.
177-
* The encoding argument is optional and only applies when chunk is a string. Defaults to 'utf8'.
178-
* The callback argument is optional and will be called when this chunk of data is flushed.
179-
* Returns request.
180-
*/
181-
def write(chunk: js.Any): Unit = js.native
111+
def setTimeout(timeout: Int, callback: js.Function = js.native): Unit = js.native
182112

183113
}
184114

@@ -187,10 +117,7 @@ class ClientRequest extends Readable {
187117
*/
188118
object ClientRequest {
189119

190-
/**
191-
* Client Request Events
192-
*/
193-
implicit class ClientRequestEvents(val client: ClientRequest) extends AnyVal {
120+
implicit final class ClientRequestExtensions(val client: ClientRequest) extends AnyVal {
194121

195122
/**
196123
* Emitted when the request has been aborted by the client. This event is only emitted on the first call to abort().
@@ -246,23 +173,25 @@ object ClientRequest {
246173
@inline
247174
def onUpgrade(callback: (IncomingMessage, Socket, Buffer) => Any): client.type = client.on("upgrade", callback)
248175

249-
}
250-
251-
/**
252-
* Client Request Extensions
253-
*/
254-
implicit class ClientRequestEnrichment(val client: ClientRequest) extends AnyVal {
176+
@inline
177+
def endFuture(data: Uint8Array): Future[Unit] = {
178+
promiseWithError0[Error](client.end(data, _))
179+
}
255180

256181
@inline
257-
def endFuture(data: js.Any, encoding: String): Future[js.Any] = {
258-
promiseWithError1[SystemError, js.Any](client.end(data, encoding, _))
182+
def endFuture(data: String, encoding: String): Future[Unit] = {
183+
promiseWithError0[Error](client.end(data, encoding, _))
259184
}
260185

261186
@inline
262-
def writeFuture(chunk: js.Any, encoding: String): Future[js.Any] = {
263-
promiseWithError1[SystemError, js.Any](client.write(chunk, encoding, _))
187+
def writeFuture(chunk: Uint8Array): Future[Unit] = {
188+
promiseWithError0[Error](client.write(chunk, _))
264189
}
265190

191+
@inline
192+
def writeFuture(chunk: String, encoding: String): Future[Unit] = {
193+
promiseWithError0[Error](client.write(chunk, encoding, _))
194+
}
266195
}
267196

268197
}
Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
package io.scalajs.nodejs.http
22

33
import scala.scalajs.js
4+
import scala.scalajs.js.typedarray.Uint8Array
5+
import scala.scalajs.js.|
46

5-
/**
6-
* Connection Options
7-
* @param keepAlive Keep sockets around in a pool to be used by other requests in the future. Default = false
8-
* @param keepAliveMsecs When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive.
9-
* Default = 1000. Only relevant if keepAlive is set to true.
10-
* @param maxSockets Maximum number of sockets to allow per host. Default = Infinity.
11-
* @param maxFreeSockets Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to
12-
* true (default: 256).
13-
*/
14-
class ConnectionOptions(var keepAlive: js.UndefOr[Boolean] = js.undefined,
15-
var keepAliveMsecs: js.UndefOr[Int] = js.undefined,
16-
var maxSockets: js.UndefOr[Double] = js.undefined,
17-
var maxFreeSockets: js.UndefOr[Int] = js.undefined)
18-
extends js.Object
7+
class ConnectionOptions(
8+
// for socket.connect(option)
9+
var port: Int,
10+
var host: js.UndefOr[String] = js.undefined,
11+
var localAddress: js.UndefOr[String] = js.undefined,
12+
var localPort: js.UndefOr[Int] = js.undefined,
13+
var family: js.UndefOr[Int] = js.undefined,
14+
var hints: js.UndefOr[Int] = js.undefined,
15+
var lookup: js.UndefOr[js.Function1[String, Any]] = js.undefined,
16+
var onread: js.UndefOr[OnreadObject] = js.undefined,
17+
// for new Socket(option)
18+
var fd: js.UndefOr[Int] = js.undefined,
19+
var allowHalfOpen: js.UndefOr[Boolean] = js.undefined,
20+
var readable: js.UndefOr[Boolean] = js.undefined,
21+
var writable: js.UndefOr[Int] = js.undefined
22+
) extends js.Object
23+
24+
class OnreadObject(
25+
var buffer: Uint8Array | js.Function0[Uint8Array],
26+
var calback: js.Function2[Int, Uint8Array, Boolean]
27+
) extends js.Object
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.scalajs.nodejs.http
2+
3+
import scala.scalajs.js
4+
5+
class GetNameOptions(
6+
var host: String,
7+
var port: js.UndefOr[Int] = js.undefined,
8+
var localAddress: js.UndefOr[String] = js.undefined,
9+
var family: js.UndefOr[Int] = js.undefined
10+
) extends js.Object

0 commit comments

Comments
 (0)