Rev 3981: Add client and server APIs for streamed request bodies. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Feb 4 12:56:18 GMT 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3981
revision-id: pqm at pqm.ubuntu.com-20090204125611-m7kqmwruvndk7yrv
parent: pqm at pqm.ubuntu.com-20090204045809-piqek6zlyl0x5ncw
parent: andrew.bennetts at canonical.com-20090204120526-ftwn676dnbmremw8
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2009-02-04 12:56:11 +0000
message:
  Add client and server APIs for streamed request bodies.
modified:
  bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
  bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
  bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
  bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
  bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
  bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
    ------------------------------------------------------------
    revno: 3842.3.22
    revision-id: andrew.bennetts at canonical.com-20090204120526-ftwn676dnbmremw8
    parent: andrew.bennetts at canonical.com-20090202055634-2uktwnsmer5s7g6q
    parent: pqm at pqm.ubuntu.com-20090204045809-piqek6zlyl0x5ncw
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: call_with_body_stream
    timestamp: Wed 2009-02-04 23:05:26 +1100
    message:
      Merge bzr.dev
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
      bzrlib/dirstate.py             dirstate.py-20060728012006-d6mvoihjb3je9peu-1
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/patches.py              patches.py-20050727183609-378c1cc5972ce908
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/branch_implementations/test_iter_merge_sorted_revisions.py test_merge_sorted_re-20090121004847-to3gvjwigstu93eh-1
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
      bzrlib/tests/test_patches.py   test_patches.py-20051231203844-f4974d20f6aea09c
      bzrlib/tests/tree_implementations/test_get_symlink_target.py test_get_symlink_tar-20070225165554-ickod3w3t7u0zzqh-1
      bzrlib/tests/tree_implementations/test_path_content_summary.py test_path_content_su-20070904100855-3vrwedz6akn34kl5-1
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
      bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
    ------------------------------------------------------------
    revno: 3842.3.21
    revision-id: andrew.bennetts at canonical.com-20090202055634-2uktwnsmer5s7g6q
    parent: andrew.bennetts at canonical.com-20090127074855-4z3yi34s583vrd1v
    parent: pqm at pqm.ubuntu.com-20090130031028-y70uzzpad9c47v09
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: call_with_body_stream
    timestamp: Mon 2009-02-02 16:56:34 +1100
    message:
      Merge bzr.dev.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/annotate.py             annotate.py-20050922133147-7c60541d2614f022
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
      bzrlib/foreign.py              foreign.py-20081112170002-olsxmandkk8qyfuq-1
      bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/missing.py              missing.py-20050812153334-097f7097e2a8bcd1
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/tests/blackbox/test_annotate.py testannotate.py-20051013044000-457f44801bfa9d39
      bzrlib/tests/blackbox/test_breakin.py test_breakin.py-20070424043903-qyy6zm4pj3h4sbp3-1
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/blackbox/test_missing.py test_missing.py-20051211212735-a2cf4c1840bb84c4
      bzrlib/tests/blackbox/test_serve.py test_serve.py-20060913064329-8t2pvmsikl4s3xhl-1
      bzrlib/tests/blackbox/test_shelve.py test_ls_shelf.py-20081202053526-thlo8yt0pi1cgor1-1
      bzrlib/tests/test_foreign.py   test_foreign.py-20081125004048-ywb901edgp9lluxo-1
      bzrlib/tests/test_graph.py     test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
      bzrlib/tests/test_merge.py     testmerge.py-20050905070950-c1b5aa49ff911024
      bzrlib/tests/test_missing.py   test_missing.py-20051212000028-694fa4f658a81f48
      bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
      bzrlib/util/bencode.py         bencode.py-20070220044742-sltr28q21w2wzlxi-1
      bzrlib/util/tests/test_bencode.py test_bencode.py-20070713042202-qjw8rppxaz7ky6i6-1
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
    ------------------------------------------------------------
    revno: 3842.3.20
    revision-id: andrew.bennetts at canonical.com-20090127074855-4z3yi34s583vrd1v
    parent: andrew.bennetts at canonical.com-20090127070825-4yicgkrd91k93fox
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: call_with_body_stream
    timestamp: Tue 2009-01-27 18:48:55 +1100
    message:
      Re-revert changes from another thread that accidentally got reinstated here.
    removed:
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
    modified:
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
    ------------------------------------------------------------
    revno: 3842.3.19
    revision-id: andrew.bennetts at canonical.com-20090127070825-4yicgkrd91k93fox
    parent: andrew.bennetts at canonical.com-20090127050443-3yw5hhk10ss23hzu
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: call_with_body_stream
    timestamp: Tue 2009-01-27 18:08:25 +1100
    message:
      Tweaks suggested by review.
    modified:
      bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
    ------------------------------------------------------------
    revno: 3842.3.18
    revision-id: andrew.bennetts at canonical.com-20090127050443-3yw5hhk10ss23hzu
    parent: andrew.bennetts at canonical.com-20090113062447-v1dnaf4e8x8mk8r8
    parent: pqm at pqm.ubuntu.com-20090126181248-yl5ctbxc3y6nu9m4
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: call_with_body_stream
    timestamp: Tue 2009-01-27 16:04:43 +1100
    message:
      Merge bzr.dev.
    added:
      bzrlib/plugins/netrc_credential_store/ netrc_credential_sto-20081006090354-oaoid1olhgk8vevm-1
      bzrlib/plugins/netrc_credential_store/__init__.py __init__.py-20081006090402-hd75m8kcrrm0vlz1-1
      bzrlib/plugins/netrc_credential_store/tests/ tests-20081006090406-6mddz8j10pux993e-1
      bzrlib/plugins/netrc_credential_store/tests/__init__.py __init__.py-20081006090411-vytweyz6sun61d4q-1
      bzrlib/plugins/netrc_credential_store/tests/test_netrc.py test_netrc.py-20081006090414-vm3or4tz6c9wk2oi-1
      bzrlib/tests/blackbox/test_filesystem_cicp.py test_filesystem_cicp-20081028010456-vclkg401m81keaxc-1
      bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py test_dotted_revno_to-20090121014844-6x7d9jtri5sspg1o-1
      bzrlib/tests/branch_implementations/test_iter_merge_sorted_revisions.py test_merge_sorted_re-20090121004847-to3gvjwigstu93eh-1
      bzrlib/tests/branch_implementations/test_revision_id_to_dotted_revno.py test_revision_id_to_-20090122052032-g3czslif6sdqfkh3-1
      bzrlib/tests/https_server.py   https_server.py-20071121173708-aj8zczi0ziwbwz21-1
      bzrlib/tests/ssl_certs/        ssl_certs-20071124141654-dc9za9nho2gmzbri-1
      bzrlib/tests/ssl_certs/__init__.py __init__.py-20071124141703-j5hr254lm287lyut-8
      bzrlib/tests/ssl_certs/ca.crt  ca.crt-20071124141703-j5hr254lm287lyut-7
      bzrlib/tests/ssl_certs/ca.key  ca.key-20071124141703-j5hr254lm287lyut-6
      bzrlib/tests/ssl_certs/create_ssls.py create_ssls.py-20071124141703-j5hr254lm287lyut-5
      bzrlib/tests/ssl_certs/server.crt server.crt-20071124141703-j5hr254lm287lyut-4
      bzrlib/tests/ssl_certs/server.csr server.csr-20071124141703-j5hr254lm287lyut-3
      bzrlib/tests/ssl_certs/server_with_pass.key server_with_pass.key-20071124141703-j5hr254lm287lyut-2
      bzrlib/tests/ssl_certs/server_without_pass.key server_without_pass.-20071124141703-j5hr254lm287lyut-1
      doc/developers/case-insensitive-file-systems.txt caseinsensitivefiles-20081117224243-p84xpmqnsa1p8k91-1
      doc/news-template.txt          newstemplate.txt-20090113030949-kn6dn0xcj1rd6vmn-1
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzr                            bzr.py-20050313053754-5485f144c7006fa6
      bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
      bzrlib/config.py               config.py-20051011043216-070c74f4e9e338e8
      bzrlib/delta.py                delta.py-20050729221636-54cf14ef94783d0a
      bzrlib/dirstate.py             dirstate.py-20060728012006-d6mvoihjb3je9peu-1
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/help_topics/en/configuration.txt configuration.txt-20060314161707-868350809502af01
      bzrlib/help_topics/en/rules.txt rules.txt-20080516063844-ghr5l6pvvrhiycun-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/mail_client.py          mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/mutabletree.py          mutabletree.py-20060906023413-4wlkalbdpsxi2r4y-2
      bzrlib/osutils.py              osutils.py-20050309040759-eeaff12fbf77ac86
      bzrlib/progress.py             progress.py-20050610070202-df9faaab791964c0
      bzrlib/push.py                 push.py-20080606021927-5fe39050e8xne9un-1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/rules.py                properties.py-20080506032617-9k06uqalkf09ck0z-1
      bzrlib/smart/medium.py         medium.py-20061103051856-rgu2huy59fkz902q-1
      bzrlib/status.py               status.py-20050505062338-431bfa63ec9b19e6
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/__init__.py __init__.py-20051128053524-eba30d8255e08dc3
      bzrlib/tests/blackbox/test_init.py test_init.py-20060309032856-a292116204d86eb7
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
      bzrlib/tests/blackbox/test_status.py teststatus.py-20050712014354-508855eb9f29f7dc
      bzrlib/tests/blackbox/test_upgrade.py test_upgrade.py-20060120060132-b41e5ed2f886ad28
      bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
      bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
      bzrlib/tests/branch_implementations/test_stacking.py test_stacking.py-20080214020755-msjlkb7urobwly0f-1
      bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
      bzrlib/tests/commands/test_push.py test_push.py-20070525122003-gc1ob0ea0nueoqgj-1
      bzrlib/tests/http_server.py    httpserver.py-20061012142527-m1yxdj1xazsf8d7s-1
      bzrlib/tests/test_bzrdir.py    test_bzrdir.py-20060131065654-deba40eef51cf220
      bzrlib/tests/test_config.py    testconfig.py-20051011041908-742d0c15d8d8c8eb
      bzrlib/tests/test_delta.py     test_delta.py-20070110134455-sqpd1y7mbjndelxf-1
      bzrlib/tests/test_http.py      testhttp.py-20051018020158-b2eef6e867c514d9
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
      bzrlib/tests/test_mail_client.py test_mail_client.py-20070809192806-vuxt3t19srtpjpdn-2
      bzrlib/tests/test_merge.py     testmerge.py-20050905070950-c1b5aa49ff911024
      bzrlib/tests/test_osutils.py   test_osutils.py-20051201224856-e48ee24c12182989
      bzrlib/tests/test_plugins.py   plugins.py-20050622075746-32002b55e5e943e9
      bzrlib/tests/test_progress.py  test_progress.py-20060308160359-978c397bc79b7fda
      bzrlib/tests/test_rules.py     test_properties.py-20080506033501-3p9kmuob25dho8xl-1
      bzrlib/tests/test_sftp_transport.py testsftp.py-20051027032739-247570325fec7e7e
      bzrlib/tests/test_status.py    test_status.py-20060516190614-fbf6432e4a6e8aa5
      bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
      bzrlib/tests/test_ui.py        test_ui.py-20051130162854-458e667a7414af09
      bzrlib/tests/tree_implementations/test_inv.py test_inv.py-20070312023226-0cdvk5uwhutis9vg-1
      bzrlib/tests/workingtree_implementations/test_move.py test_move.py-20070225171927-mohn2vqj5fx7edc6-1
      bzrlib/trace.py                trace.py-20050309040759-c8ed824bdcd4748a
      bzrlib/transport/__init__.py   transport.py-20050711165921-4978aa7ce1285ad5
      bzrlib/transport/ftp/__init__.py ftp.py-20051116161804-58dc9506548c2a53
      bzrlib/transport/http/__init__.py http_transport.py-20050711212304-506c5fd1059ace96
      bzrlib/transport/http/_pycurl.py pycurlhttp.py-20060110060940-4e2a705911af77a6
      bzrlib/transport/http/_urllib.py _urlgrabber.py-20060113083826-0bbf7d992fbf090c
      bzrlib/transport/http/ca_bundle.py ca_bundle.py-20070226091335-84kb1xg1r2jjf858-1
      bzrlib/transport/http/response.py _response.py-20060613154423-a2ci7hd4iw5c7fnt-1
      bzrlib/transport/sftp.py       sftp.py-20051019050329-ab48ce71b7e32dfe
      bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
      bzrlib/ui/__init__.py          ui.py-20050824083933-8cf663c763ba53a9
      bzrlib/ui/text.py              text.py-20051130153916-2e438cffc8afc478
      bzrlib/upgrade.py              history2weaves.py-20050818063535-e7d319791c19a8b2
      doc/developers/api-versioning.txt apiversioning.txt-20070626065626-iiihgmhgkv91uphz-1
      doc/developers/authentication-ring.txt authring.txt-20070718200437-q5tdik0ne6lor86d-1
      doc/developers/index.txt       index.txt-20070508041241-qznziunkg0nffhiw-1
      doc/developers/plugin-api.txt  pluginapi.txt-20080229110225-q2j5y4agqhlkjn0s-1
      setup.py                       setup.py-20050314065409-02f8a0a6e3f9bc70
      tools/win32/build_release.py   build_release.py-20081105204355-2ghh5cv01v1x4rzz-1
      tools/win32/bzr.iss.cog        bzr.iss.cog-20060622100836-b3yup582rt3y0nvm-5
    ------------------------------------------------------------
    revno: 3842.3.17
    revision-id: andrew.bennetts at canonical.com-20090113062447-v1dnaf4e8x8mk8r8
    parent: andrew.bennetts at canonical.com-20090112061723-y4s1s29mf2fq1ops
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Tue 2009-01-13 17:24:47 +1100
    message:
      Add comment.
    modified:
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
    ------------------------------------------------------------
    revno: 3842.3.16
    revision-id: andrew.bennetts at canonical.com-20090112061723-y4s1s29mf2fq1ops
    parent: andrew.bennetts at canonical.com-20090106233811-3lzvth3szdhh9wej
    parent: andrew.bennetts at canonical.com-20090112040039-1au92x5eqvt8p9t9
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Mon 2009-01-12 17:17:23 +1100
    message:
      Merge updated call_with_body_bytes.
    modified:
      bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
        ------------------------------------------------------------
        revno: 3923.5.6
        revision-id: andrew.bennetts at canonical.com-20090112040039-1au92x5eqvt8p9t9
        parent: andrew.bennetts at canonical.com-20090112022402-07r27yabykqp3rdw
        committer: Andrew Bennetts <andrew.bennetts at canonical.com>
        branch nick: call_with_body_stream
        timestamp: Mon 2009-01-12 15:00:39 +1100
        message:
          Fix a style nit.
        modified:
          bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
        ------------------------------------------------------------
        revno: 3923.5.5
        revision-id: andrew.bennetts at canonical.com-20090112022402-07r27yabykqp3rdw
        parent: andrew.bennetts at canonical.com-20090112021051-68imnanpiw25x0vk
        committer: Andrew Bennetts <andrew.bennetts at canonical.com>
        branch nick: call_with_body_stream
        timestamp: Mon 2009-01-12 13:24:02 +1100
        message:
          Cleanly abort the request if an error occurs while iterating a body stream.
        modified:
          bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
          bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
        ------------------------------------------------------------
        revno: 3923.5.4
        revision-id: andrew.bennetts at canonical.com-20090112021051-68imnanpiw25x0vk
        parent: andrew.bennetts at canonical.com-20090109062245-jw5jbc723zefd8ru
        committer: Andrew Bennetts <andrew.bennetts at canonical.com>
        branch nick: call_with_body_stream
        timestamp: Mon 2009-01-12 13:10:51 +1100
        message:
          Allow a request's body part(s) to be followed by an error.
        modified:
          bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
          bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
          bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
        ------------------------------------------------------------
        revno: 3923.5.3
        revision-id: andrew.bennetts at canonical.com-20090109062245-jw5jbc723zefd8ru
        parent: andrew.bennetts at canonical.com-20090109061134-ulc6y3mpz1djqigh
        committer: Andrew Bennetts <andrew.bennetts at canonical.com>
        branch nick: call_with_body_stream
        timestamp: Fri 2009-01-09 17:22:45 +1100
        message:
          Raise a better exception if a premature message end happens.
        modified:
          bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
        ------------------------------------------------------------
        revno: 3923.5.2
        revision-id: andrew.bennetts at canonical.com-20090109061134-ulc6y3mpz1djqigh
        parent: andrew.bennetts at canonical.com-20090109055237-t3oandez65vs06uk
        committer: Andrew Bennetts <andrew.bennetts at canonical.com>
        branch nick: call_with_body_stream
        timestamp: Fri 2009-01-09 17:11:34 +1100
        message:
          Completely delegate handling of request body chunks to the command object.  The default implementation accumulates, like the existing behaviour.
        modified:
          bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
          bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
          bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
        ------------------------------------------------------------
        revno: 3923.5.1
        revision-id: andrew.bennetts at canonical.com-20090109055237-t3oandez65vs06uk
        parent: pqm at pqm.ubuntu.com-20090106171520-9pzjoqa7m74hvhht
        committer: Andrew Bennetts <andrew.bennetts at canonical.com>
        branch nick: call_with_body_stream
        timestamp: Fri 2009-01-09 16:52:37 +1100
        message:
          Add _SmartClient.call_with_body_bytes, plus some server-side code for handling bodies delivered in multiple parts.
        modified:
          bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
          bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
          bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
          bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
          bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
          bzrlib/util/bencode.py         bencode.py-20070220044742-sltr28q21w2wzlxi-1
    ------------------------------------------------------------
    revno: 3842.3.15
    revision-id: andrew.bennetts at canonical.com-20090106233811-3lzvth3szdhh9wej
    parent: andrew.bennetts at canonical.com-20081212075837-5rmjp846gxxd1tvr
    parent: pqm at pqm.ubuntu.com-20090106171520-9pzjoqa7m74hvhht
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Wed 2009-01-07 10:38:11 +1100
    message:
      Merge from bzr.dev
    added:
      bzrlib/_chunks_to_lines_py.py  _chunks_to_lines_py.-20081211024848-6uc3mtuje8j14l60-1
      bzrlib/_chunks_to_lines_pyx.pyx _chunks_to_lines_pyx-20081211021736-op7n8vrxgrd8snfi-1
      bzrlib/fifo_cache.py           fifo_cache.py-20081209212307-31ffjwvteyvmydnf-1
      bzrlib/tests/blackbox/test_shelve.py test_ls_shelf.py-20081202053526-thlo8yt0pi1cgor1-1
      bzrlib/tests/per_repository/test_add_inventory_by_delta.py test_add_inventory_d-20081013002626-rut81igtlqb4590z-1
      bzrlib/tests/test__chunks_to_lines.py test__chunks_to_line-20081211024848-6uc3mtuje8j14l60-2
      bzrlib/tests/test_fifo_cache.py test_fifo_cache.py-20081209212307-31ffjwvteyvmydnf-2
    modified:
      .bzrignore                     bzrignore-20050311232317-81f7b71efa2db11a
      Makefile                       Makefile-20050805140406-d96e3498bb61c5bb
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
      bzrlib/_dirstate_helpers_c.h   _dirstate_helpers_c.-20070802205935-hqo9yzuzjix271dd-1
      bzrlib/atomicfile.py           atomicfile.py-20050509044450-dbd24e6c564f7c66
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
      bzrlib/delta.py                delta.py-20050729221636-54cf14ef94783d0a
      bzrlib/diff.py                 diff.py-20050309040759-26944fbbf2ebbf36
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/foreign.py              foreign.py-20081112170002-olsxmandkk8qyfuq-1
      bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/inventory.py            inventory.py-20050309040759-6648b84ca2005b37
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/lru_cache.py            lru_cache.py-20070119165515-tlw203kuwh0id5gv-1
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/msgeditor.py            msgeditor.py-20050901111708-ef6d8de98f5d8f2f
      bzrlib/osutils.py              osutils.py-20050309040759-eeaff12fbf77ac86
      bzrlib/patiencediff.py         patiencediff.py-20070721205536-jz8gaykeb7xtampk-1
      bzrlib/push.py                 push.py-20080606021927-5fe39050e8xne9un-1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/shelf.py                prepare_shelf.py-20081005181341-n74qe6gu1e65ad4v-1
      bzrlib/shelf_ui.py             shelver.py-20081005210102-33worgzwrtdw0yrm-1
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/__init__.py __init__.py-20051128053524-eba30d8255e08dc3
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/blackbox/test_ls.py test_ls.py-20060712232047-0jraqpecwngee12y-1
      bzrlib/tests/blackbox/test_pull.py test_pull.py-20051201144907-64959364f629947f
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
      bzrlib/tests/blackbox/test_revision_info.py test_revision_info.py-20050917162600-21dab3877aa348d7
      bzrlib/tests/blackbox/test_tags.py test_tags.py-20070116132048-5h4qak2cm22jlb9e-1
      bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
      bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
      bzrlib/tests/interrepository_implementations/__init__.py __init__.py-20060220054744-baf49a1f88f17b1a
      bzrlib/tests/per_repository/__init__.py __init__.py-20060131092037-9564957a7d4a841b
      bzrlib/tests/per_repository/test_add_fallback_repository.py test_add_fallback_re-20080215040003-8w9n4ck9uqdxj18m-1
      bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
      bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/test_bzrdir.py    test_bzrdir.py-20060131065654-deba40eef51cf220
      bzrlib/tests/test_diff.py      testdiff.py-20050727164403-d1a3496ebb12e339
      bzrlib/tests/test_errors.py    test_errors.py-20060210110251-41aba2deddf936a8
      bzrlib/tests/test_graph.py     test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
      bzrlib/tests/test_http.py      testhttp.py-20051018020158-b2eef6e867c514d9
      bzrlib/tests/test_info.py      test_info.py-20070320150933-m0xxm1g7xi9v6noe-1
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_lru_cache.py test_lru_cache.py-20070119165535-hph6rk4h9rzy4180-1
      bzrlib/tests/test_msgeditor.py test_msgeditor.py-20051202041359-920315ec6011ee51
      bzrlib/tests/test_osutils.py   test_osutils.py-20051201224856-e48ee24c12182989
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
      bzrlib/tests/test_revisionspec.py testrevisionnamespaces.py-20050711050225-8b4af89e6b1efe84
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
      bzrlib/tests/test_shelf.py     test_prepare_shelf.p-20081005181341-n74qe6gu1e65ad4v-2
      bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
      bzrlib/tests/test_source.py    test_source.py-20051207061333-a58dea6abecc030d
      bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
      bzrlib/tests/tree_implementations/__init__.py __init__.py-20060717075546-420s7b0bj9hzeowi-2
      bzrlib/tests/workingtree_implementations/test_add.py test_add.py-20070226165239-4vo178spkrnhavc7-1
      bzrlib/tests/workingtree_implementations/test_basis_inventory.py test_basis_inventory.py-20051218151655-3650468941091309
      bzrlib/tests/workingtree_implementations/test_move.py test_move.py-20070225171927-mohn2vqj5fx7edc6-1
      bzrlib/tests/workingtree_implementations/test_rename_one.py test_rename_one.py-20070226161242-2d8ibdedl700jgio-1
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
      bzrlib/transport/__init__.py   transport.py-20050711165921-4978aa7ce1285ad5
      bzrlib/transport/decorator.py  decorator.py-20060402223305-e913a0f25319ab42
      bzrlib/transport/http/__init__.py http_transport.py-20050711212304-506c5fd1059ace96
      bzrlib/transport/http/_pycurl.py pycurlhttp.py-20060110060940-4e2a705911af77a6
      bzrlib/transport/http/_urllib.py _urlgrabber.py-20060113083826-0bbf7d992fbf090c
      bzrlib/transport/http/_urllib2_wrappers.py _urllib2_wrappers.py-20060913231729-ha9ugi48ktx481ao-1
      bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
      bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
      bzrlib/weave.py                knit.py-20050627021749-759c29984154256b
      bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
      bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
      bzrlib/xml4.py                 xml4.py-20050916091259-db5ab55e7e6ca324
      bzrlib/xml5.py                 xml5.py-20080328030717-t9guwinq8hom0ar3-1
      bzrlib/xml7.py                 xml7.py-20061029182747-d5tiiny21bvrd2jj-1
      bzrlib/xml8.py                 xml5.py-20050907032657-aac8f960815b66b1
      bzrlib/xml_serializer.py       xml.py-20050309040759-57d51586fdec365d
      doc/developers/HACKING.txt     HACKING-20050805200004-2a5dc975d870f78c
      doc/en/user-guide/organizing_branches.txt organizing_branches.-20071123154453-dk2mjhrg1vpjm5w2-3
      doc/en/user-guide/publishing_a_branch.txt publishing_a_branch.-20071123055134-k5x4ekduci2lbn36-2
      doc/en/user-guide/reusing_a_checkout.txt reusing_a_checkout.t-20071123055134-k5x4ekduci2lbn36-3
      doc/en/user-guide/svn_plugin.txt svn_plugin.txt-20080509065016-cjc90f46407vi9a0-2
      doc/en/user-guide/using_checkouts.txt using_checkouts.txt-20071123055134-k5x4ekduci2lbn36-4
      setup.py                       setup.py-20050314065409-02f8a0a6e3f9bc70
      tools/win32/build_release.py   build_release.py-20081105204355-2ghh5cv01v1x4rzz-1
    ------------------------------------------------------------
    revno: 3842.3.14
    revision-id: andrew.bennetts at canonical.com-20081212075837-5rmjp846gxxd1tvr
    parent: andrew.bennetts at canonical.com-20081209060456-g5yeuf0t3e2d2stt
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Fri 2008-12-12 18:58:37 +1100
    message:
      Small hacks to make 'bzr init bzr://host/foo; bzr push bzr://host/foo' in bzr.dev successfully use the insert_record_stream RPC.
    modified:
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
    ------------------------------------------------------------
    revno: 3842.3.13
    revision-id: andrew.bennetts at canonical.com-20081209060456-g5yeuf0t3e2d2stt
    parent: andrew.bennetts at canonical.com-20081209051453-ep6fojv6q31w9eyu
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Tue 2008-12-09 17:04:56 +1100
    message:
      Remove SmartServerVersionedFilesGetParentMap.
    modified:
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
    ------------------------------------------------------------
    revno: 3842.3.12
    revision-id: andrew.bennetts at canonical.com-20081209051453-ep6fojv6q31w9eyu
    parent: andrew.bennetts at canonical.com-20081209050615-4xps1j3z0sljfja5
    parent: andrew.bennetts at canonical.com-20081209051436-3vet9gjvh0rzgl9c
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Tue 2008-12-09 16:14:53 +1100
    message:
      Merge loom thread.
    ------------------------------------------------------------
    revno: 3842.3.11
    revision-id: andrew.bennetts at canonical.com-20081209050615-4xps1j3z0sljfja5
    parent: andrew.bennetts at canonical.com-20081209050414-kg71l0r87i66br79
    parent: pqm at pqm.ubuntu.com-20081209023452-12dbzcwzxrt1xee3
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Tue 2008-12-09 16:06:15 +1100
    message:
      Merge from bzr.dev.
    added:
      bzrlib/foreign.py              foreign.py-20081112170002-olsxmandkk8qyfuq-1
      bzrlib/tests/test_foreign.py   test_foreign.py-20081125004048-ywb901edgp9lluxo-1
      contrib/convert_to_1.9.py      convert_to_dev2.py-20081014130524-z1ydl3mq9b4ehlvv-1
      tools/win32/build_release.py   build_release.py-20081105204355-2ghh5cv01v1x4rzz-1
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzr                            bzr.py-20050313053754-5485f144c7006fa6
      bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
      bzrlib/_patiencediff_c.c       _patiencediff_c.c-20070721205602-q3imkipwlgagp3cy-1
      bzrlib/_readdir_pyx.pyx        readdir.pyx-20060609152855-rm6v321vuaqyh9tu-1
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/btree_index.py          index.py-20080624222253-p0x5f92uyh5hw734-7
      bzrlib/bugtracker.py           bugtracker.py-20070410073305-vu1vu1qosjurg8kb-1
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
      bzrlib/config.py               config.py-20051011043216-070c74f4e9e338e8
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/lockable_files.py       control_files.py-20051111201905-bb88546e799d669f
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/mutabletree.py          mutabletree.py-20060906023413-4wlkalbdpsxi2r4y-2
      bzrlib/python-compat.h         pythoncompat.h-20080924041409-9kvi0fgtuuqp743j-1
      bzrlib/registry.py             lazy_factory.py-20060809213415-2gfvqadtvdn0phtg-1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
      bzrlib/repofmt/weaverepo.py    presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/test_diff.py test_diff.py-20060110203741-aa99ac93e633d971
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
      bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
      bzrlib/tests/branch_implementations/test_sprout.py test_sprout.py-20070521151739-b8t8p7axw1h966ws-1
      bzrlib/tests/branch_implementations/test_stacking.py test_stacking.py-20080214020755-msjlkb7urobwly0f-1
      bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
      bzrlib/tests/commands/test_commit.py test_commit.py-20070913161801-ydrx2k5gmv7k7eiu-1
      bzrlib/tests/interrepository_implementations/test_fetch.py test_fetch.py-20080425213627-j60cjh782ufm83ry-1
      bzrlib/tests/per_repository/test_add_fallback_repository.py test_add_fallback_re-20080215040003-8w9n4ck9uqdxj18m-1
      bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
      bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/per_repository/test_revision.py testrevprops.py-20051013073044-92bc3c68302ce1bf
      bzrlib/tests/test_fetch.py     testfetch.py-20050825090644-f73e07e7dfb1765a
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
      bzrlib/tests/test_pack_repository.py test_pack_repository-20080801043947-eaw0e6h2gu75kwmy-1
      bzrlib/tests/test_permissions.py test_permissions.py-20051215004520-ccf475789c80e80c
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
      bzrlib/tests/test_revision.py  testrevision.py-20050804210559-46f5e1eb67b01289
      bzrlib/tests/test_sftp_transport.py testsftp.py-20051027032739-247570325fec7e7e
      bzrlib/tests/test_transport.py testtransport.py-20050718175618-e5cdb99f4555ddce
      bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
      bzrlib/tests/workingtree_implementations/test_parents.py test_set_parents.py-20060807231740-yicmnlci1mj8smu1-1
      bzrlib/transport/__init__.py   transport.py-20050711165921-4978aa7ce1285ad5
      bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
      bzrlib/upgrade.py              history2weaves.py-20050818063535-e7d319791c19a8b2
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
      bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
      bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
      doc/developers/ppa.txt         ppa.txt-20080722055539-606u7t2z32t3ae4w-1
    ------------------------------------------------------------
    revno: 3842.3.10
    revision-id: andrew.bennetts at canonical.com-20081209050414-kg71l0r87i66br79
    parent: andrew.bennetts at canonical.com-20081128101130-wonkakulwknf4mpa
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Tue 2008-12-09 16:04:14 +1100
    message:
      More comments.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
    ------------------------------------------------------------
    revno: 3842.3.9
    revision-id: andrew.bennetts at canonical.com-20081128101130-wonkakulwknf4mpa
    parent: andrew.bennetts at canonical.com-20081128094308-xwq1tcq5yg4zdkbk
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Fri 2008-11-28 21:11:30 +1100
    message:
      Backing up the stream so that we can fallback correctly.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
    ------------------------------------------------------------
    revno: 3842.3.8
    revision-id: andrew.bennetts at canonical.com-20081128094308-xwq1tcq5yg4zdkbk
    parent: andrew.bennetts at canonical.com-20081128094221-hvxddevo3vcvpvtn
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Fri 2008-11-28 20:43:08 +1100
    message:
      Remove some debugging cruft.
    modified:
      bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
    ------------------------------------------------------------
    revno: 3842.3.7
    revision-id: andrew.bennetts at canonical.com-20081128094221-hvxddevo3vcvpvtn
    parent: andrew.bennetts at canonical.com-20081128065802-f0ppt9qv0hpwoj0x
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Fri 2008-11-28 20:42:21 +1100
    message:
      Implement a simple fallback (that buffers the whole record stream) for dealing with older servers.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
    ------------------------------------------------------------
    revno: 3842.3.6
    revision-id: andrew.bennetts at canonical.com-20081128065802-f0ppt9qv0hpwoj0x
    parent: andrew.bennetts at canonical.com-20081126131717-h8y9qk87hfkjf963
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Fri 2008-11-28 17:58:02 +1100
    message:
      Tweak bencode.py to decode sequences as tuples, not lists.
    modified:
      bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
      bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
      bzrlib/util/bencode.py         bencode.py-20070220044742-sltr28q21w2wzlxi-1
    ------------------------------------------------------------
    revno: 3842.3.5
    revision-id: andrew.bennetts at canonical.com-20081126131717-h8y9qk87hfkjf963
    parent: andrew.bennetts at canonical.com-20081126113537-9vn1v1yo4gkxi05o
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Thu 2008-11-27 00:17:17 +1100
    message:
      Remove some debugging cruft, make more tests pass.
    modified:
      bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
      bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
    ------------------------------------------------------------
    revno: 3842.3.4
    revision-id: andrew.bennetts at canonical.com-20081126113537-9vn1v1yo4gkxi05o
    parent: andrew.bennetts at canonical.com-20081120104923-8rfafwxwzc4ujkj4
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Wed 2008-11-26 22:35:37 +1100
    message:
      TestStacking.test_fetch_copies_from_stacked_on now passes using the VersionedFile.insert_record_stream RPC; lots of debugging cruft needs removal though.
    added:
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
    modified:
      bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
      bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/util/bencode.py         bencode.py-20070220044742-sltr28q21w2wzlxi-1
    ------------------------------------------------------------
    revno: 3842.3.3
    revision-id: andrew.bennetts at canonical.com-20081120104923-8rfafwxwzc4ujkj4
    parent: andrew.bennetts at canonical.com-20081120104339-86nxvaaclh6fdyp4
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Thu 2008-11-20 21:49:23 +1100
    message:
      Remove RPC registration for VersionedFiles.get_parent_map, not Repository.get_parent_map.
    modified:
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
    ------------------------------------------------------------
    revno: 3842.3.2
    revision-id: andrew.bennetts at canonical.com-20081120104339-86nxvaaclh6fdyp4
    parent: andrew.bennetts at canonical.com-20081120103056-05g6c6nv30ceyxdx
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Thu 2008-11-20 21:43:39 +1100
    message:
      Revert the RemoteVersionedFiles.get_parent_map implementation, leaving just the skeleton of RemoteVersionedFiles.
    removed:
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
      bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
    ------------------------------------------------------------
    revno: 3842.3.1
    revision-id: andrew.bennetts at canonical.com-20081120103056-05g6c6nv30ceyxdx
    parent: pqm at pqm.ubuntu.com-20081120045730-d6ik8z5dfnzcnab6
    parent: andrew.bennetts at canonical.com-20080924015245-nm3rnompf1wux142
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: RemoteVersionedFile
    timestamp: Thu 2008-11-20 21:30:56 +1100
    message:
      Merge RemoteVersionedFiles class from hpss-push-rpc.
    added:
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
    modified:
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
      bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
    ------------------------------------------------------------
    revno: 3695.2.6
    revision-id: andrew.bennetts at canonical.com-20080924015245-nm3rnompf1wux142
    parent: andrew.bennetts at canonical.com-20080922093304-jm4ky0x20qssbenc
    parent: pqm at pqm.ubuntu.com-20080922180718-n946121e40ql2bb3
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: hpss-push-rpc
    timestamp: Wed 2008-09-24 11:52:45 +1000
    message:
      Merge from bzr.dev.
    renamed:
      bzrlib/tests/repository_implementations => bzrlib/tests/per_repository repository_implementations-20060131092037-ec97814745cc6128
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzr                            bzr.py-20050313053754-5485f144c7006fa6
      bzr.ico                        bzr.ico-20060629083000-q18ip0hk7lq55i4y-1
      bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bundle/__init__.py      changeset.py-20050513021216-b02ab57fb9738913
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/directory_service.py    directory_service.py-20080305221044-vr2mkvlsk8jypa2y-1
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/missing.py              missing.py-20050812153334-097f7097e2a8bcd1
      bzrlib/osutils.py              osutils.py-20050309040759-eeaff12fbf77ac86
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/smart/branch.py         branch.py-20061124031907-mzh3pla28r83r97f-1
      bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
      bzrlib/smart/medium.py         medium.py-20061103051856-rgu2huy59fkz902q-1
      bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/smart/server.py         server.py-20061110062051-chzu10y32vx8gvur-1
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/test_branch.py test_branch.py-20060524161337-noms9gmcwqqrfi8y-1
      bzrlib/tests/blackbox/test_export.py test_export.py-20051229024010-e6c26658e460fb1c
      bzrlib/tests/blackbox/test_init.py test_init.py-20060309032856-a292116204d86eb7
      bzrlib/tests/blackbox/test_remove_tree.py test_remove_tree.py-20061110192919-5j3xjciiaqbs2dvo-1
      bzrlib/tests/blackbox/test_switch.py test_switch.py-20071122111948-0c5en6uz92bwl76h-1
      bzrlib/tests/branch_implementations/test_break_lock.py test_break_lock.py-20060504111902-9aae411dbe9aadd2
      bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
      bzrlib/tests/per_repository/__init__.py __init__.py-20060131092037-9564957a7d4a841b
      bzrlib/tests/per_repository/helpers.py helpers.py-20070924032407-m460yl9j5gu5ju85-2
      bzrlib/tests/per_repository/test__generate_text_key_index.py test__generate_text_-20071114232121-00h9fd8qg8kjfa5k-1
      bzrlib/tests/per_repository/test_add_fallback_repository.py test_add_fallback_re-20080215040003-8w9n4ck9uqdxj18m-1
      bzrlib/tests/per_repository/test_break_lock.py test_break_lock.py-20060504111704-ee09a107f9f42e43
      bzrlib/tests/per_repository/test_check.py test_check.py-20070824124512-38g4d135gcqxo4zb-1
      bzrlib/tests/per_repository/test_check_reconcile.py test_broken.py-20070928125406-62236394w0jpbpd6-2
      bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
      bzrlib/tests/per_repository/test_fetch.py test_fetch.py-20070814052151-5cxha9slx4c93uog-1
      bzrlib/tests/per_repository/test_fileid_involved.py test_file_involved.py-20051215205901-728a172d1014daaa
      bzrlib/tests/per_repository/test_find_text_key_references.py test_find_text_key_r-20071114033605-v73bakal8x77qlfi-1
      bzrlib/tests/per_repository/test_get_parent_map.py test_get_parent_map.-20080421172708-x1z6ot341osr0jq1-1
      bzrlib/tests/per_repository/test_has_revisions.py test_has_revisions.p-20080111035443-xaupgdsx5fw1q54b-1
      bzrlib/tests/per_repository/test_has_same_location.py test_has_same_locati-20070807074648-2i2ah82fbe83iys7-1
      bzrlib/tests/per_repository/test_is_write_locked.py test_is_write_locked-20071012063748-vk062lmu683qgbc3-1
      bzrlib/tests/per_repository/test_iter_reverse_revision_history.py test_iter_reverse_re-20070217015036-spu7j5ggch7pbpyd-1
      bzrlib/tests/per_repository/test_pack.py test_pack.py-20070712120702-0c7585lh56p894mo-2
      bzrlib/tests/per_repository/test_reconcile.py test_reconcile.py-20060223022332-572ef70a3288e369
      bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/per_repository/test_revision.py testrevprops.py-20051013073044-92bc3c68302ce1bf
      bzrlib/tests/per_repository/test_statistics.py test_statistics.py-20070203082432-6738e8fl0mm7ikre-1
      bzrlib/tests/per_repository/test_write_group.py test_write_group.py-20070716105516-89n34xtogq5frn0m-1
      bzrlib/tests/per_repository_reference/__init__.py __init__.py-20080220025549-nnm2s80it1lvcwnc-2
      bzrlib/tests/test_annotate.py  test_annotate.py-20061213215015-sttc9agsxomls7q0-1
      bzrlib/tests/test_bundle.py    test.py-20050630184834-092aa401ab9f039c
      bzrlib/tests/test_directory_service.py test_directory_servi-20080305221044-vr2mkvlsk8jypa2y-2
      bzrlib/tests/test_missing.py   test_missing.py-20051212000028-694fa4f658a81f48
      bzrlib/tests/test_reconcile.py test_reconcile.py-20060225054842-50aa618584a86f26
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
      bzrlib/tests/test_sftp_transport.py testsftp.py-20051027032739-247570325fec7e7e
      bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
      bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
      bzrlib/tests/test_transport.py testtransport.py-20050718175618-e5cdb99f4555ddce
      bzrlib/tests/test_transport_implementations.py test_transport_implementations.py-20051227111451-f97c5c7d5c49fce7
      bzrlib/tests/tree_implementations/__init__.py __init__.py-20060717075546-420s7b0bj9hzeowi-2
      bzrlib/tests/tree_implementations/test_inv.py test_inv.py-20070312023226-0cdvk5uwhutis9vg-1
      bzrlib/tests/tree_implementations/test_test_trees.py test_tree_trees.py-20060720091921-3nwi5h21lf06vf5p-1
      bzrlib/tests/tree_implementations/test_tree.py test_tree.py-20061215160206-usu7lwcj8aq2n3br-1
      bzrlib/tests/workingtree_implementations/test_remove.py test_remove.py-20070413183901-rvnp85rtc0q0sclp-1
      bzrlib/tests/workingtree_implementations/test_rename_one.py test_rename_one.py-20070226161242-2d8ibdedl700jgio-1
      bzrlib/tests/workingtree_implementations/test_workingtree.py test_workingtree.py-20060203003124-817757d3e31444fb
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
      bzrlib/transport/__init__.py   transport.py-20050711165921-4978aa7ce1285ad5
      bzrlib/transport/local.py      local_transport.py-20050711165921-9b1f142bfe480c24
      bzrlib/transport/sftp.py       sftp.py-20051019050329-ab48ce71b7e32dfe
      bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
      bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
      doc/en/user-guide/http_smart_server.txt fastcgi.txt-20061005091552-rz8pva0olkxv0sd8-3
      profile_imports.py             profile_imports.py-20060618020306-k5uw80achysrokj9-1
      setup.py                       setup.py-20050314065409-02f8a0a6e3f9bc70
      tools/doc_generate/autodoc_man.py bzrman.py-20050601153041-0ff7f74de456d15e
    ------------------------------------------------------------
    revno: 3695.2.5
    revision-id: andrew.bennetts at canonical.com-20080922093304-jm4ky0x20qssbenc
    parent: andrew.bennetts at canonical.com-20080911002618-z1ngkakxitjfg9lx
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: hpss-push-rpc
    timestamp: Mon 2008-09-22 19:33:04 +1000
    message:
      More tests, and slightly simpler encoding of VersionedFiles.get_parent_map responses.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
    ------------------------------------------------------------
    revno: 3695.2.4
    revision-id: andrew.bennetts at canonical.com-20080911002618-z1ngkakxitjfg9lx
    parent: andrew.bennetts at canonical.com-20080909114054-m5kddq501jzmxqeo
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: hpss-push-rpc
    timestamp: Thu 2008-09-11 10:26:18 +1000
    message:
      Add a test that the client can interoperate with a server that does not support the VersionedFiles.get_parent_map RPC.
    modified:
      bzrlib/branchbuilder.py        branchbuilder.py-20070427022007-zlxpqz2lannhk6y8-1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
    ------------------------------------------------------------
    revno: 3695.2.3
    revision-id: andrew.bennetts at canonical.com-20080909114054-m5kddq501jzmxqeo
    parent: andrew.bennetts at canonical.com-20080908091136-4g73wcnla3h7lynq
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: hpss-push-rpc
    timestamp: Tue 2008-09-09 21:40:54 +1000
    message:
      Use a simple custom serialiser rather than bencode for VersionedFile.get_parent_map results.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
    ------------------------------------------------------------
    revno: 3695.2.2
    revision-id: andrew.bennetts at canonical.com-20080908091136-4g73wcnla3h7lynq
    parent: andrew.bennetts at canonical.com-20080908055218-22ytu21ra0sid2kk
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: hpss-push-rpc
    timestamp: Mon 2008-09-08 19:11:36 +1000
    message:
      Rough cut of implementing and using a VersionedFiles.get_parent_map RPC.
    added:
      bzrlib/smart/versionedfiles.py versionedfiles.py-20080908091044-zk43rd2m1p521wlq-1
    modified:
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
      bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
      bzrlib/smart/protocol.py       protocol.py-20061108035435-ot0lstk2590yqhzr-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
    ------------------------------------------------------------
    revno: 3695.2.1
    revision-id: andrew.bennetts at canonical.com-20080908055218-22ytu21ra0sid2kk
    parent: pqm at pqm.ubuntu.com-20080906102539-ss1fkx2csdcalqlc
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: hpss-push-rpc
    timestamp: Mon 2008-09-08 15:52:18 +1000
    message:
      Define and use a simple RemoteVersionedFiles class that delegates to the real VF object for everything.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
=== modified file 'bzrlib/smart/client.py'
--- a/bzrlib/smart/client.py	2008-09-24 13:46:44 +0000
+++ b/bzrlib/smart/client.py	2009-01-12 06:17:23 +0000
@@ -37,7 +37,7 @@
             self._headers = dict(headers)
 
     def _send_request(self, protocol_version, method, args, body=None,
-                      readv_body=None):
+                      readv_body=None, body_stream=None):
         encoder, response_handler = self._construct_protocol(
             protocol_version)
         encoder.set_headers(self._headers)
@@ -45,10 +45,17 @@
             if readv_body is not None:
                 raise AssertionError(
                     "body and readv_body are mutually exclusive.")
+            if body_stream is not None:
+                raise AssertionError(
+                    "body and body_stream are mutually exclusive.")
             encoder.call_with_body_bytes((method, ) + args, body)
         elif readv_body is not None:
-            encoder.call_with_body_readv_array((method, ) + args,
-                    readv_body)
+            if body_stream is not None:
+                raise AssertionError(
+                    "readv_body and body_stream are mutually exclusive.")
+            encoder.call_with_body_readv_array((method, ) + args, readv_body)
+        elif body_stream is not None:
+            encoder.call_with_body_stream((method, ) + args, body_stream)
         else:
             encoder.call(method, *args)
         return response_handler
@@ -61,12 +68,12 @@
             hook(params)
             
     def _call_and_read_response(self, method, args, body=None, readv_body=None,
-            expect_response_body=True):
+            body_stream=None, expect_response_body=True):
         self._run_call_hooks(method, args, body, readv_body)
         if self._medium._protocol_version is not None:
             response_handler = self._send_request(
                 self._medium._protocol_version, method, args, body=body,
-                readv_body=readv_body)
+                readv_body=readv_body, body_stream=body_stream)
             return (response_handler.read_response_tuple(
                         expect_body=expect_response_body),
                     response_handler)
@@ -77,7 +84,7 @@
                     self._medium._remember_remote_is_before((1, 6))
                 response_handler = self._send_request(
                     protocol_version, method, args, body=body,
-                    readv_body=readv_body)
+                    readv_body=readv_body, body_stream=body_stream)
                 try:
                     response_tuple = response_handler.read_response_tuple(
                         expect_body=expect_response_body)
@@ -165,6 +172,12 @@
                 args[0], args[1:], readv_body=body, expect_response_body=True)
         return (response, response_handler)
 
+    def call_with_body_stream(self, args, stream):
+        response, response_handler = self._call_and_read_response(
+                args[0], args[1:], body_stream=stream,
+                expect_response_body=False)
+        return (response, response_handler)
+
     def remote_path_from_transport(self, transport):
         """Convert transport into a path suitable for using in a request.
         

=== modified file 'bzrlib/smart/message.py'
--- a/bzrlib/smart/message.py	2008-10-01 06:54:56 +0000
+++ b/bzrlib/smart/message.py	2009-01-27 07:08:25 +0000
@@ -84,13 +84,22 @@
     "Conventional" is used in the sense described in
     doc/developers/network-protocol.txt: a simple message with arguments and an
     optional body.
+
+    Possible states:
+     * args: expecting args
+     * body: expecting body (terminated by receiving a post-body status)
+     * error: expecting post-body error
+     * end: expecting end of message
+     * nothing: finished
     """
 
     def __init__(self, request_handler, responder):
         MessageHandler.__init__(self)
         self.request_handler = request_handler
         self.responder = responder
-        self.args_received = False
+        self.expecting = 'args'
+        self._should_finish_body = False
+        self._response_sent = False
 
     def protocol_error(self, exception):
         if self.responder.response_sent:
@@ -100,30 +109,62 @@
         self.responder.send_error(exception)
 
     def byte_part_received(self, byte):
-        raise errors.SmartProtocolError(
-            'Unexpected message part: byte(%r)' % (byte,))
+        if self.expecting == 'body':
+            if byte == 'S':
+                # Success.  Nothing more to come except the end of message.
+                self.expecting = 'end'
+            elif byte == 'E':
+                # Error.  Expect an error structure.
+                self.expecting = 'error'
+            else:
+                raise errors.SmartProtocolError(
+                    'Non-success status byte in request body: %r' % (byte,))
+        else:
+            raise errors.SmartProtocolError(
+                'Unexpected message part: byte(%r)' % (byte,))
 
     def structure_part_received(self, structure):
-        if self.args_received:
+        if self.expecting == 'args':
+            self._args_received(structure)
+        elif self.expecting == 'error':
+            self._error_received(structure)
+        else:
             raise errors.SmartProtocolError(
                 'Unexpected message part: structure(%r)' % (structure,))
-        self.args_received = True
-        self.request_handler.dispatch_command(structure[0], structure[1:])
+
+    def _args_received(self, args):
+        self.expecting = 'body'
+        self.request_handler.dispatch_command(args[0], args[1:])
         if self.request_handler.finished_reading:
+            self._response_sent = True
             self.responder.send_response(self.request_handler.response)
+            self.expecting = 'end'
+
+    def _error_received(self, error_args):
+        self.expecting = 'end'
+        self.request_handler.post_body_error_received(error_args)
 
     def bytes_part_received(self, bytes):
-        # Note that there's no intrinsic way to distinguish a monolithic body
-        # from a chunk stream.  A request handler knows which it is expecting
-        # (once the args have been received), so it should be able to do the
-        # right thing.
-        self.request_handler.accept_body(bytes)
-        self.request_handler.end_of_body()
+        if self.expecting == 'body':
+            self._should_finish_body = True
+            self.request_handler.accept_body(bytes)
+        else:
+            raise errors.SmartProtocolError(
+                'Unexpected message part: bytes(%r)' % (bytes,))
+
+    def end_received(self):
+        if self.expecting not in ['body', 'end']:
+            raise errors.SmartProtocolError(
+                'End of message received prematurely (while expecting %s)'
+                % (self.expecting,))
+        self.expecting = 'nothing'
+        self.request_handler.end_received()
         if not self.request_handler.finished_reading:
             raise errors.SmartProtocolError(
-                "Conventional request body was received, but request handler "
-                "has not finished reading.")
-        self.responder.send_response(self.request_handler.response)
+                "Complete conventional request was received, but request "
+                "handler has not finished reading.")
+        if not self._response_sent:
+            self.responder.send_response(self.request_handler.response)
 
 
 class ResponseHandler(object):
@@ -202,10 +243,9 @@
         self._bytes_parts.append(bytes)
 
     def structure_part_received(self, structure):
-        if type(structure) is not list:
+        if type(structure) is not tuple:
             raise errors.SmartProtocolError(
                 'Args structure is not a sequence: %r' % (structure,))
-        structure = tuple(structure)
         if not self._body_started:
             if self.args is not None:
                 raise errors.SmartProtocolError(

=== modified file 'bzrlib/smart/protocol.py'
--- a/bzrlib/smart/protocol.py	2008-09-17 07:18:20 +0000
+++ b/bzrlib/smart/protocol.py	2009-02-02 05:56:34 +0000
@@ -29,7 +29,7 @@
 from bzrlib import errors
 from bzrlib.smart import message, request
 from bzrlib.trace import log_exception_quietly, mutter
-from bzrlib.util.bencode import bdecode, bencode
+from bzrlib.util.bencode import bdecode_as_tuple, bencode
 
 
 # Protocol version strings.  These are sent as prefixes of bzr requests and
@@ -655,6 +655,14 @@
         if 'hpss' in debug.debug_flags:
             mutter('              %d bytes in readv request', len(readv_bytes))
         self._last_verb = args[0]
+    
+    def call_with_body_stream(self, args, stream):
+        # Protocols v1 and v2 don't support body streams.  So it's safe to
+        # assume that a v1/v2 server doesn't support whatever method we're
+        # trying to call with a body stream.
+        self._request.finished_writing()
+        self._request.finished_reading()
+        raise errors.UnknownSmartMethod(args[0])
 
     def cancel_read_body(self):
         """After expecting a body, a response code may indicate one otherwise.
@@ -931,7 +939,7 @@
     def _extract_prefixed_bencoded_data(self):
         prefixed_bytes = self._extract_length_prefixed_bytes()
         try:
-            decoded = bdecode(prefixed_bytes)
+            decoded = bdecode_as_tuple(prefixed_bytes)
         except ValueError:
             raise errors.SmartProtocolError(
                 'Bytes %r not bencoded' % (prefixed_bytes,))
@@ -1100,6 +1108,9 @@
         self._write_func(struct.pack('!L', len(bytes)))
         self._write_func(bytes)
 
+    def _write_chunked_body_start(self):
+        self._write_func('oC')
+
     def _write_error_status(self):
         self._write_func('oE')
 
@@ -1217,3 +1228,30 @@
         self._write_end()
         self._medium_request.finished_writing()
 
+    def call_with_body_stream(self, args, stream):
+        if 'hpss' in debug.debug_flags:
+            mutter('hpss call w/body stream: %r', args)
+            path = getattr(self._medium_request._medium, '_path', None)
+            if path is not None:
+                mutter('                  (to %s)', path)
+            self._request_start_time = time.time()
+        self._write_protocol_version()
+        self._write_headers(self._headers)
+        self._write_structure(args)
+        # TODO: notice if the server has sent an early error reply before we
+        #       have finished sending the stream.  We would notice at the end
+        #       anyway, but if the medium can deliver it early then it's good
+        #       to short-circuit the whole request...
+        try:
+            for part in stream:
+                self._write_prefixed_body(part)
+                self.flush()
+        except Exception:
+            # Iterating the stream failed.  Cleanly abort the request.
+            self._write_error_status()
+            # Currently the client unconditionally sends ('error',) as the
+            # error args.
+            self._write_structure(('error',))
+        self._write_end()
+        self._medium_request.finished_writing()
+

=== modified file 'bzrlib/smart/request.py'
--- a/bzrlib/smart/request.py	2008-10-30 03:47:59 +0000
+++ b/bzrlib/smart/request.py	2009-01-27 07:48:55 +0000
@@ -70,6 +70,7 @@
             if not root_client_path.endswith('/'):
                 root_client_path += '/'
         self._root_client_path = root_client_path
+        self._body_chunks = []
 
     def _check_enabled(self):
         """Raises DisabledMethod if this method is disabled."""
@@ -110,11 +111,13 @@
 
         The do() method is still called, and must have returned None.
         """
-        raise NotImplementedError(self.do_chunk)
+        self._body_chunks.append(chunk_bytes)
 
     def do_end(self):
         """Called when the end of the request has been received."""
-        pass
+        body_bytes = ''.join(self._body_chunks)
+        self._body_chunks = None
+        return self.do_body(body_bytes)
     
     def translate_client_path(self, client_path):
         """Translate a path received from a network client into a local
@@ -229,25 +232,17 @@
         self._backing_transport = backing_transport
         self._root_client_path = root_client_path
         self._commands = commands
-        self._body_bytes = ''
         self.response = None
         self.finished_reading = False
         self._command = None
 
     def accept_body(self, bytes):
         """Accept body data."""
-
-        # TODO: This should be overriden for each command that desired body data
-        # to handle the right format of that data, i.e. plain bytes, a bundle,
-        # etc.  The deserialisation into that format should be done in the
-        # Protocol object.
-
-        # default fallback is to accumulate bytes.
-        self._body_bytes += bytes
+        self._run_handler_code(self._command.do_chunk, (bytes,), {})
         
     def end_of_body(self):
         """No more body data will be received."""
-        self._run_handler_code(self._command.do_body, (self._body_bytes,), {})
+        self._run_handler_code(self._command.do_end, (), {})
         # cannot read after this.
         self.finished_reading = True
 
@@ -338,18 +333,13 @@
         self._command = command(self._backing_transport)
         self._run_handler_code(self._command.execute, args, {})
 
-    def prefixed_body_received(self, body_bytes):
-        """No more body data will be received."""
-        self._run_handler_code(self._command.do_body, (body_bytes,), {})
-        # cannot read after this.
-        self.finished_reading = True
-
-    def body_chunk_received(self, chunk_bytes):
-        self._run_handler_code(self._command.do_chunk, (chunk_bytes,), {})
-
     def end_received(self):
         self._run_handler_code(self._command.do_end, (), {})
 
+    def post_body_error_received(self, error_args):
+        # Just a no-op at the moment.
+        pass
+
 
 class HelloRequest(SmartServerRequest):
     """Answer a version request with the highest protocol version this server

=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py	2008-12-03 05:09:44 +0000
+++ b/bzrlib/tests/test_remote.py	2009-01-27 07:48:55 +0000
@@ -253,6 +253,14 @@
         self.expecting_body = True
         return result[1], FakeProtocol(result[2], self)
 
+    def call_with_body_stream(self, args, stream):
+        # Explicitly consume the stream before checking for an error, because
+        # that's what happens a real medium.
+        stream = list(stream)
+        self._check_call(args[0], args[1:])
+        self._calls.append(('call_with_body_stream', args[0], args[1:], stream))
+        return self._get_next_response()[1]
+
 
 class FakeMedium(medium.SmartClientMedium):
 

=== modified file 'bzrlib/tests/test_smart_transport.py'
--- a/bzrlib/tests/test_smart_transport.py	2008-12-12 14:33:13 +0000
+++ b/bzrlib/tests/test_smart_transport.py	2009-01-27 05:04:43 +0000
@@ -1489,12 +1489,12 @@
         smart_protocol._has_dispatched = True
         smart_protocol.request = _mod_request.SmartServerRequestHandler(
             None, _mod_request.request_handlers, '/')
-        class FakeCommand(object):
-            def do_body(cmd, body_bytes):
+        class FakeCommand(_mod_request.SmartServerRequest):
+            def do_body(self_cmd, body_bytes):
                 self.end_received = True
                 self.assertEqual('abcdefg', body_bytes)
                 return _mod_request.SuccessfulSmartServerResponse(('ok', ))
-        smart_protocol.request._command = FakeCommand()
+        smart_protocol.request._command = FakeCommand(None)
         # Call accept_bytes to make sure that internal state like _body_decoder
         # is initialised.  This test should probably be given a clearer
         # interface to work with that will not cause this inconsistency.
@@ -2358,7 +2358,7 @@
             '\0\0\0\x07' # length prefix
             'l3:ARGe' # ['ARG']
             )
-        self.assertEqual([('structure', ['ARG'])], event_log)
+        self.assertEqual([('structure', ('ARG',))], event_log)
 
     def test_decode_multiple_bytes(self):
         """The protocol can decode a multiple 'bytes' message parts."""
@@ -2375,7 +2375,7 @@
             [('bytes', 'first'), ('bytes', 'second')], event_log)
 
 
-class TestConventionalResponseHandler(tests.TestCase):
+class TestConventionalResponseHandlerBodyStream(tests.TestCase):
 
     def make_response_handler(self, response_bytes):
         from bzrlib.smart.message import ConventionalResponseHandler
@@ -2392,7 +2392,7 @@
             protocol_decoder, medium_request)
         return response_handler
 
-    def test_body_stream_interrupted_by_error(self):
+    def test_interrupted_by_error(self):
         interrupted_body_stream = (
             'oS' # successful response
             's\0\0\0\x02le' # empty args
@@ -2409,7 +2409,7 @@
         exc = self.assertRaises(errors.ErrorFromSmartServer, stream.next)
         self.assertEqual(('error', 'abc'), exc.error_tuple)
 
-    def test_body_stream_interrupted_by_connection_lost(self):
+    def test_interrupted_by_connection_lost(self):
         interrupted_body_stream = (
             'oS' # successful response
             's\0\0\0\x02le' # empty args
@@ -2427,6 +2427,83 @@
         self.assertRaises(
             errors.ConnectionReset, response_handler.read_body_bytes)
 
+    def test_multiple_bytes_parts(self):
+        multiple_bytes_parts = (
+            'oS' # successful response
+            's\0\0\0\x02le' # empty args
+            'b\0\0\0\x0bSome bytes\n' # some bytes
+            'b\0\0\0\x0aMore bytes' # more bytes
+            'e' # message end
+            )
+        response_handler = self.make_response_handler(multiple_bytes_parts)
+        self.assertEqual(
+            'Some bytes\nMore bytes', response_handler.read_body_bytes())
+        response_handler = self.make_response_handler(multiple_bytes_parts)
+        self.assertEqual(
+            ['Some bytes\n', 'More bytes'],
+            list(response_handler.read_streamed_body()))
+
+
+class FakeResponder(object):
+
+    response_sent = False
+
+    def send_error(self, exc):
+        raise exc
+
+    def send_response(self, response):
+        pass
+
+
+class TestConventionalRequestHandlerBodyStream(tests.TestCase):
+    """Tests for ConventionalRequestHandler's handling of request bodies."""
+
+    def make_request_handler(self, request_bytes):
+        """Make a ConventionalRequestHandler for the given bytes using test
+        doubles for the request_handler and the responder.
+        """
+        from bzrlib.smart.message import ConventionalRequestHandler
+        request_handler = InstrumentedRequestHandler()
+        request_handler.response = _mod_request.SuccessfulSmartServerResponse(('arg', 'arg'))
+        responder = FakeResponder()
+        message_handler = ConventionalRequestHandler(request_handler, responder)
+        protocol_decoder = protocol.ProtocolThreeDecoder(message_handler)
+        # put decoder in desired state (waiting for message parts)
+        protocol_decoder.state_accept = protocol_decoder._state_accept_expecting_message_part
+        protocol_decoder.accept_bytes(request_bytes)
+        return request_handler
+
+    def test_multiple_bytes_parts(self):
+        """Each bytes part triggers a call to the request_handler's
+        accept_body method.
+        """
+        multiple_bytes_parts = (
+            's\0\0\0\x07l3:fooe' # args
+            'b\0\0\0\x0bSome bytes\n' # some bytes
+            'b\0\0\0\x0aMore bytes' # more bytes
+            'e' # message end
+            )
+        request_handler = self.make_request_handler(multiple_bytes_parts)
+        accept_body_calls = [
+            call_info[1] for call_info in request_handler.calls
+            if call_info[0] == 'accept_body']
+        self.assertEqual(
+            ['Some bytes\n', 'More bytes'], accept_body_calls)
+
+    def test_error_flag_after_body(self):
+        body_then_error = (
+            's\0\0\0\x07l3:fooe' # request args
+            'b\0\0\0\x0bSome bytes\n' # some bytes
+            'b\0\0\0\x0aMore bytes' # more bytes
+            'oE' # error flag
+            's\0\0\0\x07l3:bare' # error args
+            'e' # message end
+            )
+        request_handler = self.make_request_handler(body_then_error)
+        self.assertEqual(
+            [('post_body_error_received', ('bar',)), ('end_received',)],
+            request_handler.calls[-2:])
+
 
 class TestMessageHandlerErrors(tests.TestCase):
     """Tests for v3 that unrecognised (but well-formed) requests/responses are
@@ -2476,18 +2553,27 @@
 
     def __init__(self):
         self.calls = []
-
-    def body_chunk_received(self, chunk_bytes):
-        self.calls.append(('body_chunk_received', chunk_bytes))
+        self.finished_reading = False
 
     def no_body_received(self):
         self.calls.append(('no_body_received',))
 
-    def prefixed_body_received(self, body_bytes):
-        self.calls.append(('prefixed_body_received', body_bytes))
-
     def end_received(self):
         self.calls.append(('end_received',))
+        self.finished_reading = True
+
+    def dispatch_command(self, cmd, args):
+        self.calls.append(('dispatch_command', cmd, args))
+
+    def accept_body(self, bytes):
+        self.calls.append(('accept_body', bytes))
+
+    def end_of_body(self):
+        self.calls.append(('end_of_body',))
+        self.finished_reading = True
+
+    def post_body_error_received(self, error_args):
+        self.calls.append(('post_body_error_received', error_args))
 
 
 class StubRequest(object):
@@ -2529,7 +2615,7 @@
         # The message handler has been invoked with all the parts of the
         # trivial response: empty headers, status byte, no args, end.
         self.assertEqual(
-            [('headers', {}), ('byte', 'S'), ('structure', []), ('end',)],
+            [('headers', {}), ('byte', 'S'), ('structure', ()), ('end',)],
             response_handler.event_log)
 
     def test_incomplete_message(self):
@@ -2643,6 +2729,63 @@
         self.assertEqual(
             ['accept_bytes', 'finished_writing'], medium_request.calls)
 
+    def test_call_with_body_stream_smoke_test(self):
+        """A smoke test for ProtocolThreeRequester.call_with_body_stream.
+
+        This test checks that a particular simple invocation of
+        call_with_body_stream emits the correct bytes for that invocation.
+        """
+        requester, output = self.make_client_encoder_and_output()
+        requester.set_headers({'header name': 'header value'})
+        stream = ['chunk 1', 'chunk two']
+        requester.call_with_body_stream(('one arg',), stream)
+        self.assertEquals(
+            'bzr message 3 (bzr 1.6)\n' # protocol version
+            '\x00\x00\x00\x1fd11:header name12:header valuee' # headers
+            's\x00\x00\x00\x0bl7:one arge' # args
+            'b\x00\x00\x00\x07chunk 1' # a prefixed body chunk
+            'b\x00\x00\x00\x09chunk two' # a prefixed body chunk
+            'e', # end
+            output.getvalue())
+
+    def test_call_with_body_stream_empty_stream(self):
+        """call_with_body_stream with an empty stream."""
+        requester, output = self.make_client_encoder_and_output()
+        requester.set_headers({})
+        stream = []
+        requester.call_with_body_stream(('one arg',), stream)
+        self.assertEquals(
+            'bzr message 3 (bzr 1.6)\n' # protocol version
+            '\x00\x00\x00\x02de' # headers
+            's\x00\x00\x00\x0bl7:one arge' # args
+            # no body chunks
+            'e', # end
+            output.getvalue())
+
+    def test_call_with_body_stream_error(self):
+        """call_with_body_stream will abort the streamed body with an
+        error if the stream raises an error during iteration.
+        
+        The resulting request will still be a complete message.
+        """
+        requester, output = self.make_client_encoder_and_output()
+        requester.set_headers({})
+        def stream_that_fails():
+            yield 'aaa'
+            yield 'bbb'
+            raise Exception('Boom!')
+        requester.call_with_body_stream(('one arg',), stream_that_fails())
+        self.assertEquals(
+            'bzr message 3 (bzr 1.6)\n' # protocol version
+            '\x00\x00\x00\x02de' # headers
+            's\x00\x00\x00\x0bl7:one arge' # args
+            'b\x00\x00\x00\x03aaa' # body
+            'b\x00\x00\x00\x03bbb' # more body
+            'oE' # error flag
+            's\x00\x00\x00\x09l5:errore' # error args: ('error',)
+            'e', # end
+            output.getvalue())
+
 
 class StubMediumRequest(object):
     """A stub medium request that tracks the number of times accept_bytes is




More information about the bazaar-commits mailing list