UNPKG

4.97 kBJavaScriptView Raw
1
2
3var URL = require("url")
4, net = require("net")
5, Agent = require("http").Agent
6, agentPool = {}
7, debug = require("../../lib/log.js")("app:net")
8, querystring = require("querystring")
9
10, adapter = {
11 http: http, // port 80
12 https: http, // port 443
13 mqtt: na, // port 1883
14 mqtts: na, // port 8883
15 amqp: na, // port 5672
16 amqps: na, // port 5671
17 tcp: function(opts, next) {
18 var socket = new net.Socket()
19 , body = ""
20 socket.connect(opts.port, opts.hostname, function() {
21 if (opts.hParam.noDelay === "true") {
22 socket.setNoDelay(true)
23 }
24 if (opts.body) {
25 socket.write(opts.hParam.encoding ?
26 Buffer.from(opts.body, opts.hParam.encoding) :
27 opts.body
28 )
29 }
30 socket.end()
31 })
32 socket.on("error", debug.error)
33 socket.on("data", function(d) {
34 body += d
35 })
36 socket.on("close", function() {
37 if (next) {
38 next(null, socket, body)
39 }
40 })
41 },
42 udp: function(opts, next) {
43 var socket = require("dgram")
44 .createSocket({
45 reuseAddr: true,
46 type: net.isIPv6(opts.hostname) ? "udp6" : "udp4"
47 })
48 socket.on("error", debug.error)
49
50 socket.bind(function() {
51 var message = opts.body
52 , len = message.length
53 if (opts.hParam.broadcast == "true") {
54 socket.setBroadcast(true)
55 }
56 if (opts.hParam.ttl) {
57 socket.setTTL(+opts.hParam.ttl)
58 }
59 if (opts.hParam.encoding) {
60 message = Buffer.from(message, opts.hParam.encoding)
61 }
62 socket.send(message, opts.port, opts.hostname, function(err) {
63 socket.close()
64 if (next) {
65 next(err, socket)
66 }
67 })
68 })
69 }
70}
71
72
73exports.request = request
74
75
76function request(url, opts, next) {
77 try {
78 var req = validate(url)
79
80 if (!next && typeof opts === "function") {
81 next = opts
82 opts = null
83 }
84
85 if (opts) {
86 req.method = opts.method
87 req.headers = opts.headers
88 req.body = opts.body
89 }
90
91 debug("%s %s", (req.method || "REQ"), url)
92 adapter[req.schema](req, next)
93 } catch(e) {
94 debug.error(e)
95 }
96}
97
98function validate(url) {
99 var req = typeof url === "string" ? URL.parse(url) : url
100 , schema = req.schema = req.protocol.slice(0, -1)
101 req.hParam = req.hash ? querystring.parse(req.hash.slice(1)) : {}
102 if (!adapter[schema]) {
103 throw "Invalid schema: " + req.schema
104 }
105 return req
106}
107
108var unsentHttp = []
109
110function http(opts, next) {
111 if (opts.hParam.keepAlive) {
112 var time = +opts.hParam.keepAlive
113 if (time) {
114 opts.agent = agentPool[time] || (agentPool[time] = new Agent({
115 keepAlive: true,
116 keepAliveMsecs: time
117 }))
118 }
119 }
120 var req = require(opts.schema).request(opts, function(res) {
121 if (res.statusCode < 200 || res.statusCode > 299) {
122 return onError("Error: status " + res.statusCode)
123 }
124 var body = ""
125 res.on("data", function(d) {
126 body += d
127 })
128 res.on("end", function() {
129 if (next) {
130 next(null, res, body)
131 }
132 })
133 })
134
135 if (opts.hParam.timeout > 0) {
136 req.setTimeout(+opts.hParam.timeout, function() {
137 req.abort()
138 })
139 }
140 req.on("error", onError)
141
142 if (opts.body) {
143 req.write(opts.body)
144 }
145
146 req.end()
147
148 function onError(e) {
149 debug.error("%s on %s, retry: %i", e, opts.href, opts.hParam.retry)
150 if (opts.hParam.retry > 0) {
151 opts.hParam.retry -= 1
152 if (unsentHttp.push([opts, next]) !== 1) return
153 setTimeout(function() {
154 debug("Resending %i requests", unsentHttp.length)
155 unsentHttp.splice(0).forEach(function(row) {
156 http(row[0], row[1])
157 })
158 }, 60000).unref()
159 }
160 }
161}
162
163function na(opts, next) {
164 throw opts.schema + " not implemented"
165}
166
167// PostgreSQL max query size 1 gigabyte
168// SQLITE_MAX_SQL_LENGTH which defaults to 1000000
169// mysql:
170// SHOW VARIABLES LIKE 'max_allowed_packet';
171// mysql max_allowed_packet=1048576 or 1mb
172
173
174/*
175Protocol Purpose Normal port SSL variant SSL port
176SMTP Send email 25/587 SMTPS 465 (legacy)[5][dead link]
177POP3 Retrieve email 110 POP3S 995
178IMAP Read email 143 IMAPS 993
179NNTP News reader 119/433 NNTPS 563
180LDAP Directory Access 389 LDAPS 636
181FTP File transfer 21 FTPS 990
182 // https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml
183 // tag:sandro@hawke.org,2001-06-05:Taiko. http://www.taguri.org/
184 // dns:[//authority/]domain[?CLASS=class;TYPE=type]
185 // geo:13.4125,103.8667 lat,lon,alt https://tools.ietf.org/html/rfc5870
186 // mailto:infobot@example.com?cc=bob@example.com&subject=current-issue&body=send%20current-issue
187 // mqtt[s]://[username][:password]@host.domain[:port]
188 // ftp: require("./ftp"), // port 21
189 // imap://<iserver>/<enc-mailbox>[<uidvalidity>]<iuid>[<isection>][<ipartial>][<iurlauth>]
190 // imap://michael@example.org/INBOX
191 // imap://joe@example.com/INBOX/;uid=20/;section=1.2;urlauth=submit+fred:internal:91354a473744909de610943775f92038
192 // imap: require("./imap"), // port 143
193 // postgresql://host1:123,host2:456/somedb?target_session_attrs=any&application_name=myapp
194 // smtps://address%40gmail.com:password@smtp.gmail.com
195 // smtp: require("./smtp"), // port 25
196 // ssdp: require("./ssdp") // port 1900
197*/