| 1219 | close(false) {} |
| 1220 | |
| 1221 | Future<Response> send(const Request& request, bool streamedResponse) |
| 1222 | { |
| 1223 | if (!disconnection.future().isPending()) { |
| 1224 | return Failure("Disconnected"); |
| 1225 | } |
| 1226 | |
| 1227 | if (close) { |
| 1228 | return Failure("Cannot pipeline after 'Connection: close'"); |
| 1229 | } |
| 1230 | |
| 1231 | if (request.type == Request::PIPE) { |
| 1232 | if (request.reader.isNone()) { |
| 1233 | return Failure("Request reader must be set for PIPE request"); |
| 1234 | } |
| 1235 | |
| 1236 | if (!request.body.empty()) { |
| 1237 | return Failure("Request body must be empty for PIPE request"); |
| 1238 | } |
| 1239 | |
| 1240 | Option<string> contentLength = request.headers.get("Content-Length"); |
| 1241 | if (request.headers.contains("Content-Length")) { |
| 1242 | return Failure("'Content-Length' cannot be set for PIPE request"); |
| 1243 | } |
| 1244 | } |
| 1245 | |
| 1246 | if (!request.keepAlive) { |
| 1247 | close = true; |
| 1248 | } |
| 1249 | |
| 1250 | // We must chain the calls to Socket::send as it |
| 1251 | // otherwise interleaves data across calls. |
| 1252 | network::Socket socket_ = socket; |
| 1253 | |
| 1254 | sendChain = sendChain |
| 1255 | .then([socket_, request]() { |
| 1256 | return _send(socket_, encode(request)); |
| 1257 | }); |
| 1258 | |
| 1259 | // If we can't write to the socket, disconnect. |
| 1260 | sendChain |
| 1261 | .onFailed(defer(self(), [this](const string& failure) { |
| 1262 | disconnect(failure); |
| 1263 | })); |
| 1264 | |
| 1265 | Promise<Response> promise; |
| 1266 | Future<Response> response = promise.future(); |
| 1267 | |
| 1268 | pipeline.push(std::make_tuple(streamedResponse, std::move(promise))); |
| 1269 | |
| 1270 | return response; |
| 1271 | } |
| 1272 | |
| 1273 | Future<Nothing> disconnect(const Option<string>& message = None()) |
| 1274 | { |
nothing calls this directly
no test coverage detected