|
398 | 398 | [session channel stream]
|
399 | 399 | (if (not= :eof (:status stream))
|
400 | 400 | (let [pump-fn (if (= :output (:direction stream)) pull push)
|
401 |
| - last-read-time (:last-read-time stream) |
402 |
| - new-status (pump-fn session channel (:id stream) (:stream stream)) |
403 |
| - now (System/currentTimeMillis)] |
404 |
| - (when (and (= pump-fn pull) |
405 |
| - (= :eagain new-status) |
406 |
| - (< (-> session :options :read-timeout) (- now last-read-time))) |
407 |
| - (error/raise "Read timeout on a channel." |
408 |
| - {:direction (-> stream :direction name) |
409 |
| - :id (-> stream :id) |
410 |
| - :timeout (-> session :options :read-timeout) |
411 |
| - :session session})) |
412 |
| - (assoc stream :status new-status :last-read-time now)) |
| 401 | + new-status (pump-fn session channel (:id stream) (:stream stream))] |
| 402 | + (assoc stream :status new-status |
| 403 | + :last-read-time (if (= :ready new-status) |
| 404 | + (System/currentTimeMillis) |
| 405 | + (:last-read-time stream)))) |
413 | 406 | stream))
|
414 | 407 |
|
| 408 | +(defn- enforce-read-timeout |
| 409 | + "Enforce the read timeout on the output streams in a set of streams. |
| 410 | +
|
| 411 | + Arguments: |
| 412 | +
|
| 413 | + session The clj-libssh2.session.Session object for the current session. |
| 414 | + channel The SSH channel that we're enforcing timeouts on. |
| 415 | + streams The collection of streams that are in use in pump |
| 416 | +
|
| 417 | + Return: |
| 418 | +
|
| 419 | + nil, or throw an exception if the timeout is exceeded on any of the streams |
| 420 | + given." |
| 421 | + [session channel streams] |
| 422 | + (let [read-timeout (-> session :options :read-timeout) |
| 423 | + last-read-time (->> streams |
| 424 | + (remove #(= :input (:direction %))) |
| 425 | + (map :last-read-time) |
| 426 | + (#(when-not (empty? %) |
| 427 | + (apply max %))))] |
| 428 | + (when (and (some? last-read-time) |
| 429 | + (< read-timeout (- (System/currentTimeMillis) last-read-time))) |
| 430 | + (error/raise "Read timeout on a channel." |
| 431 | + {:timeout read-timeout |
| 432 | + :session session |
| 433 | + :channel channel})))) |
| 434 | + |
415 | 435 | (defn pump
|
416 | 436 | "Process a collection of input and output streams all at once. This will run
|
417 | 437 | until all streams have reported EOF.
|
|
452 | 472 | (do
|
453 | 473 | (when (contains? status-set :eagain)
|
454 | 474 | (wait session))
|
| 475 | + (enforce-read-timeout session channel s) |
455 | 476 | (recur (map (partial pump-stream session channel) streams)))
|
456 | 477 | (->> s
|
457 | 478 | (filter #(= :output (:direction %)))
|
|
0 commit comments