(message, value)
| 133 | Request.error = -2; |
| 134 | |
| 135 | function callback(message, value) { |
| 136 | let socket = this.socket; |
| 137 | |
| 138 | if (1 === message) { // connected |
| 139 | if (0 !== this.state) |
| 140 | throw new Error("socket connected but http not in connecting state"); |
| 141 | |
| 142 | this.state = 1; // advance to sending request headers state |
| 143 | |
| 144 | const parts = []; |
| 145 | parts.push(`${this.method} `, this.path, " HTTP/1.1\r\n"); |
| 146 | parts.push("Connection: close\r\n"); |
| 147 | |
| 148 | let length, host = this.host; |
| 149 | for (let i = 0; i < (this.headers?.length ?? 0); i += 2) { |
| 150 | let name = this.headers[i].toString(); |
| 151 | parts.push(`${name}: `, this.headers[i + 1].toString(), "\r\n"); |
| 152 | name = name.toLowerCase(); |
| 153 | if ("content-length" === name) |
| 154 | length = true; |
| 155 | else if ("host" === name) |
| 156 | host = undefined; |
| 157 | } |
| 158 | |
| 159 | if (this.body && (true !== this.body) && !length) { |
| 160 | length = (this.body instanceof ArrayBuffer) ? this.body.byteLength : this.body.length; |
| 161 | parts.push(`content-length: ${length}\r\n`); |
| 162 | } |
| 163 | |
| 164 | if (host) |
| 165 | parts.push(`Host: ${host}\r\n`); |
| 166 | |
| 167 | parts.push("\r\n"); |
| 168 | |
| 169 | delete this.method; |
| 170 | delete this.path; |
| 171 | delete this.host; |
| 172 | delete this.headers; |
| 173 | |
| 174 | this.parts = parts; |
| 175 | |
| 176 | message = 3; |
| 177 | value = socket.write(); |
| 178 | } |
| 179 | |
| 180 | if (3 === message) { // safe to write more data |
| 181 | if (1 == this.state) { |
| 182 | const p = [], parts = this.parts; |
| 183 | while (value && parts.length) { |
| 184 | const length = parts[0].length; |
| 185 | if (length <= value) { |
| 186 | p.push(parts.shift()); |
| 187 | value -= length; |
| 188 | } |
| 189 | else { |
| 190 | p.push(parts[0].slice(0, value)); |
| 191 | parts[0] = parts[0].slice(value); |
| 192 | value = 0; |
no test coverage detected