Merge lp:~jderose/ubuntu/saucy/couchdb/1.4.0 into lp:ubuntu/saucy/couchdb
- Saucy (13.10)
- 1.4.0
- Merge into saucy
Status: | Merged |
---|---|
Merge reported by: | Robie Basak |
Merged at revision: | not available |
Proposed branch: | lp:~jderose/ubuntu/saucy/couchdb/1.4.0 |
Merge into: | lp:ubuntu/saucy/couchdb |
Diff against target: |
173949 lines (+110026/-36696) 496 files modified
.pc/applied-patches (+0/-8) .pc/couchdb_own_rundir.patch/etc/init/couchdb.tpl.in (+0/-156) .pc/couchdb_sighup.patch/bin/couchdb.tpl.in (+0/-335) .pc/force-reload.patch/etc/init/couchdb.tpl.in (+0/-156) .pc/improve_parsing_of_mochiweb_relative_paths.patch/src/mochiweb/mochiweb_util.erl (+0/-973) .pc/improve_script_url_validation.patch/share/www/script/couch_test_runner.js (+0/-472) .pc/include_a_comment_before_jsonp_output.patch/src/couchdb/couch_httpd.erl (+0/-1081) .pc/logrotate_as_couchdb.patch/etc/logrotate.d/couchdb.tpl.in (+0/-9) .pc/wait_for_couchdb_stop.patch/etc/init/couchdb.tpl.in (+0/-157) AUTHORS (+6/-0) BUGS (+5/-3) CHANGES (+0/-874) DEVELOPERS (+128/-22) INSTALL (+171/-35) INSTALL.Unix (+80/-44) INSTALL.Windows (+72/-21) LICENSE (+489/-12) Makefile.am (+63/-59) Makefile.in (+329/-188) NEWS (+0/-418) NOTICE (+98/-10) README (+0/-83) README.rst (+95/-0) THANKS (+55/-4) acinclude.m4 (+1/-1) aclocal.m4 (+962/-140) bin/Makefile.am (+59/-30) bin/Makefile.in (+212/-140) bin/couch-config.tpl.in (+1/-1) bin/couchdb.1 (+2/-2) bin/couchdb.bat.tpl.in (+1/-1) bin/couchdb.tpl.in (+34/-5) build-aux/config.guess (+343/-293) build-aux/config.sub (+294/-103) build-aux/depcomp (+207/-83) build-aux/dist-error (+28/-0) build-aux/install-sh (+141/-121) build-aux/ltmain.sh (+1640/-749) build-aux/missing (+29/-65) build-aux/sphinx-build (+67/-0) build-aux/sphinx-touch (+24/-0) config.h.in (+48/-7) configure (+8546/-8152) configure.ac (+356/-214) debian/README.Debian (+0/-26) debian/README.source (+0/-20) debian/changelog (+41/-0) debian/compat (+1/-1) debian/control (+39/-19) debian/couchdb-bin.install (+4/-1) debian/couchdb-bin.postrm (+0/-16) debian/couchdb-common.install (+3/-0) debian/couchdb.install (+0/-2) debian/couchdb.lintian-overrides (+2/-1) debian/couchdb.postinst (+6/-0) debian/couchdb.postrm (+0/-5) debian/couchdb.upstart (+19/-0) debian/patches/couchdb_own_rundir.patch (+0/-20) debian/patches/couchdb_sighup.patch (+0/-22) debian/patches/force-reload.patch (+0/-21) debian/patches/improve_parsing_of_mochiweb_relative_paths.patch (+0/-40) debian/patches/improve_script_url_validation.patch (+0/-26) debian/patches/include_a_comment_before_jsonp_output.patch (+0/-20) debian/patches/logrotate_as_couchdb.patch (+0/-16) debian/patches/series (+0/-8) debian/patches/wait_for_couchdb_stop.patch (+0/-30) debian/rules (+20/-51) debian/watch (+1/-1) etc/Makefile.in (+218/-96) etc/couchdb/Makefile.am (+10/-3) etc/couchdb/Makefile.in (+122/-40) etc/couchdb/default.ini.tpl.in (+55/-12) etc/couchdb/local.ini (+13/-4) etc/default/Makefile.in (+76/-24) etc/init/Makefile.in (+76/-24) etc/init/couchdb.tpl.in (+6/-15) etc/launchd/Makefile.in (+76/-24) etc/logrotate.d/Makefile.in (+76/-24) etc/logrotate.d/couchdb.tpl.in (+0/-2) etc/windows/Makefile.in (+76/-24) etc/windows/couchdb.iss.tpl (+8/-4) license.skip (+59/-36) m4/ac_check_curl.m4 (+0/-69) m4/ac_check_icu.m4 (+0/-74) m4/libtool.m4 (+762/-355) m4/ltversion.m4 (+6/-6) m4/pkg.m4 (+0/-157) share/Makefile.am (+20/-1) share/Makefile.in (+408/-100) share/doc/Makefile.am (+14/-0) share/doc/Makefile.in (+644/-0) share/doc/build/Makefile.am (+329/-0) share/doc/build/Makefile.in (+752/-0) share/doc/build/html/_sources/api-basics.txt (+463/-0) share/doc/build/html/_sources/api/authn.txt (+41/-0) share/doc/build/html/_sources/api/configuration.txt (+297/-0) share/doc/build/html/_sources/api/database.txt (+1471/-0) share/doc/build/html/_sources/api/design.txt (+1264/-0) share/doc/build/html/_sources/api/documents.txt (+973/-0) share/doc/build/html/_sources/api/local.txt (+169/-0) share/doc/build/html/_sources/api/misc.txt (+867/-0) share/doc/build/html/_sources/api/reference.txt (+42/-0) share/doc/build/html/_sources/changelog.txt (+1489/-0) share/doc/build/html/_sources/changes.txt (+227/-0) share/doc/build/html/_sources/config_reference.txt (+330/-0) share/doc/build/html/_sources/configuring.txt (+629/-0) share/doc/build/html/_sources/contributing.txt (+167/-0) share/doc/build/html/_sources/ddocs.txt (+751/-0) share/doc/build/html/_sources/index.txt (+46/-0) share/doc/build/html/_sources/intro.txt (+309/-0) share/doc/build/html/_sources/json-structure.txt (+825/-0) share/doc/build/html/_sources/query-servers.txt (+436/-0) share/doc/build/html/_sources/replication.txt (+95/-0) share/doc/build/html/_sources/replicator.txt (+383/-0) share/doc/build/html/_static/basic.css (+540/-0) share/doc/build/html/_static/default.css (+256/-0) share/doc/build/html/_static/doctools.js (+247/-0) share/doc/build/html/_static/jquery.js (+154/-0) share/doc/build/html/_static/pygments.css (+62/-0) share/doc/build/html/_static/rtd.css (+795/-0) share/doc/build/html/_static/searchtools.js (+560/-0) share/doc/build/html/_static/sidebar.js (+151/-0) share/doc/build/html/_static/underscore.js (+23/-0) share/doc/build/html/_static/websupport.js (+808/-0) share/doc/build/html/api-basics.html (+556/-0) share/doc/build/html/api/authn.html (+222/-0) share/doc/build/html/api/configuration.html (+467/-0) share/doc/build/html/api/database.html (+1646/-0) share/doc/build/html/api/design.html (+1384/-0) share/doc/build/html/api/documents.html (+1136/-0) share/doc/build/html/api/local.html (+363/-0) share/doc/build/html/api/misc.html (+1222/-0) share/doc/build/html/api/reference.html (+273/-0) share/doc/build/html/changelog.html (+2043/-0) share/doc/build/html/changes.html (+414/-0) share/doc/build/html/config_reference.html (+743/-0) share/doc/build/html/configuring.html (+682/-0) share/doc/build/html/ddocs.html (+976/-0) share/doc/build/html/genindex.html (+360/-0) share/doc/build/html/index.html (+316/-0) share/doc/build/html/intro.html (+423/-0) share/doc/build/html/json-structure.html (+1278/-0) share/doc/build/html/query-servers.html (+739/-0) share/doc/build/html/replication.html (+247/-0) share/doc/build/html/replicator.html (+503/-0) share/doc/build/html/search.html (+177/-0) share/doc/build/html/searchindex.js (+1/-0) share/doc/build/texinfo/CouchDB.info (+16106/-0) share/doc/src/api-basics.rst (+463/-0) share/doc/src/api/authn.rst (+41/-0) share/doc/src/api/configuration.rst (+297/-0) share/doc/src/api/database.rst (+1471/-0) share/doc/src/api/design.rst (+1264/-0) share/doc/src/api/documents.rst (+973/-0) share/doc/src/api/local.rst (+169/-0) share/doc/src/api/misc.rst (+867/-0) share/doc/src/api/reference.rst (+42/-0) share/doc/src/changelog.rst (+1489/-0) share/doc/src/changes.rst (+227/-0) share/doc/src/conf.py (+88/-0) share/doc/src/config_reference.rst (+330/-0) share/doc/src/configuring.rst (+629/-0) share/doc/src/contributing.rst (+167/-0) share/doc/src/ddocs.rst (+751/-0) share/doc/src/index.rst (+46/-0) share/doc/src/intro.rst (+309/-0) share/doc/src/json-structure.rst (+825/-0) share/doc/src/query-servers.rst (+436/-0) share/doc/src/replication.rst (+95/-0) share/doc/src/replicator.rst (+383/-0) share/doc/static/rtd.css (+795/-0) share/doc/templates/help.html (+24/-0) share/doc/templates/searchbox.html (+31/-0) share/doc/templates/utilities.html (+22/-0) share/server/filter.js (+1/-1) share/server/loop.js (+5/-3) share/server/render.js (+17/-5) share/server/util.js (+18/-9) share/server/validate.js (+4/-1) share/server/views.js (+2/-1) share/www/_sidebar.html (+7/-6) share/www/config.html (+5/-5) share/www/couch_tests.html (+6/-6) share/www/custom_test.html (+7/-7) share/www/database.html (+14/-11) share/www/dialog/_delete_database.html (+4/-2) share/www/document.html (+9/-9) share/www/index.html (+6/-6) share/www/replicator.html (+4/-4) share/www/script/couch.js (+52/-5) share/www/script/couch_test_runner.js (+3/-1) share/www/script/couch_tests.js (+18/-1) share/www/script/futon.browse.js (+46/-6) share/www/script/futon.js (+30/-0) share/www/script/jquery.couch.js (+10/-6) share/www/script/jquery.js (+5655/-5164) share/www/script/jquery.suggest.js (+0/-2) share/www/script/replicator_db_inc.js (+96/-0) share/www/script/test/attachment_names.js (+0/-2) share/www/script/test/attachment_ranges.js (+5/-0) share/www/script/test/attachments.js (+27/-0) share/www/script/test/attachments_multipart.js (+32/-29) share/www/script/test/changes.js (+139/-44) share/www/script/test/config.js (+49/-1) share/www/script/test/content_negotiation.js (+2/-2) share/www/script/test/cookie_auth.js (+25/-20) share/www/script/test/etags_views.js (+2/-2) share/www/script/test/form_submit.js (+0/-1) share/www/script/test/list_views.js (+37/-0) share/www/script/test/oauth.js (+2/-1) share/www/script/test/reader_acl.js (+7/-0) share/www/script/test/replication.js (+11/-0) share/www/script/test/replicator_db.js (+0/-1547) share/www/script/test/replicator_db_bad_rep_id.js (+77/-0) share/www/script/test/replicator_db_by_doc_id.js (+99/-0) share/www/script/test/replicator_db_compact_rep_db.js (+119/-0) share/www/script/test/replicator_db_continuous.js (+137/-0) share/www/script/test/replicator_db_credential_delegation.js (+149/-0) share/www/script/test/replicator_db_field_validation.js (+178/-0) share/www/script/test/replicator_db_filtered.js (+105/-0) share/www/script/test/replicator_db_identical.js (+87/-0) share/www/script/test/replicator_db_identical_continuous.js (+132/-0) share/www/script/test/replicator_db_invalid_filter.js (+115/-0) share/www/script/test/replicator_db_security.js (+12/-8) share/www/script/test/replicator_db_simple.js (+114/-0) share/www/script/test/replicator_db_successive.js (+127/-0) share/www/script/test/replicator_db_survives.js (+126/-0) share/www/script/test/replicator_db_swap_rep_db.js (+170/-0) share/www/script/test/replicator_db_update_security.js (+92/-0) share/www/script/test/replicator_db_user_ctx.js (+272/-0) share/www/script/test/replicator_db_write_auth.js (+102/-0) share/www/script/test/rev_stemming.js (+3/-0) share/www/script/test/rewrite.js (+173/-119) share/www/script/test/security_validation.js (+2/-2) share/www/script/test/show_documents.js (+2/-2) share/www/script/test/update_documents.js (+56/-2) share/www/script/test/users_db.js (+38/-0) share/www/script/test/users_db_security.js (+111/-9) share/www/script/test/utf8.js (+1/-0) share/www/script/test/uuids.js (+26/-1) share/www/script/test/view_compaction.js (+10/-10) share/www/script/test/view_multi_key_all_docs.js (+4/-0) share/www/script/test/view_multi_key_design.js (+4/-0) share/www/script/test/view_multi_key_temp.js (+3/-0) share/www/session.html (+6/-6) share/www/spec/run.html (+1/-0) share/www/status.html (+4/-4) share/www/style/layout.css (+4/-0) share/www/verify_install.html (+8/-7) src/Makefile.am (+12/-1) src/Makefile.in (+163/-59) src/couch_dbupdates/Makefile.am (+33/-0) src/couch_dbupdates/Makefile.in (+519/-0) src/couch_dbupdates/src/couch_dbupdates.app.src (+11/-0) src/couch_dbupdates/src/couch_dbupdates.erl (+46/-0) src/couch_dbupdates/src/couch_dbupdates_httpd.erl (+69/-0) src/couch_index/Makefile.am (+40/-0) src/couch_index/Makefile.in (+525/-0) src/couch_index/src/couch_index.app.src (+22/-0) src/couch_index/src/couch_index.erl (+340/-0) src/couch_index/src/couch_index_api.erl (+54/-0) src/couch_index/src/couch_index_compactor.erl (+114/-0) src/couch_index/src/couch_index_server.erl (+201/-0) src/couch_index/src/couch_index_updater.erl (+200/-0) src/couch_index/src/couch_index_util.erl (+78/-0) src/couch_mrview/Makefile.am (+73/-0) src/couch_mrview/Makefile.in (+582/-0) src/couch_mrview/include/couch_mrview.hrl (+80/-0) src/couch_mrview/src/couch_mrview.app.src (+28/-0) src/couch_mrview/src/couch_mrview.erl (+387/-0) src/couch_mrview/src/couch_mrview_cleanup.erl (+47/-0) src/couch_mrview/src/couch_mrview_compactor.erl (+178/-0) src/couch_mrview/src/couch_mrview_http.erl (+378/-0) src/couch_mrview/src/couch_mrview_index.erl (+162/-0) src/couch_mrview/src/couch_mrview_show.erl (+368/-0) src/couch_mrview/src/couch_mrview_test_util.erl (+91/-0) src/couch_mrview/src/couch_mrview_updater.erl (+282/-0) src/couch_mrview/src/couch_mrview_util.erl (+802/-0) src/couch_mrview/test/01-load.t (+34/-0) src/couch_mrview/test/02-map-views.t (+131/-0) src/couch_mrview/test/03-red-views.t (+78/-0) src/couch_mrview/test/04-index-info.t (+54/-0) src/couch_mrview/test/05-collation.t (+163/-0) src/couch_mrview/test/06-all-docs.t (+127/-0) src/couch_mrview/test/07-compact-swap.t (+57/-0) src/couch_replicator/Makefile.am (+77/-0) src/couch_replicator/Makefile.in (+586/-0) src/couch_replicator/src/couch_replicator.app.src (+33/-0) src/couch_replicator/src/couch_replicator.erl (+955/-0) src/couch_replicator/src/couch_replicator.hrl (+30/-0) src/couch_replicator/src/couch_replicator_api_wrap.erl (+780/-0) src/couch_replicator/src/couch_replicator_api_wrap.hrl (+36/-0) src/couch_replicator/src/couch_replicator_httpc.erl (+297/-0) src/couch_replicator/src/couch_replicator_httpc_pool.erl (+138/-0) src/couch_replicator/src/couch_replicator_httpd.erl (+66/-0) src/couch_replicator/src/couch_replicator_job_sup.erl (+31/-0) src/couch_replicator/src/couch_replicator_js_functions.hrl (+151/-0) src/couch_replicator/src/couch_replicator_manager.erl (+703/-0) src/couch_replicator/src/couch_replicator_notifier.erl (+57/-0) src/couch_replicator/src/couch_replicator_utils.erl (+388/-0) src/couch_replicator/src/couch_replicator_worker.erl (+515/-0) src/couch_replicator/test/01-load.t (+37/-0) src/couch_replicator/test/02-httpc-pool.t (+250/-0) src/couch_replicator/test/03-replication-compact.t (+488/-0) src/couch_replicator/test/04-replication-large-atts.t (+267/-0) src/couch_replicator/test/05-replication-many-leaves.t (+294/-0) src/couch_replicator/test/06-doc-missing-stubs.t (+304/-0) src/couchdb/Makefile.am (+10/-39) src/couchdb/Makefile.in (+210/-120) src/couchdb/couch.app.tpl.in (+1/-3) src/couchdb/couch_api_wrap.erl (+0/-779) src/couchdb/couch_api_wrap.hrl (+0/-36) src/couchdb/couch_api_wrap_httpc.erl (+0/-286) src/couchdb/couch_app.erl (+1/-1) src/couchdb/couch_auth_cache.erl (+25/-10) src/couchdb/couch_changes.erl (+19/-7) src/couchdb/couch_compaction_daemon.erl (+9/-10) src/couchdb/couch_config.erl (+2/-2) src/couchdb/couch_config_writer.erl (+1/-1) src/couchdb/couch_db.erl (+47/-25) src/couchdb/couch_db.hrl (+13/-29) src/couchdb/couch_db_update_notifier.erl (+11/-2) src/couchdb/couch_db_updater.erl (+19/-17) src/couchdb/couch_doc.erl (+64/-10) src/couchdb/couch_ejson_compare.erl (+12/-1) src/couchdb/couch_file.erl (+27/-3) src/couchdb/couch_httpc_pool.erl (+0/-138) src/couchdb/couch_httpd.erl (+122/-90) src/couchdb/couch_httpd_auth.erl (+31/-19) src/couchdb/couch_httpd_cors.erl (+349/-0) src/couchdb/couch_httpd_db.erl (+118/-280) src/couchdb/couch_httpd_external.erl (+11/-7) src/couchdb/couch_httpd_misc_handlers.erl (+77/-13) src/couchdb/couch_httpd_oauth.erl (+10/-9) src/couchdb/couch_httpd_replicator.erl (+0/-66) src/couchdb/couch_httpd_rewrite.erl (+18/-5) src/couchdb/couch_httpd_show.erl (+0/-407) src/couchdb/couch_httpd_vhost.erl (+34/-26) src/couchdb/couch_httpd_view.erl (+0/-777) src/couchdb/couch_js_functions.hrl (+11/-142) src/couchdb/couch_log.erl (+61/-10) src/couchdb/couch_os_daemons.erl (+11/-1) src/couchdb/couch_os_process.erl (+1/-1) src/couchdb/couch_passwords.erl (+119/-0) src/couchdb/couch_primary_sup.erl (+3/-3) src/couchdb/couch_rep_sup.erl (+0/-31) src/couchdb/couch_replication_manager.erl (+0/-694) src/couchdb/couch_replication_notifier.erl (+0/-57) src/couchdb/couch_replicator.erl (+0/-952) src/couchdb/couch_replicator.hrl (+0/-30) src/couchdb/couch_replicator_utils.erl (+0/-382) src/couchdb/couch_replicator_worker.erl (+0/-515) src/couchdb/couch_server.erl (+55/-30) src/couchdb/couch_stream.erl (+13/-8) src/couchdb/couch_users_db.erl (+27/-9) src/couchdb/couch_util.erl (+61/-8) src/couchdb/couch_uuids.erl (+9/-1) src/couchdb/couch_view.erl (+0/-437) src/couchdb/couch_view_compactor.erl (+0/-152) src/couchdb/couch_view_group.erl (+0/-699) src/couchdb/couch_view_updater.erl (+0/-283) src/couchdb/couch_work_queue.erl (+1/-1) src/couchdb/priv/Makefile.am (+43/-13) src/couchdb/priv/Makefile.in (+313/-215) src/couchdb/priv/couch_ejson_compare/couch_ejson_compare.c (+11/-10) src/couchdb/priv/couch_js/help.h (+4/-2) src/couchdb/priv/couch_js/http.c (+63/-3) src/couchdb/priv/couch_js/http.h (+3/-0) src/couchdb/priv/couch_js/sm170.c (+50/-30) src/couchdb/priv/couch_js/sm180.c (+50/-30) src/couchdb/priv/couch_js/sm185.c (+58/-28) src/couchdb/priv/couch_js/util.c (+79/-37) src/couchdb/priv/couch_js/util.h (+6/-4) src/couchdb/priv/couchjs.1 (+8/-4) src/ejson/Makefile.in (+183/-98) src/ejson/ejson.erl (+2/-0) src/ejson/yajl/yajl_encode.c (+7/-0) src/erlang-oauth/Makefile.am (+2/-13) src/erlang-oauth/Makefile.in (+114/-49) src/erlang-oauth/oauth.erl (+276/-68) src/erlang-oauth/oauth_hmac_sha1.erl (+0/-11) src/erlang-oauth/oauth_http.erl (+0/-22) src/erlang-oauth/oauth_plaintext.erl (+0/-10) src/erlang-oauth/oauth_rsa_sha1.erl (+0/-30) src/erlang-oauth/oauth_unix.erl (+0/-16) src/erlang-oauth/oauth_uri.erl (+0/-100) src/etap/Makefile.am (+2/-18) src/etap/Makefile.in (+114/-54) src/etap/etap.erl (+273/-76) src/etap/etap_application.erl (+0/-72) src/etap/etap_can.erl (+0/-79) src/etap/etap_exception.erl (+0/-66) src/etap/etap_process.erl (+0/-42) src/etap/etap_report.erl (+0/-343) src/etap/etap_request.erl (+0/-89) src/etap/etap_string.erl (+0/-47) src/etap/etap_web.erl (+0/-65) src/ibrowse/Makefile.in (+112/-36) src/ibrowse/ibrowse.app.in (+4/-10) src/ibrowse/ibrowse.erl (+158/-92) src/ibrowse/ibrowse_http_client.erl (+175/-109) src/ibrowse/ibrowse_lb.erl (+54/-37) src/ibrowse/ibrowse_lib.erl (+62/-12) src/ibrowse/ibrowse_test.erl (+122/-10) src/mochiweb/Makefile.am (+0/-1) src/mochiweb/Makefile.in (+112/-37) src/mochiweb/mochifmt.erl (+1/-1) src/mochiweb/mochifmt_records.erl (+10/-6) src/mochiweb/mochifmt_std.erl (+12/-9) src/mochiweb/mochiglobal.erl (+2/-2) src/mochiweb/mochihex.erl (+1/-4) src/mochiweb/mochijson.erl (+1/-3) src/mochiweb/mochijson2.erl (+52/-12) src/mochiweb/mochilists.erl (+1/-1) src/mochiweb/mochilogfile2.erl (+1/-1) src/mochiweb/mochinum.erl (+1/-1) src/mochiweb/mochitemp.erl (+2/-1) src/mochiweb/mochiutf8.erl (+4/-3) src/mochiweb/mochiweb.app.in (+5/-28) src/mochiweb/mochiweb.app.src (+0/-9) src/mochiweb/mochiweb.erl (+19/-27) src/mochiweb/mochiweb_acceptor.erl (+7/-4) src/mochiweb/mochiweb_charref.erl (+2131/-256) src/mochiweb/mochiweb_cookies.erl (+29/-7) src/mochiweb/mochiweb_cover.erl (+1/-1) src/mochiweb/mochiweb_echo.erl (+9/-6) src/mochiweb/mochiweb_headers.erl (+125/-4) src/mochiweb/mochiweb_html.erl (+100/-32) src/mochiweb/mochiweb_http.erl (+41/-67) src/mochiweb/mochiweb_io.erl (+1/-4) src/mochiweb/mochiweb_mime.erl (+360/-39) src/mochiweb/mochiweb_multipart.erl (+73/-25) src/mochiweb/mochiweb_request.erl (+299/-192) src/mochiweb/mochiweb_request_tests.erl (+120/-1) src/mochiweb/mochiweb_response.erl (+27/-19) src/mochiweb/mochiweb_socket.erl (+7/-8) src/mochiweb/mochiweb_socket_server.erl (+33/-47) src/mochiweb/mochiweb_util.erl (+11/-5) src/mochiweb/reloader.erl (+2/-2) src/snappy/Makefile.am (+3/-3) src/snappy/Makefile.in (+168/-83) src/snappy/google-snappy/config.h.in (+33/-38) src/snappy/google-snappy/snappy-sinksource.cc (+0/-1) src/snappy/google-snappy/snappy-sinksource.h (+1/-0) src/snappy/google-snappy/snappy-stubs-internal.h (+99/-5) src/snappy/google-snappy/snappy.cc (+152/-62) src/snappy/google-snappy/snappy.h (+2/-2) src/snappy/snappy.app.in (+1/-1) test/Makefile.am (+1/-0) test/Makefile.in (+151/-58) test/bench/Makefile.in (+76/-24) test/etap/001-load.t (+2/-17) test/etap/020-btree-basics.t (+2/-2) test/etap/040-util.t (+2/-2) test/etap/041-uuid-gen-id.ini (+20/-0) test/etap/041-uuid-gen.t (+31/-2) test/etap/050-stream.t (+4/-4) test/etap/072-cleanup.t (+3/-3) test/etap/073-changes.t (+1/-1) test/etap/074-doc-update-conflicts.t (+218/-0) test/etap/075-auth-cache.t (+3/-1) test/etap/076-file-compression.t (+7/-6) test/etap/077-couch-db-fast-db-delete-create.t (+61/-0) test/etap/080-config-get-set.t (+1/-1) test/etap/083-config-no-files.t (+0/-2) test/etap/090-task-status.t (+0/-3) test/etap/120-stats-collect.t (+7/-7) test/etap/140-attachment-comp.t (+4/-1) test/etap/160-vhosts.t (+12/-31) test/etap/200-view-group-no-db-leaks.t (+21/-49) test/etap/201-view-group-shutdown.t (+9/-19) test/etap/220-compaction-daemon.t (+19/-21) test/etap/230-httpc-pool.t (+0/-250) test/etap/230-pbkfd2.t (+38/-0) test/etap/231-cors.t (+449/-0) test/etap/240-replication-compact.t (+0/-488) test/etap/241-replication-large-atts.t (+0/-267) test/etap/242-replication-many-leaves.t (+0/-294) test/etap/243-doc-missing-stubs.t (+0/-304) test/etap/250-upgrade-legacy-view-files.t (+168/-0) test/etap/Makefile.am (+19/-9) test/etap/Makefile.in (+130/-61) test/etap/random_port.ini (+0/-19) test/etap/run.tpl (+16/-11) test/etap/test_util.erl.in (+25/-3) test/javascript/Makefile.am (+2/-0) test/javascript/Makefile.in (+78/-24) test/javascript/cli_runner.js (+34/-39) test/javascript/couch_http.js (+16/-5) test/javascript/run.tpl (+91/-12) test/javascript/test_setup.js (+89/-0) test/random_port.ini (+19/-0) test/view_server/Makefile.in (+76/-24) utils/Makefile.am (+1/-1) utils/Makefile.in (+77/-25) var/Makefile.in (+76/-25) |
To merge this branch: | bzr merge lp:~jderose/ubuntu/saucy/couchdb/1.4.0 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrew Starr-Bochicchio (community) | Approve | ||
Chad Miller (community) | Approve | ||
Jason Gerard DeRose (community) | Needs Resubmitting | ||
Ubuntu branches | Pending | ||
Review via email: mp+182725@code.launchpad.net |
Commit message
Description of the change
- 114. By Jason Gerard DeRose
-
merge-upstream 1.4.0 (no change from 1.4.0-rc.1)
- 115. By Jason Gerard DeRose
-
Fixed up changelog
- 116. By Jason Gerard DeRose
-
oops, revert XSBC-Original-
Maintainer to Laszlo Boszormenyi (GCS) <email address hidden> - 117. By Jason Gerard DeRose
-
oops, we still need couchdb-
bin.postinst - 118. By Jason Gerard DeRose
-
Updated debian/watch file to use current http://
www.apache. org/dist/ couchdb/ source/ location - 119. By Jason Gerard DeRose
-
Added a get-packaged-
orig-source rule - 120. By Jason Gerard DeRose
-
Updated changelog with a few last bits
Jason Gerard DeRose (jderose) wrote : | # |
Thanks, Chad!
So I've got those 3 things fixed, and I also fixed the debian/watch file, which wasn't pointing to the current download location.
I also got word from the CouchDB folks that the 1.4.0 release is now golden (no change from 1.4.0-rc.1), so I updated the version in the changelog to reflect this (note the 1.4.0 release announcement hasn't been made yet).
Jason Gerard DeRose (jderose) wrote : | # |
Oh, one more thing, something about UDD or quilt caused two conflicts when you try to merge this into lp:ubuntu/saucy/couchdb:
conflicts:
Text conflict in bin/couchdb.tpl.in
Text conflict in etc/init/
They can be correctly resolved with:
bzr resolve --all --take-other
Chad Miller (cmiller) wrote : | # |
Okay. In the future, Jason, I think the quilt state directory '.pc' should be added to bzr's ignores list. Not important now.
Chad Miller (cmiller) wrote : | # |
Jason, another wishlist thing to add in the future is "autopkgtests", so we can detect breakage between couchdb--erlang, and maybe novacut--c--e one day.
Chad Miller (cmiller) wrote : | # |
Jason, also pay attention to lintian messages. Fix these "E" at least for next upload. Maybe you can ignore the init.d ones, assuming you Depend on upstart.
W: couchdb-common: debian-
W: couchdb-common: embedded-
W: couchdb-common: embedded-
W: couchdb-common: embedded-
W: couchdb-common: embedded-
W: couchdb-common: executable-
W: couchdb-common: executable-
W: couchdb-bin: debian-
W: couchdb-bin: virtual-
E: couchdb-bin: package-
W: couchdb-bin: binary-
E: couchdb-bin: non-empty-
E: couchdb-bin: non-empty-
E: couchdb-bin: non-empty-
E: couchdb-bin: non-empty-
W: couchdb: debian-
E: couchdb: postrm-
W: couchdb: init.d-
E: couchdb: init.d-
- 121. By Jason Gerard DeRose
-
Fix linian non-empty-
dependency_ libs-in- la-file warnings - 122. By Jason Gerard DeRose
-
Fix lintian debian-
changelog- line-too- long warning - 123. By Jason Gerard DeRose
-
Oops, didn't mean to commit with --disable-tests
Jason Gerard DeRose (jderose) wrote : | # |
Chad,
So you don't need to keep .pc under version control for UDD any more?
Yeah, I'm keen adding some autopkgtests goodness. It would be good to test couchdb as a reverse dependency whenever erlang is updated, and testing the novacut components as a reverse dependency whenever couchdb is updated would also be awesome. Although these days couchdb has quite extensive unit tests that get run during the builds, so at least we're not completely lacking it automatic test coverage in the present. Could be much better though.
So I fixed the non-empty-
Out of curiosity, how are you running lintian? When I run it, I'm not seeing the package-
Thanks again for all your help!
Jason Gerard DeRose (jderose) wrote : | # |
Oh, and the last two lintian errors seem to be spurious, just the result of lintian not groking upstart:
https:/
Chad Miller (cmiller) wrote : | # |
Jason, quilt state files in .pc/ should never be in Bazaar version control. Only the results of using quilt, a set of patch files in debian/, should be in Bazaar version control.
I'm running lintian as the automatic step at the end of "bzr builddeb", on Saucy.
Andrew Starr-Bochicchio (andrewsomething) : | # |
Robie Basak (racb) wrote : | # |
This is uploaded now, so closing out this MP.
Preview Diff
1 | === removed file '.pc/applied-patches' |
2 | --- .pc/applied-patches 2013-01-18 22:04:32 +0000 |
3 | +++ .pc/applied-patches 1970-01-01 00:00:00 +0000 |
4 | @@ -1,8 +0,0 @@ |
5 | -force-reload.patch |
6 | -couchdb_own_rundir.patch |
7 | -logrotate_as_couchdb.patch |
8 | -couchdb_sighup.patch |
9 | -wait_for_couchdb_stop.patch |
10 | -improve_parsing_of_mochiweb_relative_paths.patch |
11 | -improve_script_url_validation.patch |
12 | -include_a_comment_before_jsonp_output.patch |
13 | |
14 | === removed directory '.pc/couchdb_own_rundir.patch' |
15 | === removed directory '.pc/couchdb_own_rundir.patch/etc' |
16 | === removed directory '.pc/couchdb_own_rundir.patch/etc/init' |
17 | === removed file '.pc/couchdb_own_rundir.patch/etc/init/couchdb.tpl.in' |
18 | --- .pc/couchdb_own_rundir.patch/etc/init/couchdb.tpl.in 2012-07-19 20:13:25 +0000 |
19 | +++ .pc/couchdb_own_rundir.patch/etc/init/couchdb.tpl.in 1970-01-01 00:00:00 +0000 |
20 | @@ -1,156 +0,0 @@ |
21 | -#!/bin/sh -e |
22 | - |
23 | -# Licensed under the Apache License, Version 2.0 (the "License"); you may not |
24 | -# use this file except in compliance with the License. You may obtain a copy of |
25 | -# the License at |
26 | -# |
27 | -# http://www.apache.org/licenses/LICENSE-2.0 |
28 | -# |
29 | -# Unless required by applicable law or agreed to in writing, software |
30 | -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
31 | -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
32 | -# License for the specific language governing permissions and limitations under |
33 | -# the License. |
34 | - |
35 | -### BEGIN INIT INFO |
36 | -# Provides: couchdb |
37 | -# Required-Start: $local_fs $remote_fs |
38 | -# Required-Stop: $local_fs $remote_fs |
39 | -# Default-Start: 2 3 4 5 |
40 | -# Default-Stop: 0 1 6 |
41 | -# Short-Description: Apache CouchDB init script |
42 | -# Description: Apache CouchDB init script for the database server. |
43 | -### END INIT INFO |
44 | - |
45 | -SCRIPT_OK=0 |
46 | -SCRIPT_ERROR=1 |
47 | - |
48 | -DESCRIPTION="database server" |
49 | -NAME=couchdb |
50 | -SCRIPT_NAME=`basename $0` |
51 | -COUCHDB=%bindir%/%couchdb_command_name% |
52 | -CONFIGURATION_FILE=%sysconfdir%/default/couchdb |
53 | -RUN_DIR=%localstaterundir% |
54 | -LSB_LIBRARY=/lib/lsb/init-functions |
55 | - |
56 | -if test ! -x $COUCHDB; then |
57 | - exit $SCRIPT_ERROR |
58 | -fi |
59 | - |
60 | -if test -r $CONFIGURATION_FILE; then |
61 | - . $CONFIGURATION_FILE |
62 | -fi |
63 | - |
64 | -log_daemon_msg () { |
65 | - # Dummy function to be replaced by LSB library. |
66 | - |
67 | - echo $@ |
68 | -} |
69 | - |
70 | -log_end_msg () { |
71 | - # Dummy function to be replaced by LSB library. |
72 | - |
73 | - if test "$1" != "0"; then |
74 | - echo "Error with $DESCRIPTION: $NAME" |
75 | - fi |
76 | - return $1 |
77 | -} |
78 | - |
79 | -if test -r $LSB_LIBRARY; then |
80 | - . $LSB_LIBRARY |
81 | -fi |
82 | - |
83 | -run_command () { |
84 | - command="$1" |
85 | - if test -n "$COUCHDB_OPTIONS"; then |
86 | - command="$command $COUCHDB_OPTIONS" |
87 | - fi |
88 | - if test -n "$COUCHDB_USER"; then |
89 | - if su $COUCHDB_USER -c "$command"; then |
90 | - return $SCRIPT_OK |
91 | - else |
92 | - return $SCRIPT_ERROR |
93 | - fi |
94 | - else |
95 | - if $command; then |
96 | - return $SCRIPT_OK |
97 | - else |
98 | - return $SCRIPT_ERROR |
99 | - fi |
100 | - fi |
101 | -} |
102 | - |
103 | -start_couchdb () { |
104 | - # Start Apache CouchDB as a background process. |
105 | - |
106 | - mkdir -p "$RUN_DIR" |
107 | - command="$COUCHDB -b" |
108 | - if test -n "$COUCHDB_STDOUT_FILE"; then |
109 | - command="$command -o $COUCHDB_STDOUT_FILE" |
110 | - fi |
111 | - if test -n "$COUCHDB_STDERR_FILE"; then |
112 | - command="$command -e $COUCHDB_STDERR_FILE" |
113 | - fi |
114 | - if test -n "$COUCHDB_RESPAWN_TIMEOUT"; then |
115 | - command="$command -r $COUCHDB_RESPAWN_TIMEOUT" |
116 | - fi |
117 | - run_command "$command" > /dev/null |
118 | -} |
119 | - |
120 | -stop_couchdb () { |
121 | - # Stop the running Apache CouchDB process. |
122 | - |
123 | - run_command "$COUCHDB -d" > /dev/null |
124 | -} |
125 | - |
126 | -display_status () { |
127 | - # Display the status of the running Apache CouchDB process. |
128 | - |
129 | - run_command "$COUCHDB -s" |
130 | -} |
131 | - |
132 | -parse_script_option_list () { |
133 | - # Parse arguments passed to the script and take appropriate action. |
134 | - |
135 | - case "$1" in |
136 | - start) |
137 | - log_daemon_msg "Starting $DESCRIPTION" $NAME |
138 | - if start_couchdb; then |
139 | - log_end_msg $SCRIPT_OK |
140 | - else |
141 | - log_end_msg $SCRIPT_ERROR |
142 | - fi |
143 | - ;; |
144 | - stop) |
145 | - log_daemon_msg "Stopping $DESCRIPTION" $NAME |
146 | - if stop_couchdb; then |
147 | - log_end_msg $SCRIPT_OK |
148 | - else |
149 | - log_end_msg $SCRIPT_ERROR |
150 | - fi |
151 | - ;; |
152 | - restart|force-reload) |
153 | - log_daemon_msg "Restarting $DESCRIPTION" $NAME |
154 | - if stop_couchdb; then |
155 | - if start_couchdb; then |
156 | - log_end_msg $SCRIPT_OK |
157 | - else |
158 | - log_end_msg $SCRIPT_ERROR |
159 | - fi |
160 | - else |
161 | - log_end_msg $SCRIPT_ERROR |
162 | - fi |
163 | - ;; |
164 | - status) |
165 | - display_status |
166 | - ;; |
167 | - *) |
168 | - cat << EOF >&2 |
169 | -Usage: $SCRIPT_NAME {start|stop|restart|force-reload|status} |
170 | -EOF |
171 | - exit $SCRIPT_ERROR |
172 | - ;; |
173 | - esac |
174 | -} |
175 | - |
176 | -parse_script_option_list $@ |
177 | |
178 | === removed directory '.pc/couchdb_sighup.patch' |
179 | === removed directory '.pc/couchdb_sighup.patch/bin' |
180 | === removed file '.pc/couchdb_sighup.patch/bin/couchdb.tpl.in' |
181 | --- .pc/couchdb_sighup.patch/bin/couchdb.tpl.in 2012-11-18 12:24:24 +0000 |
182 | +++ .pc/couchdb_sighup.patch/bin/couchdb.tpl.in 1970-01-01 00:00:00 +0000 |
183 | @@ -1,335 +0,0 @@ |
184 | -#! /bin/sh -e |
185 | - |
186 | -# Licensed under the Apache License, Version 2.0 (the "License"); you may not |
187 | -# use this file except in compliance with the License. You may obtain a copy of |
188 | -# the License at |
189 | -# |
190 | -# http://www.apache.org/licenses/LICENSE-2.0 |
191 | -# |
192 | -# Unless required by applicable law or agreed to in writing, software |
193 | -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
194 | -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
195 | -# License for the specific language governing permissions and limitations under |
196 | -# the License. |
197 | - |
198 | -BACKGROUND=false |
199 | -DEFAULT_CONFIG_DIR=%localconfdir%/default.d |
200 | -DEFAULT_CONFIG_FILE=%localconfdir%/%defaultini% |
201 | -ERL_OS_MON_OPTIONS="-os_mon \ |
202 | - start_memsup false \ |
203 | - start_cpu_sup false \ |
204 | - disk_space_check_interval 1 \ |
205 | - disk_almost_full_threshold 1" |
206 | -ERL_START_OPTIONS="$ERL_OS_MON_OPTIONS -sasl errlog_type error +K true +A 4" |
207 | -HEART_BEAT_TIMEOUT=11 |
208 | -HEART_COMMAND="%bindir%/%couchdb_command_name% -k" |
209 | -INTERACTIVE=false |
210 | -KILL=false |
211 | -LOCAL_CONFIG_DIR=%localconfdir%/local.d |
212 | -LOCAL_CONFIG_FILE=%localconfdir%/%localini% |
213 | -PID_FILE=%localstatedir%/run/couchdb/couchdb.pid |
214 | -RECURSED=false |
215 | -RESET_CONFIG=true |
216 | -RESPAWN_TIMEOUT=0 |
217 | -SCRIPT_ERROR=1 |
218 | -SCRIPT_OK=0 |
219 | -SHUTDOWN=false |
220 | -STDERR_FILE=couchdb.stderr |
221 | -STDOUT_FILE=couchdb.stdout |
222 | - |
223 | -print_arguments="" |
224 | -start_arguments="" |
225 | -background_start_arguments="" |
226 | - |
227 | -basename=`basename $0` |
228 | - |
229 | -display_version () { |
230 | - cat << EOF |
231 | -$basename - %package_name% %version% |
232 | - |
233 | -Licensed under the Apache License, Version 2.0 (the "License"); you may not use |
234 | -this file except in compliance with the License. You may obtain a copy of the |
235 | -License at |
236 | - |
237 | - http://www.apache.org/licenses/LICENSE-2.0 |
238 | - |
239 | -Unless required by applicable law or agreed to in writing, software distributed |
240 | -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR |
241 | -CONDITIONS OF ANY KIND, either express or implied. See the License for the |
242 | -specific language governing permissions and limitations under the License. |
243 | - |
244 | -EOF |
245 | -} |
246 | - |
247 | -display_help () { |
248 | - cat << EOF |
249 | -Usage: $basename [OPTION] |
250 | - |
251 | -The $basename command runs the %package_name% server. |
252 | - |
253 | -Erlang is called with: |
254 | - |
255 | - $ERL_START_OPTIONS |
256 | - |
257 | -Erlang inherits the environment of this command. |
258 | - |
259 | -You can override these options using the environment: |
260 | - |
261 | - ERL_AFLAGS, ERL_FLAGS, ERL_ZFLAGS |
262 | - |
263 | -See erl(1) for more information about the environment variables. |
264 | - |
265 | -The exit status is 0 for success or 1 for failure. |
266 | - |
267 | -Options: |
268 | - |
269 | - -h display a short help message and exit |
270 | - -V display version information and exit |
271 | - -a FILE add configuration FILE to chain |
272 | - -A DIR add configuration DIR to chain |
273 | - -n reset configuration file chain (including system default) |
274 | - -c print configuration file chain and exit |
275 | - -i use the interactive Erlang shell |
276 | - -b spawn as a background process |
277 | - -p FILE set the background PID FILE (overrides system default) |
278 | - -r SECONDS respawn background process after SECONDS (defaults to no respawn) |
279 | - -o FILE redirect background stdout to FILE (defaults to $STDOUT_FILE) |
280 | - -e FILE redirect background stderr to FILE (defaults to $STDERR_FILE) |
281 | - -s display the status of the background process |
282 | - -k kill the background process, will respawn if needed |
283 | - -d shutdown the background process |
284 | - |
285 | -Report bugs at <%bug_uri%>. |
286 | -EOF |
287 | -} |
288 | - |
289 | -display_error () { |
290 | - if test -n "$1"; then |
291 | - echo $1 >&2 |
292 | - fi |
293 | - echo >&2 |
294 | - echo "Try \`"$basename" -h' for more information." >&2 |
295 | - false |
296 | -} |
297 | - |
298 | -_get_pid () { |
299 | - if test -f $PID_FILE; then |
300 | - PID=`cat $PID_FILE` |
301 | - fi |
302 | - echo $PID |
303 | -} |
304 | - |
305 | -_add_config_file () { |
306 | - if test -z "$print_arguments"; then |
307 | - print_arguments="$1" |
308 | - else |
309 | - print_arguments="`cat <<EOF |
310 | -$print_arguments |
311 | -$1 |
312 | -EOF |
313 | -`" |
314 | - fi |
315 | - start_arguments="$start_arguments $1" |
316 | - background_start_arguments="$background_start_arguments -a $1" |
317 | -} |
318 | - |
319 | -_add_config_dir () { |
320 | - for file in "$1"/*.ini; do |
321 | - if [ -r "$file" ]; then |
322 | - _add_config_file "$file" |
323 | - fi |
324 | - done |
325 | -} |
326 | - |
327 | -_load_config () { |
328 | - _add_config_file "$DEFAULT_CONFIG_FILE" |
329 | - _add_config_dir "$DEFAULT_CONFIG_DIR" |
330 | - _add_config_file "$LOCAL_CONFIG_FILE" |
331 | - _add_config_dir "$LOCAL_CONFIG_DIR" |
332 | -} |
333 | - |
334 | -_reset_config () { |
335 | - print_arguments="" |
336 | - start_arguments="" |
337 | - background_start_arguments="-n" |
338 | -} |
339 | - |
340 | -_print_config () { |
341 | - cat <<EOF |
342 | -$print_arguments |
343 | -EOF |
344 | -} |
345 | - |
346 | -check_status () { |
347 | - PID=`_get_pid` |
348 | - if test -n "$PID"; then |
349 | - if kill -0 $PID 2> /dev/null; then |
350 | - echo "Apache CouchDB is running as process $PID, time to relax." |
351 | - return $SCRIPT_OK |
352 | - else |
353 | - echo >&2 << EOF |
354 | -Apache CouchDB is not running but a stale PID file exists: $PID_FILE |
355 | -EOF |
356 | - fi |
357 | - else |
358 | - echo "Apache CouchDB is not running." >&2 |
359 | - fi |
360 | - return $SCRIPT_ERROR |
361 | -} |
362 | - |
363 | -check_environment () { |
364 | - if test "$BACKGROUND" != "true"; then |
365 | - return |
366 | - fi |
367 | - touch $PID_FILE 2> /dev/null || true |
368 | - touch $STDOUT_FILE 2> /dev/null || true |
369 | - touch $STDERR_FILE 2> /dev/null || true |
370 | - message_prefix="Apache CouchDB needs write permission on the" |
371 | - if test ! -w $PID_FILE; then |
372 | - echo "$message_prefix PID file: $PID_FILE" >&2 |
373 | - false |
374 | - fi |
375 | - if test ! -w $STDOUT_FILE; then |
376 | - echo "$message_prefix STDOUT file: $STDOUT_FILE" >&2 |
377 | - false |
378 | - fi |
379 | - if test ! -w $STDERR_FILE; then |
380 | - echo "$message_prefix STDERR file: $STDERR_FILE" >&2 |
381 | - false |
382 | - fi |
383 | - message_prefix="Apache CouchDB needs a regular" |
384 | - if test `echo 2> /dev/null >> $PID_FILE; echo $?` -gt 0; then |
385 | - echo "$message_prefix PID file: $PID_FILE" >&2 |
386 | - false |
387 | - fi |
388 | - if test `echo 2> /dev/null >> $STDOUT_FILE; echo $?` -gt 0; then |
389 | - echo "$message_prefix STDOUT file: $STDOUT_FILE" >&2 |
390 | - false |
391 | - fi |
392 | - if test `echo 2> /dev/null >> $STDERR_FILE; echo $?` -gt 0; then |
393 | - echo "$message_prefix STDERR file: $STDERR_FILE" >&2 |
394 | - false |
395 | - fi |
396 | -} |
397 | - |
398 | -start_couchdb () { |
399 | - if test ! "$RECURSED" = "true"; then |
400 | - if check_status 2> /dev/null; then |
401 | - exit |
402 | - fi |
403 | - check_environment |
404 | - fi |
405 | - interactive_option="+Bd -noinput" |
406 | - if test "$INTERACTIVE" = "true"; then |
407 | - interactive_option="" |
408 | - fi |
409 | - if test "$BACKGROUND" = "true"; then |
410 | - touch $PID_FILE |
411 | - interactive_option="+Bd -noinput" |
412 | - fi |
413 | - command="%ERL% $interactive_option $ERL_START_OPTIONS \ |
414 | - -env ERL_LIBS %localerlanglibdir% -couch_ini $start_arguments -s couch" |
415 | - if test "$BACKGROUND" = "true" -a "$RECURSED" = "false"; then |
416 | - $0 $background_start_arguments -b -r $RESPAWN_TIMEOUT -p $PID_FILE \ |
417 | - -o $STDOUT_FILE -e $STDERR_FILE -R & |
418 | - echo "Apache CouchDB has started, time to relax." |
419 | - else |
420 | - if test "$RECURSED" = "true"; then |
421 | - while true; do |
422 | - export HEART_COMMAND |
423 | - export HEART_BEAT_TIMEOUT |
424 | - `eval $command -pidfile $PID_FILE -heart \ |
425 | - >> $STDOUT_FILE 2>> $STDERR_FILE` || true |
426 | - PID=`_get_pid` |
427 | - if test -n "$PID"; then |
428 | - if kill -0 $PID 2> /dev/null; then |
429 | - return $SCRIPT_ERROR |
430 | - fi |
431 | - else |
432 | - return $SCRIPT_OK |
433 | - fi |
434 | - if test "$RESPAWN_TIMEOUT" = "0"; then |
435 | - return $SCRIPT_OK |
436 | - fi |
437 | - if test "$RESPAWN_TIMEOUT" != "1"; then |
438 | - plural_ending="s" |
439 | - fi |
440 | - cat << EOF |
441 | -Apache CouchDB crashed, restarting in $RESPAWN_TIMEOUT second$plural_ending. |
442 | -EOF |
443 | - sleep $RESPAWN_TIMEOUT |
444 | - done |
445 | - else |
446 | - eval exec $command |
447 | - fi |
448 | - fi |
449 | -} |
450 | - |
451 | -stop_couchdb () { |
452 | - PID=`_get_pid` |
453 | - if test -n "$PID"; then |
454 | - if test "$1" = "false"; then |
455 | - echo > $PID_FILE |
456 | - fi |
457 | - if kill -0 $PID 2> /dev/null; then |
458 | - if kill -1 $PID 2> /dev/null; then |
459 | - if test "$1" = "false"; then |
460 | - echo "Apache CouchDB has been shutdown." |
461 | - else |
462 | - echo "Apache CouchDB has been killed." |
463 | - fi |
464 | - return $SCRIPT_OK |
465 | - else |
466 | - echo "Apache CouchDB could not be killed." >&2 |
467 | - return $SCRIPT_ERROR |
468 | - fi |
469 | - if test "$1" = "false"; then |
470 | - echo "Stale PID file exists but Apache CouchDB is not running." |
471 | - else |
472 | - echo "Stale PID file existed but Apache CouchDB is not running." |
473 | - fi |
474 | - fi |
475 | - else |
476 | - echo "Apache CouchDB is not running." |
477 | - fi |
478 | -} |
479 | - |
480 | -parse_script_option_list () { |
481 | - _load_config |
482 | - set +e |
483 | - options=`getopt hVa:A:ncibp:r:Ro:e:skd $@` |
484 | - if test ! $? -eq 0; then |
485 | - display_error |
486 | - fi |
487 | - set -e |
488 | - eval set -- $options |
489 | - while [ $# -gt 0 ]; do |
490 | - case "$1" in |
491 | - -h) shift; display_help; exit;; |
492 | - -V) shift; display_version; exit;; |
493 | - -a) shift; _add_config_file "$1"; shift;; |
494 | - -A) shift; _add_config_dir "$1"; shift;; |
495 | - -n) shift; _reset_config;; |
496 | - -c) shift; _print_config; exit;; |
497 | - -i) shift; INTERACTIVE=true;; |
498 | - -b) shift; BACKGROUND=true;; |
499 | - -r) shift; RESPAWN_TIMEOUT=$1; shift;; |
500 | - -R) shift; RECURSED=true;; |
501 | - -p) shift; PID_FILE=$1; shift;; |
502 | - -o) shift; STDOUT_FILE=$1; shift;; |
503 | - -e) shift; STDERR_FILE=$1; shift;; |
504 | - -s) shift; check_status; exit;; |
505 | - -k) shift; KILL=true;; |
506 | - -d) shift; SHUTDOWN=true;; |
507 | - --) shift; break;; |
508 | - *) display_error "Unknown option: $1" >&2;; |
509 | - esac |
510 | - done |
511 | - if test "$KILL" = "true" -o "$SHUTDOWN" = "true"; then |
512 | - stop_couchdb $KILL |
513 | - else |
514 | - start_couchdb |
515 | - fi |
516 | -} |
517 | - |
518 | -parse_script_option_list $@ |
519 | |
520 | === removed directory '.pc/force-reload.patch' |
521 | === removed directory '.pc/force-reload.patch/etc' |
522 | === removed directory '.pc/force-reload.patch/etc/init' |
523 | === removed file '.pc/force-reload.patch/etc/init/couchdb.tpl.in' |
524 | --- .pc/force-reload.patch/etc/init/couchdb.tpl.in 2012-04-10 21:14:05 +0000 |
525 | +++ .pc/force-reload.patch/etc/init/couchdb.tpl.in 1970-01-01 00:00:00 +0000 |
526 | @@ -1,156 +0,0 @@ |
527 | -#!/bin/sh -e |
528 | - |
529 | -# Licensed under the Apache License, Version 2.0 (the "License"); you may not |
530 | -# use this file except in compliance with the License. You may obtain a copy of |
531 | -# the License at |
532 | -# |
533 | -# http://www.apache.org/licenses/LICENSE-2.0 |
534 | -# |
535 | -# Unless required by applicable law or agreed to in writing, software |
536 | -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
537 | -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
538 | -# License for the specific language governing permissions and limitations under |
539 | -# the License. |
540 | - |
541 | -### BEGIN INIT INFO |
542 | -# Provides: couchdb |
543 | -# Required-Start: $local_fs $remote_fs |
544 | -# Required-Stop: $local_fs $remote_fs |
545 | -# Default-Start: 2 3 4 5 |
546 | -# Default-Stop: 0 1 6 |
547 | -# Short-Description: Apache CouchDB init script |
548 | -# Description: Apache CouchDB init script for the database server. |
549 | -### END INIT INFO |
550 | - |
551 | -SCRIPT_OK=0 |
552 | -SCRIPT_ERROR=1 |
553 | - |
554 | -DESCRIPTION="database server" |
555 | -NAME=couchdb |
556 | -SCRIPT_NAME=`basename $0` |
557 | -COUCHDB=%bindir%/%couchdb_command_name% |
558 | -CONFIGURATION_FILE=%sysconfdir%/default/couchdb |
559 | -RUN_DIR=%localstaterundir% |
560 | -LSB_LIBRARY=/lib/lsb/init-functions |
561 | - |
562 | -if test ! -x $COUCHDB; then |
563 | - exit $SCRIPT_ERROR |
564 | -fi |
565 | - |
566 | -if test -r $CONFIGURATION_FILE; then |
567 | - . $CONFIGURATION_FILE |
568 | -fi |
569 | - |
570 | -log_daemon_msg () { |
571 | - # Dummy function to be replaced by LSB library. |
572 | - |
573 | - echo $@ |
574 | -} |
575 | - |
576 | -log_end_msg () { |
577 | - # Dummy function to be replaced by LSB library. |
578 | - |
579 | - if test "$1" != "0"; then |
580 | - echo "Error with $DESCRIPTION: $NAME" |
581 | - fi |
582 | - return $1 |
583 | -} |
584 | - |
585 | -if test -r $LSB_LIBRARY; then |
586 | - . $LSB_LIBRARY |
587 | -fi |
588 | - |
589 | -run_command () { |
590 | - command="$1" |
591 | - if test -n "$COUCHDB_OPTIONS"; then |
592 | - command="$command $COUCHDB_OPTIONS" |
593 | - fi |
594 | - if test -n "$COUCHDB_USER"; then |
595 | - if su $COUCHDB_USER -c "$command"; then |
596 | - return $SCRIPT_OK |
597 | - else |
598 | - return $SCRIPT_ERROR |
599 | - fi |
600 | - else |
601 | - if $command; then |
602 | - return $SCRIPT_OK |
603 | - else |
604 | - return $SCRIPT_ERROR |
605 | - fi |
606 | - fi |
607 | -} |
608 | - |
609 | -start_couchdb () { |
610 | - # Start Apache CouchDB as a background process. |
611 | - |
612 | - mkdir -p "$RUN_DIR" |
613 | - command="$COUCHDB -b" |
614 | - if test -n "$COUCHDB_STDOUT_FILE"; then |
615 | - command="$command -o $COUCHDB_STDOUT_FILE" |
616 | - fi |
617 | - if test -n "$COUCHDB_STDERR_FILE"; then |
618 | - command="$command -e $COUCHDB_STDERR_FILE" |
619 | - fi |
620 | - if test -n "$COUCHDB_RESPAWN_TIMEOUT"; then |
621 | - command="$command -r $COUCHDB_RESPAWN_TIMEOUT" |
622 | - fi |
623 | - run_command "$command" > /dev/null |
624 | -} |
625 | - |
626 | -stop_couchdb () { |
627 | - # Stop the running Apache CouchDB process. |
628 | - |
629 | - run_command "$COUCHDB -d" > /dev/null |
630 | -} |
631 | - |
632 | -display_status () { |
633 | - # Display the status of the running Apache CouchDB process. |
634 | - |
635 | - run_command "$COUCHDB -s" |
636 | -} |
637 | - |
638 | -parse_script_option_list () { |
639 | - # Parse arguments passed to the script and take appropriate action. |
640 | - |
641 | - case "$1" in |
642 | - start) |
643 | - log_daemon_msg "Starting $DESCRIPTION" $NAME |
644 | - if start_couchdb; then |
645 | - log_end_msg $SCRIPT_OK |
646 | - else |
647 | - log_end_msg $SCRIPT_ERROR |
648 | - fi |
649 | - ;; |
650 | - stop) |
651 | - log_daemon_msg "Stopping $DESCRIPTION" $NAME |
652 | - if stop_couchdb; then |
653 | - log_end_msg $SCRIPT_OK |
654 | - else |
655 | - log_end_msg $SCRIPT_ERROR |
656 | - fi |
657 | - ;; |
658 | - restart) |
659 | - log_daemon_msg "Restarting $DESCRIPTION" $NAME |
660 | - if stop_couchdb; then |
661 | - if start_couchdb; then |
662 | - log_end_msg $SCRIPT_OK |
663 | - else |
664 | - log_end_msg $SCRIPT_ERROR |
665 | - fi |
666 | - else |
667 | - log_end_msg $SCRIPT_ERROR |
668 | - fi |
669 | - ;; |
670 | - status) |
671 | - display_status |
672 | - ;; |
673 | - *) |
674 | - cat << EOF >&2 |
675 | -Usage: $SCRIPT_NAME {start|stop|restart|status} |
676 | -EOF |
677 | - exit $SCRIPT_ERROR |
678 | - ;; |
679 | - esac |
680 | -} |
681 | - |
682 | -parse_script_option_list $@ |
683 | |
684 | === removed directory '.pc/improve_parsing_of_mochiweb_relative_paths.patch' |
685 | === removed directory '.pc/improve_parsing_of_mochiweb_relative_paths.patch/src' |
686 | === removed directory '.pc/improve_parsing_of_mochiweb_relative_paths.patch/src/mochiweb' |
687 | === removed file '.pc/improve_parsing_of_mochiweb_relative_paths.patch/src/mochiweb/mochiweb_util.erl' |
688 | --- .pc/improve_parsing_of_mochiweb_relative_paths.patch/src/mochiweb/mochiweb_util.erl 2013-01-18 22:04:32 +0000 |
689 | +++ .pc/improve_parsing_of_mochiweb_relative_paths.patch/src/mochiweb/mochiweb_util.erl 1970-01-01 00:00:00 +0000 |
690 | @@ -1,973 +0,0 @@ |
691 | -%% @author Bob Ippolito <bob@mochimedia.com> |
692 | -%% @copyright 2007 Mochi Media, Inc. |
693 | - |
694 | -%% @doc Utilities for parsing and quoting. |
695 | - |
696 | --module(mochiweb_util). |
697 | --author('bob@mochimedia.com'). |
698 | --export([join/2, quote_plus/1, urlencode/1, parse_qs/1, unquote/1]). |
699 | --export([path_split/1]). |
700 | --export([urlsplit/1, urlsplit_path/1, urlunsplit/1, urlunsplit_path/1]). |
701 | --export([guess_mime/1, parse_header/1]). |
702 | --export([shell_quote/1, cmd/1, cmd_string/1, cmd_port/2, cmd_status/1]). |
703 | --export([record_to_proplist/2, record_to_proplist/3]). |
704 | --export([safe_relative_path/1, partition/2]). |
705 | --export([parse_qvalues/1, pick_accepted_encodings/3]). |
706 | --export([make_io/1]). |
707 | - |
708 | --define(PERCENT, 37). % $\% |
709 | --define(FULLSTOP, 46). % $\. |
710 | --define(IS_HEX(C), ((C >= $0 andalso C =< $9) orelse |
711 | - (C >= $a andalso C =< $f) orelse |
712 | - (C >= $A andalso C =< $F))). |
713 | --define(QS_SAFE(C), ((C >= $a andalso C =< $z) orelse |
714 | - (C >= $A andalso C =< $Z) orelse |
715 | - (C >= $0 andalso C =< $9) orelse |
716 | - (C =:= ?FULLSTOP orelse C =:= $- orelse C =:= $~ orelse |
717 | - C =:= $_))). |
718 | - |
719 | -hexdigit(C) when C < 10 -> $0 + C; |
720 | -hexdigit(C) when C < 16 -> $A + (C - 10). |
721 | - |
722 | -unhexdigit(C) when C >= $0, C =< $9 -> C - $0; |
723 | -unhexdigit(C) when C >= $a, C =< $f -> C - $a + 10; |
724 | -unhexdigit(C) when C >= $A, C =< $F -> C - $A + 10. |
725 | - |
726 | -%% @spec partition(String, Sep) -> {String, [], []} | {Prefix, Sep, Postfix} |
727 | -%% @doc Inspired by Python 2.5's str.partition: |
728 | -%% partition("foo/bar", "/") = {"foo", "/", "bar"}, |
729 | -%% partition("foo", "/") = {"foo", "", ""}. |
730 | -partition(String, Sep) -> |
731 | - case partition(String, Sep, []) of |
732 | - undefined -> |
733 | - {String, "", ""}; |
734 | - Result -> |
735 | - Result |
736 | - end. |
737 | - |
738 | -partition("", _Sep, _Acc) -> |
739 | - undefined; |
740 | -partition(S, Sep, Acc) -> |
741 | - case partition2(S, Sep) of |
742 | - undefined -> |
743 | - [C | Rest] = S, |
744 | - partition(Rest, Sep, [C | Acc]); |
745 | - Rest -> |
746 | - {lists:reverse(Acc), Sep, Rest} |
747 | - end. |
748 | - |
749 | -partition2(Rest, "") -> |
750 | - Rest; |
751 | -partition2([C | R1], [C | R2]) -> |
752 | - partition2(R1, R2); |
753 | -partition2(_S, _Sep) -> |
754 | - undefined. |
755 | - |
756 | - |
757 | - |
758 | -%% @spec safe_relative_path(string()) -> string() | undefined |
759 | -%% @doc Return the reduced version of a relative path or undefined if it |
760 | -%% is not safe. safe relative paths can be joined with an absolute path |
761 | -%% and will result in a subdirectory of the absolute path. |
762 | -safe_relative_path("/" ++ _) -> |
763 | - undefined; |
764 | -safe_relative_path(P) -> |
765 | - safe_relative_path(P, []). |
766 | - |
767 | -safe_relative_path("", Acc) -> |
768 | - case Acc of |
769 | - [] -> |
770 | - ""; |
771 | - _ -> |
772 | - string:join(lists:reverse(Acc), "/") |
773 | - end; |
774 | -safe_relative_path(P, Acc) -> |
775 | - case partition(P, "/") of |
776 | - {"", "/", _} -> |
777 | - %% /foo or foo//bar |
778 | - undefined; |
779 | - {"..", _, _} when Acc =:= [] -> |
780 | - undefined; |
781 | - {"..", _, Rest} -> |
782 | - safe_relative_path(Rest, tl(Acc)); |
783 | - {Part, "/", ""} -> |
784 | - safe_relative_path("", ["", Part | Acc]); |
785 | - {Part, _, Rest} -> |
786 | - safe_relative_path(Rest, [Part | Acc]) |
787 | - end. |
788 | - |
789 | -%% @spec shell_quote(string()) -> string() |
790 | -%% @doc Quote a string according to UNIX shell quoting rules, returns a string |
791 | -%% surrounded by double quotes. |
792 | -shell_quote(L) -> |
793 | - shell_quote(L, [$\"]). |
794 | - |
795 | -%% @spec cmd_port([string()], Options) -> port() |
796 | -%% @doc open_port({spawn, mochiweb_util:cmd_string(Argv)}, Options). |
797 | -cmd_port(Argv, Options) -> |
798 | - open_port({spawn, cmd_string(Argv)}, Options). |
799 | - |
800 | -%% @spec cmd([string()]) -> string() |
801 | -%% @doc os:cmd(cmd_string(Argv)). |
802 | -cmd(Argv) -> |
803 | - os:cmd(cmd_string(Argv)). |
804 | - |
805 | -%% @spec cmd_string([string()]) -> string() |
806 | -%% @doc Create a shell quoted command string from a list of arguments. |
807 | -cmd_string(Argv) -> |
808 | - string:join([shell_quote(X) || X <- Argv], " "). |
809 | - |
810 | -%% @spec cmd_status([string()]) -> {ExitStatus::integer(), Stdout::binary()} |
811 | -%% @doc Accumulate the output and exit status from the given application, will be |
812 | -%% spawned with cmd_port/2. |
813 | -cmd_status(Argv) -> |
814 | - Port = cmd_port(Argv, [exit_status, stderr_to_stdout, |
815 | - use_stdio, binary]), |
816 | - try cmd_loop(Port, []) |
817 | - after catch port_close(Port) |
818 | - end. |
819 | - |
820 | -%% @spec cmd_loop(port(), list()) -> {ExitStatus::integer(), Stdout::binary()} |
821 | -%% @doc Accumulate the output and exit status from a port. |
822 | -cmd_loop(Port, Acc) -> |
823 | - receive |
824 | - {Port, {exit_status, Status}} -> |
825 | - {Status, iolist_to_binary(lists:reverse(Acc))}; |
826 | - {Port, {data, Data}} -> |
827 | - cmd_loop(Port, [Data | Acc]) |
828 | - end. |
829 | - |
830 | -%% @spec join([iolist()], iolist()) -> iolist() |
831 | -%% @doc Join a list of strings or binaries together with the given separator |
832 | -%% string or char or binary. The output is flattened, but may be an |
833 | -%% iolist() instead of a string() if any of the inputs are binary(). |
834 | -join([], _Separator) -> |
835 | - []; |
836 | -join([S], _Separator) -> |
837 | - lists:flatten(S); |
838 | -join(Strings, Separator) -> |
839 | - lists:flatten(revjoin(lists:reverse(Strings), Separator, [])). |
840 | - |
841 | -revjoin([], _Separator, Acc) -> |
842 | - Acc; |
843 | -revjoin([S | Rest], Separator, []) -> |
844 | - revjoin(Rest, Separator, [S]); |
845 | -revjoin([S | Rest], Separator, Acc) -> |
846 | - revjoin(Rest, Separator, [S, Separator | Acc]). |
847 | - |
848 | -%% @spec quote_plus(atom() | integer() | float() | string() | binary()) -> string() |
849 | -%% @doc URL safe encoding of the given term. |
850 | -quote_plus(Atom) when is_atom(Atom) -> |
851 | - quote_plus(atom_to_list(Atom)); |
852 | -quote_plus(Int) when is_integer(Int) -> |
853 | - quote_plus(integer_to_list(Int)); |
854 | -quote_plus(Binary) when is_binary(Binary) -> |
855 | - quote_plus(binary_to_list(Binary)); |
856 | -quote_plus(Float) when is_float(Float) -> |
857 | - quote_plus(mochinum:digits(Float)); |
858 | -quote_plus(String) -> |
859 | - quote_plus(String, []). |
860 | - |
861 | -quote_plus([], Acc) -> |
862 | - lists:reverse(Acc); |
863 | -quote_plus([C | Rest], Acc) when ?QS_SAFE(C) -> |
864 | - quote_plus(Rest, [C | Acc]); |
865 | -quote_plus([$\s | Rest], Acc) -> |
866 | - quote_plus(Rest, [$+ | Acc]); |
867 | -quote_plus([C | Rest], Acc) -> |
868 | - <<Hi:4, Lo:4>> = <<C>>, |
869 | - quote_plus(Rest, [hexdigit(Lo), hexdigit(Hi), ?PERCENT | Acc]). |
870 | - |
871 | -%% @spec urlencode([{Key, Value}]) -> string() |
872 | -%% @doc URL encode the property list. |
873 | -urlencode(Props) -> |
874 | - Pairs = lists:foldr( |
875 | - fun ({K, V}, Acc) -> |
876 | - [quote_plus(K) ++ "=" ++ quote_plus(V) | Acc] |
877 | - end, [], Props), |
878 | - string:join(Pairs, "&"). |
879 | - |
880 | -%% @spec parse_qs(string() | binary()) -> [{Key, Value}] |
881 | -%% @doc Parse a query string or application/x-www-form-urlencoded. |
882 | -parse_qs(Binary) when is_binary(Binary) -> |
883 | - parse_qs(binary_to_list(Binary)); |
884 | -parse_qs(String) -> |
885 | - parse_qs(String, []). |
886 | - |
887 | -parse_qs([], Acc) -> |
888 | - lists:reverse(Acc); |
889 | -parse_qs(String, Acc) -> |
890 | - {Key, Rest} = parse_qs_key(String), |
891 | - {Value, Rest1} = parse_qs_value(Rest), |
892 | - parse_qs(Rest1, [{Key, Value} | Acc]). |
893 | - |
894 | -parse_qs_key(String) -> |
895 | - parse_qs_key(String, []). |
896 | - |
897 | -parse_qs_key([], Acc) -> |
898 | - {qs_revdecode(Acc), ""}; |
899 | -parse_qs_key([$= | Rest], Acc) -> |
900 | - {qs_revdecode(Acc), Rest}; |
901 | -parse_qs_key(Rest=[$; | _], Acc) -> |
902 | - {qs_revdecode(Acc), Rest}; |
903 | -parse_qs_key(Rest=[$& | _], Acc) -> |
904 | - {qs_revdecode(Acc), Rest}; |
905 | -parse_qs_key([C | Rest], Acc) -> |
906 | - parse_qs_key(Rest, [C | Acc]). |
907 | - |
908 | -parse_qs_value(String) -> |
909 | - parse_qs_value(String, []). |
910 | - |
911 | -parse_qs_value([], Acc) -> |
912 | - {qs_revdecode(Acc), ""}; |
913 | -parse_qs_value([$; | Rest], Acc) -> |
914 | - {qs_revdecode(Acc), Rest}; |
915 | -parse_qs_value([$& | Rest], Acc) -> |
916 | - {qs_revdecode(Acc), Rest}; |
917 | -parse_qs_value([C | Rest], Acc) -> |
918 | - parse_qs_value(Rest, [C | Acc]). |
919 | - |
920 | -%% @spec unquote(string() | binary()) -> string() |
921 | -%% @doc Unquote a URL encoded string. |
922 | -unquote(Binary) when is_binary(Binary) -> |
923 | - unquote(binary_to_list(Binary)); |
924 | -unquote(String) -> |
925 | - qs_revdecode(lists:reverse(String)). |
926 | - |
927 | -qs_revdecode(S) -> |
928 | - qs_revdecode(S, []). |
929 | - |
930 | -qs_revdecode([], Acc) -> |
931 | - Acc; |
932 | -qs_revdecode([$+ | Rest], Acc) -> |
933 | - qs_revdecode(Rest, [$\s | Acc]); |
934 | -qs_revdecode([Lo, Hi, ?PERCENT | Rest], Acc) when ?IS_HEX(Lo), ?IS_HEX(Hi) -> |
935 | - qs_revdecode(Rest, [(unhexdigit(Lo) bor (unhexdigit(Hi) bsl 4)) | Acc]); |
936 | -qs_revdecode([C | Rest], Acc) -> |
937 | - qs_revdecode(Rest, [C | Acc]). |
938 | - |
939 | -%% @spec urlsplit(Url) -> {Scheme, Netloc, Path, Query, Fragment} |
940 | -%% @doc Return a 5-tuple, does not expand % escapes. Only supports HTTP style |
941 | -%% URLs. |
942 | -urlsplit(Url) -> |
943 | - {Scheme, Url1} = urlsplit_scheme(Url), |
944 | - {Netloc, Url2} = urlsplit_netloc(Url1), |
945 | - {Path, Query, Fragment} = urlsplit_path(Url2), |
946 | - {Scheme, Netloc, Path, Query, Fragment}. |
947 | - |
948 | -urlsplit_scheme(Url) -> |
949 | - case urlsplit_scheme(Url, []) of |
950 | - no_scheme -> |
951 | - {"", Url}; |
952 | - Res -> |
953 | - Res |
954 | - end. |
955 | - |
956 | -urlsplit_scheme([C | Rest], Acc) when ((C >= $a andalso C =< $z) orelse |
957 | - (C >= $A andalso C =< $Z) orelse |
958 | - (C >= $0 andalso C =< $9) orelse |
959 | - C =:= $+ orelse C =:= $- orelse |
960 | - C =:= $.) -> |
961 | - urlsplit_scheme(Rest, [C | Acc]); |
962 | -urlsplit_scheme([$: | Rest], Acc=[_ | _]) -> |
963 | - {string:to_lower(lists:reverse(Acc)), Rest}; |
964 | -urlsplit_scheme(_Rest, _Acc) -> |
965 | - no_scheme. |
966 | - |
967 | -urlsplit_netloc("//" ++ Rest) -> |
968 | - urlsplit_netloc(Rest, []); |
969 | -urlsplit_netloc(Path) -> |
970 | - {"", Path}. |
971 | - |
972 | -urlsplit_netloc("", Acc) -> |
973 | - {lists:reverse(Acc), ""}; |
974 | -urlsplit_netloc(Rest=[C | _], Acc) when C =:= $/; C =:= $?; C =:= $# -> |
975 | - {lists:reverse(Acc), Rest}; |
976 | -urlsplit_netloc([C | Rest], Acc) -> |
977 | - urlsplit_netloc(Rest, [C | Acc]). |
978 | - |
979 | - |
980 | -%% @spec path_split(string()) -> {Part, Rest} |
981 | -%% @doc Split a path starting from the left, as in URL traversal. |
982 | -%% path_split("foo/bar") = {"foo", "bar"}, |
983 | -%% path_split("/foo/bar") = {"", "foo/bar"}. |
984 | -path_split(S) -> |
985 | - path_split(S, []). |
986 | - |
987 | -path_split("", Acc) -> |
988 | - {lists:reverse(Acc), ""}; |
989 | -path_split("/" ++ Rest, Acc) -> |
990 | - {lists:reverse(Acc), Rest}; |
991 | -path_split([C | Rest], Acc) -> |
992 | - path_split(Rest, [C | Acc]). |
993 | - |
994 | - |
995 | -%% @spec urlunsplit({Scheme, Netloc, Path, Query, Fragment}) -> string() |
996 | -%% @doc Assemble a URL from the 5-tuple. Path must be absolute. |
997 | -urlunsplit({Scheme, Netloc, Path, Query, Fragment}) -> |
998 | - lists:flatten([case Scheme of "" -> ""; _ -> [Scheme, "://"] end, |
999 | - Netloc, |
1000 | - urlunsplit_path({Path, Query, Fragment})]). |
1001 | - |
1002 | -%% @spec urlunsplit_path({Path, Query, Fragment}) -> string() |
1003 | -%% @doc Assemble a URL path from the 3-tuple. |
1004 | -urlunsplit_path({Path, Query, Fragment}) -> |
1005 | - lists:flatten([Path, |
1006 | - case Query of "" -> ""; _ -> [$? | Query] end, |
1007 | - case Fragment of "" -> ""; _ -> [$# | Fragment] end]). |
1008 | - |
1009 | -%% @spec urlsplit_path(Url) -> {Path, Query, Fragment} |
1010 | -%% @doc Return a 3-tuple, does not expand % escapes. Only supports HTTP style |
1011 | -%% paths. |
1012 | -urlsplit_path(Path) -> |
1013 | - urlsplit_path(Path, []). |
1014 | - |
1015 | -urlsplit_path("", Acc) -> |
1016 | - {lists:reverse(Acc), "", ""}; |
1017 | -urlsplit_path("?" ++ Rest, Acc) -> |
1018 | - {Query, Fragment} = urlsplit_query(Rest), |
1019 | - {lists:reverse(Acc), Query, Fragment}; |
1020 | -urlsplit_path("#" ++ Rest, Acc) -> |
1021 | - {lists:reverse(Acc), "", Rest}; |
1022 | -urlsplit_path([C | Rest], Acc) -> |
1023 | - urlsplit_path(Rest, [C | Acc]). |
1024 | - |
1025 | -urlsplit_query(Query) -> |
1026 | - urlsplit_query(Query, []). |
1027 | - |
1028 | -urlsplit_query("", Acc) -> |
1029 | - {lists:reverse(Acc), ""}; |
1030 | -urlsplit_query("#" ++ Rest, Acc) -> |
1031 | - {lists:reverse(Acc), Rest}; |
1032 | -urlsplit_query([C | Rest], Acc) -> |
1033 | - urlsplit_query(Rest, [C | Acc]). |
1034 | - |
1035 | -%% @spec guess_mime(string()) -> string() |
1036 | -%% @doc Guess the mime type of a file by the extension of its filename. |
1037 | -guess_mime(File) -> |
1038 | - case mochiweb_mime:from_extension(filename:extension(File)) of |
1039 | - undefined -> |
1040 | - "text/plain"; |
1041 | - Mime -> |
1042 | - Mime |
1043 | - end. |
1044 | - |
1045 | -%% @spec parse_header(string()) -> {Type, [{K, V}]} |
1046 | -%% @doc Parse a Content-Type like header, return the main Content-Type |
1047 | -%% and a property list of options. |
1048 | -parse_header(String) -> |
1049 | - %% TODO: This is exactly as broken as Python's cgi module. |
1050 | - %% Should parse properly like mochiweb_cookies. |
1051 | - [Type | Parts] = [string:strip(S) || S <- string:tokens(String, ";")], |
1052 | - F = fun (S, Acc) -> |
1053 | - case lists:splitwith(fun (C) -> C =/= $= end, S) of |
1054 | - {"", _} -> |
1055 | - %% Skip anything with no name |
1056 | - Acc; |
1057 | - {_, ""} -> |
1058 | - %% Skip anything with no value |
1059 | - Acc; |
1060 | - {Name, [$\= | Value]} -> |
1061 | - [{string:to_lower(string:strip(Name)), |
1062 | - unquote_header(string:strip(Value))} | Acc] |
1063 | - end |
1064 | - end, |
1065 | - {string:to_lower(Type), |
1066 | - lists:foldr(F, [], Parts)}. |
1067 | - |
1068 | -unquote_header("\"" ++ Rest) -> |
1069 | - unquote_header(Rest, []); |
1070 | -unquote_header(S) -> |
1071 | - S. |
1072 | - |
1073 | -unquote_header("", Acc) -> |
1074 | - lists:reverse(Acc); |
1075 | -unquote_header("\"", Acc) -> |
1076 | - lists:reverse(Acc); |
1077 | -unquote_header([$\\, C | Rest], Acc) -> |
1078 | - unquote_header(Rest, [C | Acc]); |
1079 | -unquote_header([C | Rest], Acc) -> |
1080 | - unquote_header(Rest, [C | Acc]). |
1081 | - |
1082 | -%% @spec record_to_proplist(Record, Fields) -> proplist() |
1083 | -%% @doc calls record_to_proplist/3 with a default TypeKey of '__record' |
1084 | -record_to_proplist(Record, Fields) -> |
1085 | - record_to_proplist(Record, Fields, '__record'). |
1086 | - |
1087 | -%% @spec record_to_proplist(Record, Fields, TypeKey) -> proplist() |
1088 | -%% @doc Return a proplist of the given Record with each field in the |
1089 | -%% Fields list set as a key with the corresponding value in the Record. |
1090 | -%% TypeKey is the key that is used to store the record type |
1091 | -%% Fields should be obtained by calling record_info(fields, record_type) |
1092 | -%% where record_type is the record type of Record |
1093 | -record_to_proplist(Record, Fields, TypeKey) |
1094 | - when tuple_size(Record) - 1 =:= length(Fields) -> |
1095 | - lists:zip([TypeKey | Fields], tuple_to_list(Record)). |
1096 | - |
1097 | - |
1098 | -shell_quote([], Acc) -> |
1099 | - lists:reverse([$\" | Acc]); |
1100 | -shell_quote([C | Rest], Acc) when C =:= $\" orelse C =:= $\` orelse |
1101 | - C =:= $\\ orelse C =:= $\$ -> |
1102 | - shell_quote(Rest, [C, $\\ | Acc]); |
1103 | -shell_quote([C | Rest], Acc) -> |
1104 | - shell_quote(Rest, [C | Acc]). |
1105 | - |
1106 | -%% @spec parse_qvalues(string()) -> [qvalue()] | invalid_qvalue_string |
1107 | -%% @type qvalue() = {media_type() | encoding() , float()}. |
1108 | -%% @type media_type() = string(). |
1109 | -%% @type encoding() = string(). |
1110 | -%% |
1111 | -%% @doc Parses a list (given as a string) of elements with Q values associated |
1112 | -%% to them. Elements are separated by commas and each element is separated |
1113 | -%% from its Q value by a semicolon. Q values are optional but when missing |
1114 | -%% the value of an element is considered as 1.0. A Q value is always in the |
1115 | -%% range [0.0, 1.0]. A Q value list is used for example as the value of the |
1116 | -%% HTTP "Accept" and "Accept-Encoding" headers. |
1117 | -%% |
1118 | -%% Q values are described in section 2.9 of the RFC 2616 (HTTP 1.1). |
1119 | -%% |
1120 | -%% Example: |
1121 | -%% |
1122 | -%% parse_qvalues("gzip; q=0.5, deflate, identity;q=0.0") -> |
1123 | -%% [{"gzip", 0.5}, {"deflate", 1.0}, {"identity", 0.0}] |
1124 | -%% |
1125 | -parse_qvalues(QValuesStr) -> |
1126 | - try |
1127 | - lists:map( |
1128 | - fun(Pair) -> |
1129 | - [Type | Params] = string:tokens(Pair, ";"), |
1130 | - NormParams = normalize_media_params(Params), |
1131 | - {Q, NonQParams} = extract_q(NormParams), |
1132 | - {string:join([string:strip(Type) | NonQParams], ";"), Q} |
1133 | - end, |
1134 | - string:tokens(string:to_lower(QValuesStr), ",") |
1135 | - ) |
1136 | - catch |
1137 | - _Type:_Error -> |
1138 | - invalid_qvalue_string |
1139 | - end. |
1140 | - |
1141 | -normalize_media_params(Params) -> |
1142 | - {ok, Re} = re:compile("\\s"), |
1143 | - normalize_media_params(Re, Params, []). |
1144 | - |
1145 | -normalize_media_params(_Re, [], Acc) -> |
1146 | - lists:reverse(Acc); |
1147 | -normalize_media_params(Re, [Param | Rest], Acc) -> |
1148 | - NormParam = re:replace(Param, Re, "", [global, {return, list}]), |
1149 | - normalize_media_params(Re, Rest, [NormParam | Acc]). |
1150 | - |
1151 | -extract_q(NormParams) -> |
1152 | - {ok, KVRe} = re:compile("^([^=]+)=([^=]+)$"), |
1153 | - {ok, QRe} = re:compile("^((?:0|1)(?:\\.\\d{1,3})?)$"), |
1154 | - extract_q(KVRe, QRe, NormParams, []). |
1155 | - |
1156 | -extract_q(_KVRe, _QRe, [], Acc) -> |
1157 | - {1.0, lists:reverse(Acc)}; |
1158 | -extract_q(KVRe, QRe, [Param | Rest], Acc) -> |
1159 | - case re:run(Param, KVRe, [{capture, [1, 2], list}]) of |
1160 | - {match, [Name, Value]} -> |
1161 | - case Name of |
1162 | - "q" -> |
1163 | - {match, [Q]} = re:run(Value, QRe, [{capture, [1], list}]), |
1164 | - QVal = case Q of |
1165 | - "0" -> |
1166 | - 0.0; |
1167 | - "1" -> |
1168 | - 1.0; |
1169 | - Else -> |
1170 | - list_to_float(Else) |
1171 | - end, |
1172 | - case QVal < 0.0 orelse QVal > 1.0 of |
1173 | - false -> |
1174 | - {QVal, lists:reverse(Acc) ++ Rest} |
1175 | - end; |
1176 | - _ -> |
1177 | - extract_q(KVRe, QRe, Rest, [Param | Acc]) |
1178 | - end |
1179 | - end. |
1180 | - |
1181 | -%% @spec pick_accepted_encodings([qvalue()], [encoding()], encoding()) -> |
1182 | -%% [encoding()] |
1183 | -%% |
1184 | -%% @doc Determines which encodings specified in the given Q values list are |
1185 | -%% valid according to a list of supported encodings and a default encoding. |
1186 | -%% |
1187 | -%% The returned list of encodings is sorted, descendingly, according to the |
1188 | -%% Q values of the given list. The last element of this list is the given |
1189 | -%% default encoding unless this encoding is explicitily or implicitily |
1190 | -%% marked with a Q value of 0.0 in the given Q values list. |
1191 | -%% Note: encodings with the same Q value are kept in the same order as |
1192 | -%% found in the input Q values list. |
1193 | -%% |
1194 | -%% This encoding picking process is described in section 14.3 of the |
1195 | -%% RFC 2616 (HTTP 1.1). |
1196 | -%% |
1197 | -%% Example: |
1198 | -%% |
1199 | -%% pick_accepted_encodings( |
1200 | -%% [{"gzip", 0.5}, {"deflate", 1.0}], |
1201 | -%% ["gzip", "identity"], |
1202 | -%% "identity" |
1203 | -%% ) -> |
1204 | -%% ["gzip", "identity"] |
1205 | -%% |
1206 | -pick_accepted_encodings(AcceptedEncs, SupportedEncs, DefaultEnc) -> |
1207 | - SortedQList = lists:reverse( |
1208 | - lists:sort(fun({_, Q1}, {_, Q2}) -> Q1 < Q2 end, AcceptedEncs) |
1209 | - ), |
1210 | - {Accepted, Refused} = lists:foldr( |
1211 | - fun({E, Q}, {A, R}) -> |
1212 | - case Q > 0.0 of |
1213 | - true -> |
1214 | - {[E | A], R}; |
1215 | - false -> |
1216 | - {A, [E | R]} |
1217 | - end |
1218 | - end, |
1219 | - {[], []}, |
1220 | - SortedQList |
1221 | - ), |
1222 | - Refused1 = lists:foldr( |
1223 | - fun(Enc, Acc) -> |
1224 | - case Enc of |
1225 | - "*" -> |
1226 | - lists:subtract(SupportedEncs, Accepted) ++ Acc; |
1227 | - _ -> |
1228 | - [Enc | Acc] |
1229 | - end |
1230 | - end, |
1231 | - [], |
1232 | - Refused |
1233 | - ), |
1234 | - Accepted1 = lists:foldr( |
1235 | - fun(Enc, Acc) -> |
1236 | - case Enc of |
1237 | - "*" -> |
1238 | - lists:subtract(SupportedEncs, Accepted ++ Refused1) ++ Acc; |
1239 | - _ -> |
1240 | - [Enc | Acc] |
1241 | - end |
1242 | - end, |
1243 | - [], |
1244 | - Accepted |
1245 | - ), |
1246 | - Accepted2 = case lists:member(DefaultEnc, Accepted1) of |
1247 | - true -> |
1248 | - Accepted1; |
1249 | - false -> |
1250 | - Accepted1 ++ [DefaultEnc] |
1251 | - end, |
1252 | - [E || E <- Accepted2, lists:member(E, SupportedEncs), |
1253 | - not lists:member(E, Refused1)]. |
1254 | - |
1255 | -make_io(Atom) when is_atom(Atom) -> |
1256 | - atom_to_list(Atom); |
1257 | -make_io(Integer) when is_integer(Integer) -> |
1258 | - integer_to_list(Integer); |
1259 | -make_io(Io) when is_list(Io); is_binary(Io) -> |
1260 | - Io. |
1261 | - |
1262 | -%% |
1263 | -%% Tests |
1264 | -%% |
1265 | --include_lib("eunit/include/eunit.hrl"). |
1266 | --ifdef(TEST). |
1267 | - |
1268 | -make_io_test() -> |
1269 | - ?assertEqual( |
1270 | - <<"atom">>, |
1271 | - iolist_to_binary(make_io(atom))), |
1272 | - ?assertEqual( |
1273 | - <<"20">>, |
1274 | - iolist_to_binary(make_io(20))), |
1275 | - ?assertEqual( |
1276 | - <<"list">>, |
1277 | - iolist_to_binary(make_io("list"))), |
1278 | - ?assertEqual( |
1279 | - <<"binary">>, |
1280 | - iolist_to_binary(make_io(<<"binary">>))), |
1281 | - ok. |
1282 | - |
1283 | --record(test_record, {field1=f1, field2=f2}). |
1284 | -record_to_proplist_test() -> |
1285 | - ?assertEqual( |
1286 | - [{'__record', test_record}, |
1287 | - {field1, f1}, |
1288 | - {field2, f2}], |
1289 | - record_to_proplist(#test_record{}, record_info(fields, test_record))), |
1290 | - ?assertEqual( |
1291 | - [{'typekey', test_record}, |
1292 | - {field1, f1}, |
1293 | - {field2, f2}], |
1294 | - record_to_proplist(#test_record{}, |
1295 | - record_info(fields, test_record), |
1296 | - typekey)), |
1297 | - ok. |
1298 | - |
1299 | -shell_quote_test() -> |
1300 | - ?assertEqual( |
1301 | - "\"foo \\$bar\\\"\\`' baz\"", |
1302 | - shell_quote("foo $bar\"`' baz")), |
1303 | - ok. |
1304 | - |
1305 | -cmd_port_test_spool(Port, Acc) -> |
1306 | - receive |
1307 | - {Port, eof} -> |
1308 | - Acc; |
1309 | - {Port, {data, {eol, Data}}} -> |
1310 | - cmd_port_test_spool(Port, ["\n", Data | Acc]); |
1311 | - {Port, Unknown} -> |
1312 | - throw({unknown, Unknown}) |
1313 | - after 1000 -> |
1314 | - throw(timeout) |
1315 | - end. |
1316 | - |
1317 | -cmd_port_test() -> |
1318 | - Port = cmd_port(["echo", "$bling$ `word`!"], |
1319 | - [eof, stream, {line, 4096}]), |
1320 | - Res = try lists:append(lists:reverse(cmd_port_test_spool(Port, []))) |
1321 | - after catch port_close(Port) |
1322 | - end, |
1323 | - self() ! {Port, wtf}, |
1324 | - try cmd_port_test_spool(Port, []) |
1325 | - catch throw:{unknown, wtf} -> ok |
1326 | - end, |
1327 | - try cmd_port_test_spool(Port, []) |
1328 | - catch throw:timeout -> ok |
1329 | - end, |
1330 | - ?assertEqual( |
1331 | - "$bling$ `word`!\n", |
1332 | - Res). |
1333 | - |
1334 | -cmd_test() -> |
1335 | - ?assertEqual( |
1336 | - "$bling$ `word`!\n", |
1337 | - cmd(["echo", "$bling$ `word`!"])), |
1338 | - ok. |
1339 | - |
1340 | -cmd_string_test() -> |
1341 | - ?assertEqual( |
1342 | - "\"echo\" \"\\$bling\\$ \\`word\\`!\"", |
1343 | - cmd_string(["echo", "$bling$ `word`!"])), |
1344 | - ok. |
1345 | - |
1346 | -cmd_status_test() -> |
1347 | - ?assertEqual( |
1348 | - {0, <<"$bling$ `word`!\n">>}, |
1349 | - cmd_status(["echo", "$bling$ `word`!"])), |
1350 | - ok. |
1351 | - |
1352 | - |
1353 | -parse_header_test() -> |
1354 | - ?assertEqual( |
1355 | - {"multipart/form-data", [{"boundary", "AaB03x"}]}, |
1356 | - parse_header("multipart/form-data; boundary=AaB03x")), |
1357 | - %% This tests (currently) intentionally broken behavior |
1358 | - ?assertEqual( |
1359 | - {"multipart/form-data", |
1360 | - [{"b", ""}, |
1361 | - {"cgi", "is"}, |
1362 | - {"broken", "true\"e"}]}, |
1363 | - parse_header("multipart/form-data;b=;cgi=\"i\\s;broken=true\"e;=z;z")), |
1364 | - ok. |
1365 | - |
1366 | -guess_mime_test() -> |
1367 | - "text/plain" = guess_mime(""), |
1368 | - "text/plain" = guess_mime(".text"), |
1369 | - "application/zip" = guess_mime(".zip"), |
1370 | - "application/zip" = guess_mime("x.zip"), |
1371 | - "text/html" = guess_mime("x.html"), |
1372 | - "application/xhtml+xml" = guess_mime("x.xhtml"), |
1373 | - ok. |
1374 | - |
1375 | -path_split_test() -> |
1376 | - {"", "foo/bar"} = path_split("/foo/bar"), |
1377 | - {"foo", "bar"} = path_split("foo/bar"), |
1378 | - {"bar", ""} = path_split("bar"), |
1379 | - ok. |
1380 | - |
1381 | -urlsplit_test() -> |
1382 | - {"", "", "/foo", "", "bar?baz"} = urlsplit("/foo#bar?baz"), |
1383 | - {"http", "host:port", "/foo", "", "bar?baz"} = |
1384 | - urlsplit("http://host:port/foo#bar?baz"), |
1385 | - {"http", "host", "", "", ""} = urlsplit("http://host"), |
1386 | - {"", "", "/wiki/Category:Fruit", "", ""} = |
1387 | - urlsplit("/wiki/Category:Fruit"), |
1388 | - ok. |
1389 | - |
1390 | -urlsplit_path_test() -> |
1391 | - {"/foo/bar", "", ""} = urlsplit_path("/foo/bar"), |
1392 | - {"/foo", "baz", ""} = urlsplit_path("/foo?baz"), |
1393 | - {"/foo", "", "bar?baz"} = urlsplit_path("/foo#bar?baz"), |
1394 | - {"/foo", "", "bar?baz#wibble"} = urlsplit_path("/foo#bar?baz#wibble"), |
1395 | - {"/foo", "bar", "baz"} = urlsplit_path("/foo?bar#baz"), |
1396 | - {"/foo", "bar?baz", "baz"} = urlsplit_path("/foo?bar?baz#baz"), |
1397 | - ok. |
1398 | - |
1399 | -urlunsplit_test() -> |
1400 | - "/foo#bar?baz" = urlunsplit({"", "", "/foo", "", "bar?baz"}), |
1401 | - "http://host:port/foo#bar?baz" = |
1402 | - urlunsplit({"http", "host:port", "/foo", "", "bar?baz"}), |
1403 | - ok. |
1404 | - |
1405 | -urlunsplit_path_test() -> |
1406 | - "/foo/bar" = urlunsplit_path({"/foo/bar", "", ""}), |
1407 | - "/foo?baz" = urlunsplit_path({"/foo", "baz", ""}), |
1408 | - "/foo#bar?baz" = urlunsplit_path({"/foo", "", "bar?baz"}), |
1409 | - "/foo#bar?baz#wibble" = urlunsplit_path({"/foo", "", "bar?baz#wibble"}), |
1410 | - "/foo?bar#baz" = urlunsplit_path({"/foo", "bar", "baz"}), |
1411 | - "/foo?bar?baz#baz" = urlunsplit_path({"/foo", "bar?baz", "baz"}), |
1412 | - ok. |
1413 | - |
1414 | -join_test() -> |
1415 | - ?assertEqual("foo,bar,baz", |
1416 | - join(["foo", "bar", "baz"], $,)), |
1417 | - ?assertEqual("foo,bar,baz", |
1418 | - join(["foo", "bar", "baz"], ",")), |
1419 | - ?assertEqual("foo bar", |
1420 | - join([["foo", " bar"]], ",")), |
1421 | - ?assertEqual("foo bar,baz", |
1422 | - join([["foo", " bar"], "baz"], ",")), |
1423 | - ?assertEqual("foo", |
1424 | - join(["foo"], ",")), |
1425 | - ?assertEqual("foobarbaz", |
1426 | - join(["foo", "bar", "baz"], "")), |
1427 | - ?assertEqual("foo" ++ [<<>>] ++ "bar" ++ [<<>>] ++ "baz", |
1428 | - join(["foo", "bar", "baz"], <<>>)), |
1429 | - ?assertEqual("foobar" ++ [<<"baz">>], |
1430 | - join(["foo", "bar", <<"baz">>], "")), |
1431 | - ?assertEqual("", |
1432 | - join([], "any")), |
1433 | - ok. |
1434 | - |
1435 | -quote_plus_test() -> |
1436 | - "foo" = quote_plus(foo), |
1437 | - "1" = quote_plus(1), |
1438 | - "1.1" = quote_plus(1.1), |
1439 | - "foo" = quote_plus("foo"), |
1440 | - "foo+bar" = quote_plus("foo bar"), |
1441 | - "foo%0A" = quote_plus("foo\n"), |
1442 | - "foo%0A" = quote_plus("foo\n"), |
1443 | - "foo%3B%26%3D" = quote_plus("foo;&="), |
1444 | - "foo%3B%26%3D" = quote_plus(<<"foo;&=">>), |
1445 | - ok. |
1446 | - |
1447 | -unquote_test() -> |
1448 | - ?assertEqual("foo bar", |
1449 | - unquote("foo+bar")), |
1450 | - ?assertEqual("foo bar", |
1451 | - unquote("foo%20bar")), |
1452 | - ?assertEqual("foo\r\n", |
1453 | - unquote("foo%0D%0A")), |
1454 | - ?assertEqual("foo\r\n", |
1455 | - unquote(<<"foo%0D%0A">>)), |
1456 | - ok. |
1457 | - |
1458 | -urlencode_test() -> |
1459 | - "foo=bar&baz=wibble+%0D%0A&z=1" = urlencode([{foo, "bar"}, |
1460 | - {"baz", "wibble \r\n"}, |
1461 | - {z, 1}]), |
1462 | - ok. |
1463 | - |
1464 | -parse_qs_test() -> |
1465 | - ?assertEqual( |
1466 | - [{"foo", "bar"}, {"baz", "wibble \r\n"}, {"z", "1"}], |
1467 | - parse_qs("foo=bar&baz=wibble+%0D%0a&z=1")), |
1468 | - ?assertEqual( |
1469 | - [{"", "bar"}, {"baz", "wibble \r\n"}, {"z", ""}], |
1470 | - parse_qs("=bar&baz=wibble+%0D%0a&z=")), |
1471 | - ?assertEqual( |
1472 | - [{"foo", "bar"}, {"baz", "wibble \r\n"}, {"z", "1"}], |
1473 | - parse_qs(<<"foo=bar&baz=wibble+%0D%0a&z=1">>)), |
1474 | - ?assertEqual( |
1475 | - [], |
1476 | - parse_qs("")), |
1477 | - ?assertEqual( |
1478 | - [{"foo", ""}, {"bar", ""}, {"baz", ""}], |
1479 | - parse_qs("foo;bar&baz")), |
1480 | - ok. |
1481 | - |
1482 | -partition_test() -> |
1483 | - {"foo", "", ""} = partition("foo", "/"), |
1484 | - {"foo", "/", "bar"} = partition("foo/bar", "/"), |
1485 | - {"foo", "/", ""} = partition("foo/", "/"), |
1486 | - {"", "/", "bar"} = partition("/bar", "/"), |
1487 | - {"f", "oo/ba", "r"} = partition("foo/bar", "oo/ba"), |
1488 | - ok. |
1489 | - |
1490 | -safe_relative_path_test() -> |
1491 | - "foo" = safe_relative_path("foo"), |
1492 | - "foo/" = safe_relative_path("foo/"), |
1493 | - "foo" = safe_relative_path("foo/bar/.."), |
1494 | - "bar" = safe_relative_path("foo/../bar"), |
1495 | - "bar/" = safe_relative_path("foo/../bar/"), |
1496 | - "" = safe_relative_path("foo/.."), |
1497 | - "" = safe_relative_path("foo/../"), |
1498 | - undefined = safe_relative_path("/foo"), |
1499 | - undefined = safe_relative_path("../foo"), |
1500 | - undefined = safe_relative_path("foo/../.."), |
1501 | - undefined = safe_relative_path("foo//"), |
1502 | - ok. |
1503 | - |
1504 | -parse_qvalues_test() -> |
1505 | - [] = parse_qvalues(""), |
1506 | - [{"identity", 0.0}] = parse_qvalues("identity;q=0"), |
1507 | - [{"identity", 0.0}] = parse_qvalues("identity ;q=0"), |
1508 | - [{"identity", 0.0}] = parse_qvalues(" identity; q =0 "), |
1509 | - [{"identity", 0.0}] = parse_qvalues("identity ; q = 0"), |
1510 | - [{"identity", 0.0}] = parse_qvalues("identity ; q= 0.0"), |
1511 | - [{"gzip", 1.0}, {"deflate", 1.0}, {"identity", 0.0}] = parse_qvalues( |
1512 | - "gzip,deflate,identity;q=0.0" |
1513 | - ), |
1514 | - [{"deflate", 1.0}, {"gzip", 1.0}, {"identity", 0.0}] = parse_qvalues( |
1515 | - "deflate,gzip,identity;q=0.0" |
1516 | - ), |
1517 | - [{"gzip", 1.0}, {"deflate", 1.0}, {"gzip", 1.0}, {"identity", 0.0}] = |
1518 | - parse_qvalues("gzip,deflate,gzip,identity;q=0"), |
1519 | - [{"gzip", 1.0}, {"deflate", 1.0}, {"identity", 0.0}] = parse_qvalues( |
1520 | - "gzip, deflate , identity; q=0.0" |
1521 | - ), |
1522 | - [{"gzip", 1.0}, {"deflate", 1.0}, {"identity", 0.0}] = parse_qvalues( |
1523 | - "gzip; q=1, deflate;q=1.0, identity;q=0.0" |
1524 | - ), |
1525 | - [{"gzip", 0.5}, {"deflate", 1.0}, {"identity", 0.0}] = parse_qvalues( |
1526 | - "gzip; q=0.5, deflate;q=1.0, identity;q=0" |
1527 | - ), |
1528 | - [{"gzip", 0.5}, {"deflate", 1.0}, {"identity", 0.0}] = parse_qvalues( |
1529 | - "gzip; q=0.5, deflate , identity;q=0.0" |
1530 | - ), |
1531 | - [{"gzip", 0.5}, {"deflate", 0.8}, {"identity", 0.0}] = parse_qvalues( |
1532 | - "gzip; q=0.5, deflate;q=0.8, identity;q=0.0" |
1533 | - ), |
1534 | - [{"gzip", 0.5}, {"deflate", 1.0}, {"identity", 1.0}] = parse_qvalues( |
1535 | - "gzip; q=0.5,deflate,identity" |
1536 | - ), |
1537 | - [{"gzip", 0.5}, {"deflate", 1.0}, {"identity", 1.0}, {"identity", 1.0}] = |
1538 | - parse_qvalues("gzip; q=0.5,deflate,identity, identity "), |
1539 | - [{"text/html;level=1", 1.0}, {"text/plain", 0.5}] = |
1540 | - parse_qvalues("text/html;level=1, text/plain;q=0.5"), |
1541 | - [{"text/html;level=1", 0.3}, {"text/plain", 1.0}] = |
1542 | - parse_qvalues("text/html;level=1;q=0.3, text/plain"), |
1543 | - [{"text/html;level=1", 0.3}, {"text/plain", 1.0}] = |
1544 | - parse_qvalues("text/html; level = 1; q = 0.3, text/plain"), |
1545 | - [{"text/html;level=1", 0.3}, {"text/plain", 1.0}] = |
1546 | - parse_qvalues("text/html;q=0.3;level=1, text/plain"), |
1547 | - invalid_qvalue_string = parse_qvalues("gzip; q=1.1, deflate"), |
1548 | - invalid_qvalue_string = parse_qvalues("gzip; q=0.5, deflate;q=2"), |
1549 | - invalid_qvalue_string = parse_qvalues("gzip, deflate;q=AB"), |
1550 | - invalid_qvalue_string = parse_qvalues("gzip; q=2.1, deflate"), |
1551 | - invalid_qvalue_string = parse_qvalues("gzip; q=0.1234, deflate"), |
1552 | - invalid_qvalue_string = parse_qvalues("text/html;level=1;q=0.3, text/html;level"), |
1553 | - ok. |
1554 | - |
1555 | -pick_accepted_encodings_test() -> |
1556 | - ["identity"] = pick_accepted_encodings( |
1557 | - [], |
1558 | - ["gzip", "identity"], |
1559 | - "identity" |
1560 | - ), |
1561 | - ["gzip", "identity"] = pick_accepted_encodings( |
1562 | - [{"gzip", 1.0}], |
1563 | - ["gzip", "identity"], |
1564 | - "identity" |
1565 | - ), |
1566 | - ["identity"] = pick_accepted_encodings( |
1567 | - [{"gzip", 0.0}], |
1568 | - ["gzip", "identity"], |
1569 | - "identity" |
1570 | - ), |
1571 | - ["gzip", "identity"] = pick_accepted_encodings( |
1572 | - [{"gzip", 1.0}, {"deflate", 1.0}], |
1573 | - ["gzip", "identity"], |
1574 | - "identity" |
1575 | - ), |
1576 | - ["gzip", "identity"] = pick_accepted_encodings( |
1577 | - [{"gzip", 0.5}, {"deflate", 1.0}], |
1578 | - ["gzip", "identity"], |
1579 | - "identity" |
1580 | - ), |
1581 | - ["identity"] = pick_accepted_encodings( |
1582 | - [{"gzip", 0.0}, {"deflate", 0.0}], |
1583 | - ["gzip", "identity"], |
1584 | - "identity" |
1585 | - ), |
1586 | - ["gzip"] = pick_accepted_encodings( |
1587 | - [{"gzip", 1.0}, {"deflate", 1.0}, {"identity", 0.0}], |
1588 | - ["gzip", "identity"], |
1589 | - "identity" |
1590 | - ), |
1591 | - ["gzip", "deflate", "identity"] = pick_accepted_encodings( |
1592 | - [{"gzip", 1.0}, {"deflate", 1.0}], |
1593 | - ["gzip", "deflate", "identity"], |
1594 | - "identity" |
1595 | - ), |
1596 | - ["gzip", "deflate"] = pick_accepted_encodings( |
1597 | - [{"gzip", 1.0}, {"deflate", 1.0}, {"identity", 0.0}], |
1598 | - ["gzip", "deflate", "identity"], |
1599 | - "identity" |
1600 | - ), |
1601 | - ["deflate", "gzip", "identity"] = pick_accepted_encodings( |
1602 | - [{"gzip", 0.2}, {"deflate", 1.0}], |
1603 | - ["gzip", "deflate", "identity"], |
1604 | - "identity" |
1605 | - ), |
1606 | - ["deflate", "deflate", "gzip", "identity"] = pick_accepted_encodings( |
1607 | - [{"gzip", 0.2}, {"deflate", 1.0}, {"deflate", 1.0}], |
1608 | - ["gzip", "deflate", "identity"], |
1609 | - "identity" |
1610 | - ), |
1611 | - ["deflate", "gzip", "gzip", "identity"] = pick_accepted_encodings( |
1612 | - [{"gzip", 0.2}, {"deflate", 1.0}, {"gzip", 1.0}], |
1613 | - ["gzip", "deflate", "identity"], |
1614 | - "identity" |
1615 | - ), |
1616 | - ["gzip", "deflate", "gzip", "identity"] = pick_accepted_encodings( |
1617 | - [{"gzip", 0.2}, {"deflate", 0.9}, {"gzip", 1.0}], |
1618 | - ["gzip", "deflate", "identity"], |
1619 | - "identity" |
1620 | - ), |
1621 | - [] = pick_accepted_encodings( |
1622 | - [{"*", 0.0}], |
1623 | - ["gzip", "deflate", "identity"], |
1624 | - "identity" |
1625 | - ), |
1626 | - ["gzip", "deflate", "identity"] = pick_accepted_encodings( |
1627 | - [{"*", 1.0}], |
1628 | - ["gzip", "deflate", "identity"], |
1629 | - "identity" |
1630 | - ), |
1631 | - ["gzip", "deflate", "identity"] = pick_accepted_encodings( |
1632 | - [{"*", 0.6}], |
1633 | - ["gzip", "deflate", "identity"], |
1634 | - "identity" |
1635 | - ), |
1636 | - ["gzip"] = pick_accepted_encodings( |
1637 | - [{"gzip", 1.0}, {"*", 0.0}], |
1638 | - ["gzip", "deflate", "identity"], |
1639 | - "identity" |
1640 | - ), |
1641 | - ["gzip", "deflate"] = pick_accepted_encodings( |
1642 | - [{"gzip", 1.0}, {"deflate", 0.6}, {"*", 0.0}], |
1643 | - ["gzip", "deflate", "identity"], |
1644 | - "identity" |
1645 | - ), |
1646 | - ["deflate", "gzip"] = pick_accepted_encodings( |
1647 | - [{"gzip", 0.5}, {"deflate", 1.0}, {"*", 0.0}], |
1648 | - ["gzip", "deflate", "identity"], |
1649 | - "identity" |
1650 | - ), |
1651 | - ["gzip", "identity"] = pick_accepted_encodings( |
1652 | - [{"deflate", 0.0}, {"*", 1.0}], |
1653 | - ["gzip", "deflate", "identity"], |
1654 | - "identity" |
1655 | - ), |
1656 | - ["gzip", "identity"] = pick_accepted_encodings( |
1657 | - [{"*", 1.0}, {"deflate", 0.0}], |
1658 | - ["gzip", "deflate", "identity"], |
1659 | - "identity" |
1660 | - ), |
1661 | - ok. |
1662 | - |
1663 | --endif. |
1664 | |
1665 | === removed directory '.pc/improve_script_url_validation.patch' |
1666 | === removed directory '.pc/improve_script_url_validation.patch/share' |
1667 | === removed directory '.pc/improve_script_url_validation.patch/share/www' |
1668 | === removed directory '.pc/improve_script_url_validation.patch/share/www/script' |
1669 | === removed file '.pc/improve_script_url_validation.patch/share/www/script/couch_test_runner.js' |
1670 | --- .pc/improve_script_url_validation.patch/share/www/script/couch_test_runner.js 2013-01-18 22:04:32 +0000 |
1671 | +++ .pc/improve_script_url_validation.patch/share/www/script/couch_test_runner.js 1970-01-01 00:00:00 +0000 |
1672 | @@ -1,472 +0,0 @@ |
1673 | -// Licensed under the Apache License, Version 2.0 (the "License"); you may not |
1674 | -// use this file except in compliance with the License. You may obtain a copy of |
1675 | -// the License at |
1676 | -// |
1677 | -// http://www.apache.org/licenses/LICENSE-2.0 |
1678 | -// |
1679 | -// Unless required by applicable law or agreed to in writing, software |
1680 | -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
1681 | -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
1682 | -// License for the specific language governing permissions and limitations under |
1683 | -// the License. |
1684 | - |
1685 | -// *********************** Test Framework of Sorts ************************* // |
1686 | - |
1687 | - |
1688 | -function loadScript(url) { |
1689 | - // disallow loading remote URLs |
1690 | - if((url.substr(0, 7) == "http://") |
1691 | - || (url.substr(0, 2) == "//") |
1692 | - || (url.substr(0, 5) == "data:") |
1693 | - || (url.substr(0, 11) == "javascript:")) { |
1694 | - throw "Not loading remote test scripts"; |
1695 | - } |
1696 | - if (typeof document != "undefined") document.write('<script src="'+url+'"></script>'); |
1697 | -}; |
1698 | - |
1699 | -function patchTest(fun) { |
1700 | - var source = fun.toString(); |
1701 | - var output = ""; |
1702 | - var i = 0; |
1703 | - var testMarker = "T("; |
1704 | - while (i < source.length) { |
1705 | - var testStart = source.indexOf(testMarker, i); |
1706 | - if (testStart == -1) { |
1707 | - output = output + source.substring(i, source.length); |
1708 | - break; |
1709 | - } |
1710 | - var testEnd = source.indexOf(");", testStart); |
1711 | - var testCode = source.substring(testStart + testMarker.length, testEnd); |
1712 | - output += source.substring(i, testStart) + "T(" + testCode + "," + JSON.stringify(testCode); |
1713 | - i = testEnd; |
1714 | - } |
1715 | - try { |
1716 | - return eval("(" + output + ")"); |
1717 | - } catch (e) { |
1718 | - return null; |
1719 | - } |
1720 | -} |
1721 | - |
1722 | -function runAllTests() { |
1723 | - var rows = $("#tests tbody.content tr"); |
1724 | - $("td", rows).text(""); |
1725 | - $("td.status", rows).removeClass("error").removeClass("failure").removeClass("success").text("not run"); |
1726 | - var offset = 0; |
1727 | - function runNext() { |
1728 | - if (offset < rows.length) { |
1729 | - var row = rows.get(offset); |
1730 | - runTest($("th button", row).get(0), function() { |
1731 | - offset += 1; |
1732 | - setTimeout(runNext, 100); |
1733 | - }, false, true); |
1734 | - } else { |
1735 | - saveTestReport(); |
1736 | - } |
1737 | - } |
1738 | - runNext(); |
1739 | -} |
1740 | - |
1741 | -var numFailures = 0; |
1742 | -var currentRow = null; |
1743 | - |
1744 | -function runTest(button, callback, debug, noSave) { |
1745 | - |
1746 | - // offer to save admins |
1747 | - if (currentRow != null) { |
1748 | - alert("Can not run multiple tests simultaneously."); |
1749 | - return; |
1750 | - } |
1751 | - var row = currentRow = $(button).parents("tr").get(0); |
1752 | - $("td.status", row).removeClass("error").removeClass("failure").removeClass("success"); |
1753 | - $("td", row).text(""); |
1754 | - $("#toolbar li.current").text("Running: "+row.id); |
1755 | - var testFun = couchTests[row.id]; |
1756 | - function run() { |
1757 | - numFailures = 0; |
1758 | - var start = new Date().getTime(); |
1759 | - try { |
1760 | - if (debug == undefined || !debug) { |
1761 | - testFun = patchTest(testFun) || testFun; |
1762 | - } |
1763 | - testFun(debug); |
1764 | - var status = numFailures > 0 ? "failure" : "success"; |
1765 | - } catch (e) { |
1766 | - var status = "error"; |
1767 | - if ($("td.details ol", row).length == 0) { |
1768 | - $("<ol></ol>").appendTo($("td.details", row)); |
1769 | - } |
1770 | - $("<li><b>Exception raised:</b> <code class='error'></code></li>") |
1771 | - .find("code").text(JSON.stringify(e)).end() |
1772 | - .appendTo($("td.details ol", row)); |
1773 | - if (debug) { |
1774 | - currentRow = null; |
1775 | - throw e; |
1776 | - } |
1777 | - } |
1778 | - if ($("td.details ol", row).length) { |
1779 | - $("<a href='#'>Run with debugger</a>").click(function() { |
1780 | - runTest(this, undefined, true); |
1781 | - }).prependTo($("td.details ol", row)); |
1782 | - } |
1783 | - var duration = new Date().getTime() - start; |
1784 | - $("td.status", row).removeClass("running").addClass(status).text(status); |
1785 | - $("td.duration", row).text(duration + "ms"); |
1786 | - $("#toolbar li.current").text("Finished: "+row.id); |
1787 | - updateTestsFooter(); |
1788 | - currentRow = null; |
1789 | - if (callback) callback(); |
1790 | - if (!noSave) saveTestReport(); |
1791 | - } |
1792 | - $("td.status", row).addClass("running").text("running…"); |
1793 | - setTimeout(run, 100); |
1794 | -} |
1795 | - |
1796 | -function showSource(cell) { |
1797 | - var name = $(cell).text(); |
1798 | - var win = window.open("", name, "width=700,height=500,resizable=yes,scrollbars=yes"); |
1799 | - win.document.location = "script/test/" + name + ".js"; |
1800 | -} |
1801 | - |
1802 | -var readyToRun; |
1803 | -function setupAdminParty(fun) { |
1804 | - if (readyToRun) { |
1805 | - fun(); |
1806 | - } else { |
1807 | - function removeAdmins(confs, doneFun) { |
1808 | - // iterate through the config and remove current user last |
1809 | - // current user is at front of list |
1810 | - var remove = confs.pop(); |
1811 | - if (remove) { |
1812 | - $.couch.config({ |
1813 | - success : function() { |
1814 | - removeAdmins(confs, doneFun); |
1815 | - } |
1816 | - }, "admins", remove[0], null); |
1817 | - } else { |
1818 | - doneFun(); |
1819 | - } |
1820 | - }; |
1821 | - $.couch.session({ |
1822 | - success : function(resp) { |
1823 | - var userCtx = resp.userCtx; |
1824 | - if (userCtx.name && userCtx.roles.indexOf("_admin") != -1) { |
1825 | - // admin but not admin party. dialog offering to make admin party |
1826 | - $.showDialog("dialog/_admin_party.html", { |
1827 | - submit: function(data, callback) { |
1828 | - $.couch.config({ |
1829 | - success : function(conf) { |
1830 | - var meAdmin, adminConfs = []; |
1831 | - for (var name in conf) { |
1832 | - if (name == userCtx.name) { |
1833 | - meAdmin = [name, conf[name]]; |
1834 | - } else { |
1835 | - adminConfs.push([name, conf[name]]); |
1836 | - } |
1837 | - } |
1838 | - adminConfs.unshift(meAdmin); |
1839 | - removeAdmins(adminConfs, function() { |
1840 | - callback(); |
1841 | - $.futon.session.sidebar(); |
1842 | - readyToRun = true; |
1843 | - setTimeout(fun, 500); |
1844 | - }); |
1845 | - } |
1846 | - }, "admins"); |
1847 | - } |
1848 | - }); |
1849 | - } else if (userCtx.roles.indexOf("_admin") != -1) { |
1850 | - // admin party! |
1851 | - readyToRun = true; |
1852 | - fun(); |
1853 | - } else { |
1854 | - // not an admin |
1855 | - alert("Error: You need to be an admin to run the tests."); |
1856 | - }; |
1857 | - } |
1858 | - }); |
1859 | - } |
1860 | -}; |
1861 | - |
1862 | -function updateTestsListing() { |
1863 | - for (var name in couchTests) { |
1864 | - var testFunction = couchTests[name]; |
1865 | - var row = $("<tr><th></th><td></td><td></td><td></td></tr>") |
1866 | - .find("th").text(name).attr("title", "Show source").click(function() { |
1867 | - showSource(this); |
1868 | - }).end() |
1869 | - .find("td:nth(0)").addClass("status").text("not run").end() |
1870 | - .find("td:nth(1)").addClass("duration").end() |
1871 | - .find("td:nth(2)").addClass("details").end(); |
1872 | - $("<button type='button' class='run' title='Run test'></button>").click(function() { |
1873 | - this.blur(); |
1874 | - var self = this; |
1875 | - // check for admin party |
1876 | - setupAdminParty(function() { |
1877 | - runTest(self); |
1878 | - }); |
1879 | - return false; |
1880 | - }).prependTo(row.find("th")); |
1881 | - row.attr("id", name).appendTo("#tests tbody.content"); |
1882 | - } |
1883 | - $("#tests tr").removeClass("odd").filter(":odd").addClass("odd"); |
1884 | - updateTestsFooter(); |
1885 | -} |
1886 | - |
1887 | -function updateTestsFooter() { |
1888 | - var tests = $("#tests tbody.content tr td.status"); |
1889 | - var testsRun = tests.filter(".success, .error, .failure"); |
1890 | - var testsFailed = testsRun.not(".success"); |
1891 | - var totalDuration = 0; |
1892 | - $("#tests tbody.content tr td.duration:contains('ms')").each(function() { |
1893 | - var text = $(this).text(); |
1894 | - totalDuration += parseInt(text.substr(0, text.length - 2), 10); |
1895 | - }); |
1896 | - $("#tests tbody.footer td").html("<span>"+testsRun.length + " of " + tests.length + |
1897 | - " test(s) run, " + testsFailed.length + " failures (" + |
1898 | - totalDuration + " ms)</span> "); |
1899 | -} |
1900 | - |
1901 | -// make report and save to local db |
1902 | -// display how many reports need replicating to the mothership |
1903 | -// have button to replicate them |
1904 | - |
1905 | -function saveTestReport(report) { |
1906 | - var report = makeTestReport(); |
1907 | - if (report) { |
1908 | - var db = $.couch.db("test_suite_reports"); |
1909 | - var saveReport = function(db_info) { |
1910 | - report.db = db_info; |
1911 | - $.couch.info({success : function(node_info) { |
1912 | - report.node = node_info; |
1913 | - db.saveDoc(report); |
1914 | - }}); |
1915 | - }; |
1916 | - var createDb = function() { |
1917 | - db.create({success: function() { |
1918 | - db.info({success:saveReport}); |
1919 | - }}); |
1920 | - }; |
1921 | - db.info({error: createDb, success:saveReport}); |
1922 | - } |
1923 | -}; |
1924 | - |
1925 | -function makeTestReport() { |
1926 | - var report = {}; |
1927 | - report.summary = $("#tests tbody.footer td").text(); |
1928 | - report.platform = testPlatform(); |
1929 | - var date = new Date(); |
1930 | - report.timestamp = date.getTime(); |
1931 | - report.timezone = date.getTimezoneOffset(); |
1932 | - report.tests = []; |
1933 | - $("#tests tbody.content tr").each(function() { |
1934 | - var status = $("td.status", this).text(); |
1935 | - if (status != "not run") { |
1936 | - var test = {}; |
1937 | - test.name = this.id; |
1938 | - test.status = status; |
1939 | - test.duration = parseInt($("td.duration", this).text()); |
1940 | - test.details = []; |
1941 | - $("td.details li", this).each(function() { |
1942 | - test.details.push($(this).text()); |
1943 | - }); |
1944 | - if (test.details.length == 0) { |
1945 | - delete test.details; |
1946 | - } |
1947 | - report.tests.push(test); |
1948 | - } |
1949 | - }); |
1950 | - if (report.tests.length > 0) return report; |
1951 | -}; |
1952 | - |
1953 | -function testPlatform() { |
1954 | - var b = $.browser; |
1955 | - var bs = ["mozilla", "msie", "opera", "safari"]; |
1956 | - for (var i=0; i < bs.length; i++) { |
1957 | - if (b[bs[i]]) { |
1958 | - return {"browser" : bs[i], "version" : b.version}; |
1959 | - } |
1960 | - }; |
1961 | - return {"browser" : "undetected"}; |
1962 | -} |
1963 | - |
1964 | - |
1965 | -function reportTests() { |
1966 | - // replicate the database to couchdb.couchdb.org |
1967 | -} |
1968 | - |
1969 | -// Use T to perform a test that returns false on failure and if the test fails, |
1970 | -// display the line that failed. |
1971 | -// Example: |
1972 | -// T(MyValue==1); |
1973 | -function T(arg1, arg2, testName) { |
1974 | - if (!arg1) { |
1975 | - if (currentRow) { |
1976 | - if ($("td.details ol", currentRow).length == 0) { |
1977 | - $("<ol></ol>").appendTo($("td.details", currentRow)); |
1978 | - } |
1979 | - var message = (arg2 != null ? arg2 : arg1).toString(); |
1980 | - $("<li><b>Assertion " + (testName ? "'" + testName + "'" : "") + " failed:</b> <code class='failure'></code></li>") |
1981 | - .find("code").text(message).end() |
1982 | - .appendTo($("td.details ol", currentRow)); |
1983 | - } |
1984 | - numFailures += 1; |
1985 | - } |
1986 | -} |
1987 | - |
1988 | -function TIsnull(actual, testName) { |
1989 | - T(actual === null, "expected 'null', got '" |
1990 | - + repr(actual) + "'", testName); |
1991 | -} |
1992 | - |
1993 | -function TEquals(expected, actual, testName) { |
1994 | - T(equals(expected, actual), "expected '" + repr(expected) + |
1995 | - "', got '" + repr(actual) + "'", testName); |
1996 | -} |
1997 | - |
1998 | -function TEqualsIgnoreCase(expected, actual, testName) { |
1999 | - T(equals(expected.toUpperCase(), actual.toUpperCase()), "expected '" + repr(expected) + |
2000 | - "', got '" + repr(actual) + "'", testName); |
2001 | -} |
2002 | - |
2003 | -function equals(a,b) { |
2004 | - if (a === b) return true; |
2005 | - try { |
2006 | - return repr(a) === repr(b); |
2007 | - } catch (e) { |
2008 | - return false; |
2009 | - } |
2010 | -} |
2011 | - |
2012 | -function repr(val) { |
2013 | - if (val === undefined) { |
2014 | - return null; |
2015 | - } else if (val === null) { |
2016 | - return "null"; |
2017 | - } else { |
2018 | - return JSON.stringify(val); |
2019 | - } |
2020 | -} |
2021 | - |
2022 | -function makeDocs(start, end, templateDoc) { |
2023 | - var templateDocSrc = templateDoc ? JSON.stringify(templateDoc) : "{}"; |
2024 | - if (end === undefined) { |
2025 | - end = start; |
2026 | - start = 0; |
2027 | - } |
2028 | - var docs = []; |
2029 | - for (var i = start; i < end; i++) { |
2030 | - var newDoc = eval("(" + templateDocSrc + ")"); |
2031 | - newDoc._id = (i).toString(); |
2032 | - newDoc.integer = i; |
2033 | - newDoc.string = (i).toString(); |
2034 | - docs.push(newDoc); |
2035 | - } |
2036 | - return docs; |
2037 | -} |
2038 | - |
2039 | -function run_on_modified_server(settings, fun) { |
2040 | - try { |
2041 | - // set the settings |
2042 | - for(var i=0; i < settings.length; i++) { |
2043 | - var s = settings[i]; |
2044 | - var xhr = CouchDB.request("PUT", "/_config/" + s.section + "/" + s.key, { |
2045 | - body: JSON.stringify(s.value), |
2046 | - headers: {"X-Couch-Persist": "false"} |
2047 | - }); |
2048 | - CouchDB.maybeThrowError(xhr); |
2049 | - s.oldValue = xhr.responseText; |
2050 | - } |
2051 | - // run the thing |
2052 | - fun(); |
2053 | - } finally { |
2054 | - // unset the settings |
2055 | - for(var j=0; j < i; j++) { |
2056 | - var s = settings[j]; |
2057 | - if(s.oldValue == "\"\"\n") { // unset value |
2058 | - CouchDB.request("DELETE", "/_config/" + s.section + "/" + s.key, { |
2059 | - headers: {"X-Couch-Persist": "false"} |
2060 | - }); |
2061 | - } else { |
2062 | - CouchDB.request("PUT", "/_config/" + s.section + "/" + s.key, { |
2063 | - body: s.oldValue, |
2064 | - headers: {"X-Couch-Persist": "false"} |
2065 | - }); |
2066 | - } |
2067 | - } |
2068 | - } |
2069 | -} |
2070 | - |
2071 | -function stringFun(fun) { |
2072 | - var string = fun.toSource ? fun.toSource() : "(" + fun.toString() + ")"; |
2073 | - return string; |
2074 | -} |
2075 | - |
2076 | -function waitForSuccess(fun, tag) { |
2077 | - var start = new Date(); |
2078 | - while(true) { |
2079 | - if (new Date() - start > 5000) { |
2080 | - throw("timeout: "+tag); |
2081 | - } else { |
2082 | - try { |
2083 | - fun(); |
2084 | - break; |
2085 | - } catch (e) {} |
2086 | - // sync http req allow async req to happen |
2087 | - CouchDB.request("GET", "/test_suite_db/?tag="+encodeURIComponent(tag)); |
2088 | - } |
2089 | - } |
2090 | -} |
2091 | - |
2092 | -function waitForRestart() { |
2093 | - var waiting = true; |
2094 | - // Wait for the server to go down but don't |
2095 | - // wait too long because we might miss the |
2096 | - // the unavailable period. |
2097 | - var count = 25; |
2098 | - while (waiting && count > 0) { |
2099 | - count--; |
2100 | - try { |
2101 | - CouchDB.request("GET", "/"); |
2102 | - } catch(e) { |
2103 | - waiting = false; |
2104 | - } |
2105 | - } |
2106 | - // Wait for it to come back up |
2107 | - waiting = true; |
2108 | - while (waiting) { |
2109 | - try { |
2110 | - CouchDB.request("GET", "/"); |
2111 | - waiting = false; |
2112 | - } catch(e) { |
2113 | - // the request will fail until restart completes |
2114 | - } |
2115 | - } |
2116 | -}; |
2117 | - |
2118 | -function restartServer() { |
2119 | - var xhr; |
2120 | - try { |
2121 | - CouchDB.request("POST", "/_restart"); |
2122 | - } catch(e) { |
2123 | - // this request may sometimes fail |
2124 | - } |
2125 | - waitForRestart(); |
2126 | -} |
2127 | - |
2128 | -// legacy functions for CouchDB < 1.2.0 |
2129 | -// we keep them to make sure we keep BC |
2130 | -CouchDB.user_prefix = "org.couchdb.user:"; |
2131 | - |
2132 | -CouchDB.prepareUserDoc = function(user_doc, new_password) { |
2133 | - user_doc._id = user_doc._id || CouchDB.user_prefix + user_doc.name; |
2134 | - if (new_password) { |
2135 | - // handle the password crypto |
2136 | - user_doc.salt = CouchDB.newUuids(1)[0]; |
2137 | - user_doc.password_sha = hex_sha1(new_password + user_doc.salt); |
2138 | - } |
2139 | - user_doc.type = "user"; |
2140 | - if (!user_doc.roles) { |
2141 | - user_doc.roles = []; |
2142 | - } |
2143 | - return user_doc; |
2144 | -}; |
2145 | |
2146 | === removed directory '.pc/include_a_comment_before_jsonp_output.patch' |
2147 | === removed directory '.pc/include_a_comment_before_jsonp_output.patch/src' |
2148 | === removed directory '.pc/include_a_comment_before_jsonp_output.patch/src/couchdb' |
2149 | === removed file '.pc/include_a_comment_before_jsonp_output.patch/src/couchdb/couch_httpd.erl' |
2150 | --- .pc/include_a_comment_before_jsonp_output.patch/src/couchdb/couch_httpd.erl 2013-01-18 22:04:32 +0000 |
2151 | +++ .pc/include_a_comment_before_jsonp_output.patch/src/couchdb/couch_httpd.erl 1970-01-01 00:00:00 +0000 |
2152 | @@ -1,1081 +0,0 @@ |
2153 | -% Licensed under the Apache License, Version 2.0 (the "License"); you may not |
2154 | -% use this file except in compliance with the License. You may obtain a copy of |
2155 | -% the License at |
2156 | -% |
2157 | -% http://www.apache.org/licenses/LICENSE-2.0 |
2158 | -% |
2159 | -% Unless required by applicable law or agreed to in writing, software |
2160 | -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
2161 | -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
2162 | -% License for the specific language governing permissions and limitations under |
2163 | -% the License. |
2164 | - |
2165 | --module(couch_httpd). |
2166 | --include("couch_db.hrl"). |
2167 | - |
2168 | --export([start_link/0, start_link/1, stop/0, config_change/2, |
2169 | - handle_request/5]). |
2170 | - |
2171 | --export([header_value/2,header_value/3,qs_value/2,qs_value/3,qs/1,qs_json_value/3]). |
2172 | --export([path/1,absolute_uri/2,body_length/1]). |
2173 | --export([verify_is_server_admin/1,unquote/1,quote/1,recv/2,recv_chunked/4,error_info/1]). |
2174 | --export([make_fun_spec_strs/1]). |
2175 | --export([make_arity_1_fun/1, make_arity_2_fun/1, make_arity_3_fun/1]). |
2176 | --export([parse_form/1,json_body/1,json_body_obj/1,body/1,doc_etag/1, make_etag/1, etag_respond/3]). |
2177 | --export([primary_header_value/2,partition/1,serve_file/3,serve_file/4, server_header/0]). |
2178 | --export([start_chunked_response/3,send_chunk/2,log_request/2]). |
2179 | --export([start_response_length/4, start_response/3, send/2]). |
2180 | --export([start_json_response/2, start_json_response/3, end_json_response/1]). |
2181 | --export([send_response/4,send_method_not_allowed/2,send_error/4, send_redirect/2,send_chunked_error/2]). |
2182 | --export([send_json/2,send_json/3,send_json/4,last_chunk/1,parse_multipart_request/3]). |
2183 | --export([accepted_encodings/1,handle_request_int/5,validate_referer/1,validate_ctype/2]). |
2184 | - |
2185 | -start_link() -> |
2186 | - start_link(http). |
2187 | -start_link(http) -> |
2188 | - Port = couch_config:get("httpd", "port", "5984"), |
2189 | - start_link(?MODULE, [{port, Port}]); |
2190 | -start_link(https) -> |
2191 | - Port = couch_config:get("ssl", "port", "6984"), |
2192 | - CertFile = couch_config:get("ssl", "cert_file", nil), |
2193 | - KeyFile = couch_config:get("ssl", "key_file", nil), |
2194 | - Options = case CertFile /= nil andalso KeyFile /= nil of |
2195 | - true -> |
2196 | - SslOpts = [{certfile, CertFile}, {keyfile, KeyFile}], |
2197 | - |
2198 | - %% set password if one is needed for the cert |
2199 | - SslOpts1 = case couch_config:get("ssl", "password", nil) of |
2200 | - nil -> SslOpts; |
2201 | - Password -> |
2202 | - SslOpts ++ [{password, Password}] |
2203 | - end, |
2204 | - % do we verify certificates ? |
2205 | - FinalSslOpts = case couch_config:get("ssl", |
2206 | - "verify_ssl_certificates", "false") of |
2207 | - "false" -> SslOpts1; |
2208 | - "true" -> |
2209 | - case couch_config:get("ssl", |
2210 | - "cacert_file", nil) of |
2211 | - nil -> |
2212 | - io:format("Verify SSL certificate " |
2213 | - ++"enabled but file containing " |
2214 | - ++"PEM encoded CA certificates is " |
2215 | - ++"missing", []), |
2216 | - throw({error, missing_cacerts}); |
2217 | - CaCertFile -> |
2218 | - Depth = list_to_integer(couch_config:get("ssl", |
2219 | - "ssl_certificate_max_depth", |
2220 | - "1")), |
2221 | - FinalOpts = [ |
2222 | - {cacertfile, CaCertFile}, |
2223 | - {depth, Depth}, |
2224 | - {verify, verify_peer}], |
2225 | - % allows custom verify fun. |
2226 | - case couch_config:get("ssl", |
2227 | - "verify_fun", nil) of |
2228 | - nil -> FinalOpts; |
2229 | - SpecStr -> |
2230 | - FinalOpts |
2231 | - ++ [{verify_fun, make_arity_3_fun(SpecStr)}] |
2232 | - end |
2233 | - end |
2234 | - end, |
2235 | - |
2236 | - [{port, Port}, |
2237 | - {ssl, true}, |
2238 | - {ssl_opts, FinalSslOpts}]; |
2239 | - false -> |
2240 | - io:format("SSL enabled but PEM certificates are missing.", []), |
2241 | - throw({error, missing_certs}) |
2242 | - end, |
2243 | - start_link(https, Options). |
2244 | -start_link(Name, Options) -> |
2245 | - % read config and register for configuration changes |
2246 | - |
2247 | - % just stop if one of the config settings change. couch_server_sup |
2248 | - % will restart us and then we will pick up the new settings. |
2249 | - |
2250 | - BindAddress = couch_config:get("httpd", "bind_address", any), |
2251 | - DefaultSpec = "{couch_httpd_db, handle_request}", |
2252 | - DefaultFun = make_arity_1_fun( |
2253 | - couch_config:get("httpd", "default_handler", DefaultSpec) |
2254 | - ), |
2255 | - |
2256 | - UrlHandlersList = lists:map( |
2257 | - fun({UrlKey, SpecStr}) -> |
2258 | - {?l2b(UrlKey), make_arity_1_fun(SpecStr)} |
2259 | - end, couch_config:get("httpd_global_handlers")), |
2260 | - |
2261 | - DbUrlHandlersList = lists:map( |
2262 | - fun({UrlKey, SpecStr}) -> |
2263 | - {?l2b(UrlKey), make_arity_2_fun(SpecStr)} |
2264 | - end, couch_config:get("httpd_db_handlers")), |
2265 | - |
2266 | - DesignUrlHandlersList = lists:map( |
2267 | - fun({UrlKey, SpecStr}) -> |
2268 | - {?l2b(UrlKey), make_arity_3_fun(SpecStr)} |
2269 | - end, couch_config:get("httpd_design_handlers")), |
2270 | - |
2271 | - UrlHandlers = dict:from_list(UrlHandlersList), |
2272 | - DbUrlHandlers = dict:from_list(DbUrlHandlersList), |
2273 | - DesignUrlHandlers = dict:from_list(DesignUrlHandlersList), |
2274 | - {ok, ServerOptions} = couch_util:parse_term( |
2275 | - couch_config:get("httpd", "server_options", "[]")), |
2276 | - {ok, SocketOptions} = couch_util:parse_term( |
2277 | - couch_config:get("httpd", "socket_options", "[]")), |
2278 | - |
2279 | - set_auth_handlers(), |
2280 | - |
2281 | - Loop = fun(Req)-> |
2282 | - case SocketOptions of |
2283 | - [] -> |
2284 | - ok; |
2285 | - _ -> |
2286 | - ok = mochiweb_socket:setopts(Req:get(socket), SocketOptions) |
2287 | - end, |
2288 | - apply(?MODULE, handle_request, [ |
2289 | - Req, DefaultFun, UrlHandlers, DbUrlHandlers, DesignUrlHandlers |
2290 | - ]) |
2291 | - end, |
2292 | - |
2293 | - % set mochiweb options |
2294 | - FinalOptions = lists:append([Options, ServerOptions, [ |
2295 | - {loop, Loop}, |
2296 | - {name, Name}, |
2297 | - {ip, BindAddress}]]), |
2298 | - |
2299 | - % launch mochiweb |
2300 | - {ok, Pid} = case mochiweb_http:start(FinalOptions) of |
2301 | - {ok, MochiPid} -> |
2302 | - {ok, MochiPid}; |
2303 | - {error, Reason} -> |
2304 | - io:format("Failure to start Mochiweb: ~s~n",[Reason]), |
2305 | - throw({error, Reason}) |
2306 | - end, |
2307 | - |
2308 | - ok = couch_config:register(fun ?MODULE:config_change/2, Pid), |
2309 | - {ok, Pid}. |
2310 | - |
2311 | - |
2312 | -stop() -> |
2313 | - mochiweb_http:stop(couch_httpd), |
2314 | - mochiweb_http:stop(https). |
2315 | - |
2316 | -config_change("httpd", "bind_address") -> |
2317 | - ?MODULE:stop(); |
2318 | -config_change("httpd", "port") -> |
2319 | - ?MODULE:stop(); |
2320 | -config_change("httpd", "default_handler") -> |
2321 | - ?MODULE:stop(); |
2322 | -config_change("httpd", "server_options") -> |
2323 | - ?MODULE:stop(); |
2324 | -config_change("httpd", "socket_options") -> |
2325 | - ?MODULE:stop(); |
2326 | -config_change("httpd", "authentication_handlers") -> |
2327 | - set_auth_handlers(); |
2328 | -config_change("httpd_global_handlers", _) -> |
2329 | - ?MODULE:stop(); |
2330 | -config_change("httpd_db_handlers", _) -> |
2331 | - ?MODULE:stop(); |
2332 | -config_change("ssl", _) -> |
2333 | - ?MODULE:stop(). |
2334 | - |
2335 | -set_auth_handlers() -> |
2336 | - AuthenticationSrcs = make_fun_spec_strs( |
2337 | - couch_config:get("httpd", "authentication_handlers", "")), |
2338 | - AuthHandlers = lists:map( |
2339 | - fun(A) -> {make_arity_1_fun(A), ?l2b(A)} end, AuthenticationSrcs), |
2340 | - ok = application:set_env(couch, auth_handlers, AuthHandlers). |
2341 | - |
2342 | -% SpecStr is a string like "{my_module, my_fun}" |
2343 | -% or "{my_module, my_fun, <<"my_arg">>}" |
2344 | -make_arity_1_fun(SpecStr) -> |
2345 | - case couch_util:parse_term(SpecStr) of |
2346 | - {ok, {Mod, Fun, SpecArg}} -> |
2347 | - fun(Arg) -> Mod:Fun(Arg, SpecArg) end; |
2348 | - {ok, {Mod, Fun}} -> |
2349 | - fun(Arg) -> Mod:Fun(Arg) end |
2350 | - end. |
2351 | - |
2352 | -make_arity_2_fun(SpecStr) -> |
2353 | - case couch_util:parse_term(SpecStr) of |
2354 | - {ok, {Mod, Fun, SpecArg}} -> |
2355 | - fun(Arg1, Arg2) -> Mod:Fun(Arg1, Arg2, SpecArg) end; |
2356 | - {ok, {Mod, Fun}} -> |
2357 | - fun(Arg1, Arg2) -> Mod:Fun(Arg1, Arg2) end |
2358 | - end. |
2359 | - |
2360 | -make_arity_3_fun(SpecStr) -> |
2361 | - case couch_util:parse_term(SpecStr) of |
2362 | - {ok, {Mod, Fun, SpecArg}} -> |
2363 | - fun(Arg1, Arg2, Arg3) -> Mod:Fun(Arg1, Arg2, Arg3, SpecArg) end; |
2364 | - {ok, {Mod, Fun}} -> |
2365 | - fun(Arg1, Arg2, Arg3) -> Mod:Fun(Arg1, Arg2, Arg3) end |
2366 | - end. |
2367 | - |
2368 | -% SpecStr is "{my_module, my_fun}, {my_module2, my_fun2}" |
2369 | -make_fun_spec_strs(SpecStr) -> |
2370 | - re:split(SpecStr, "(?<=})\\s*,\\s*(?={)", [{return, list}]). |
2371 | - |
2372 | -handle_request(MochiReq, DefaultFun, UrlHandlers, DbUrlHandlers, |
2373 | - DesignUrlHandlers) -> |
2374 | - |
2375 | - MochiReq1 = couch_httpd_vhost:dispatch_host(MochiReq), |
2376 | - |
2377 | - handle_request_int(MochiReq1, DefaultFun, |
2378 | - UrlHandlers, DbUrlHandlers, DesignUrlHandlers). |
2379 | - |
2380 | -handle_request_int(MochiReq, DefaultFun, |
2381 | - UrlHandlers, DbUrlHandlers, DesignUrlHandlers) -> |
2382 | - Begin = now(), |
2383 | - % for the path, use the raw path with the query string and fragment |
2384 | - % removed, but URL quoting left intact |
2385 | - RawUri = MochiReq:get(raw_path), |
2386 | - {"/" ++ Path, _, _} = mochiweb_util:urlsplit_path(RawUri), |
2387 | - |
2388 | - Headers = MochiReq:get(headers), |
2389 | - |
2390 | - % get requested path |
2391 | - RequestedPath = case MochiReq:get_header_value("x-couchdb-vhost-path") of |
2392 | - undefined -> |
2393 | - case MochiReq:get_header_value("x-couchdb-requested-path") of |
2394 | - undefined -> RawUri; |
2395 | - R -> R |
2396 | - end; |
2397 | - P -> P |
2398 | - end, |
2399 | - |
2400 | - HandlerKey = |
2401 | - case mochiweb_util:partition(Path, "/") of |
2402 | - {"", "", ""} -> |
2403 | - <<"/">>; % Special case the root url handler |
2404 | - {FirstPart, _, _} -> |
2405 | - list_to_binary(FirstPart) |
2406 | - end, |
2407 | - ?LOG_DEBUG("~p ~s ~p from ~p~nHeaders: ~p", [ |
2408 | - MochiReq:get(method), |
2409 | - RawUri, |
2410 | - MochiReq:get(version), |
2411 | - MochiReq:get(peer), |
2412 | - mochiweb_headers:to_list(MochiReq:get(headers)) |
2413 | - ]), |
2414 | - |
2415 | - Method1 = |
2416 | - case MochiReq:get(method) of |
2417 | - % already an atom |
2418 | - Meth when is_atom(Meth) -> Meth; |
2419 | - |
2420 | - % Non standard HTTP verbs aren't atoms (COPY, MOVE etc) so convert when |
2421 | - % possible (if any module references the atom, then it's existing). |
2422 | - Meth -> couch_util:to_existing_atom(Meth) |
2423 | - end, |
2424 | - increment_method_stats(Method1), |
2425 | - |
2426 | - % allow broken HTTP clients to fake a full method vocabulary with an X-HTTP-METHOD-OVERRIDE header |
2427 | - MethodOverride = MochiReq:get_primary_header_value("X-HTTP-Method-Override"), |
2428 | - Method2 = case lists:member(MethodOverride, ["GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT", "COPY"]) of |
2429 | - true -> |
2430 | - ?LOG_INFO("MethodOverride: ~s (real method was ~s)", [MethodOverride, Method1]), |
2431 | - case Method1 of |
2432 | - 'POST' -> couch_util:to_existing_atom(MethodOverride); |
2433 | - _ -> |
2434 | - % Ignore X-HTTP-Method-Override when the original verb isn't POST. |
2435 | - % I'd like to send a 406 error to the client, but that'd require a nasty refactor. |
2436 | - % throw({not_acceptable, <<"X-HTTP-Method-Override may only be used with POST requests.">>}) |
2437 | - Method1 |
2438 | - end; |
2439 | - _ -> Method1 |
2440 | - end, |
2441 | - |
2442 | - % alias HEAD to GET as mochiweb takes care of stripping the body |
2443 | - Method = case Method2 of |
2444 | - 'HEAD' -> 'GET'; |
2445 | - Other -> Other |
2446 | - end, |
2447 | - |
2448 | - HttpReq = #httpd{ |
2449 | - mochi_req = MochiReq, |
2450 | - peer = MochiReq:get(peer), |
2451 | - method = Method, |
2452 | - requested_path_parts = |
2453 | - [?l2b(unquote(Part)) || Part <- string:tokens(RequestedPath, "/")], |
2454 | - path_parts = [?l2b(unquote(Part)) || Part <- string:tokens(Path, "/")], |
2455 | - db_url_handlers = DbUrlHandlers, |
2456 | - design_url_handlers = DesignUrlHandlers, |
2457 | - default_fun = DefaultFun, |
2458 | - url_handlers = UrlHandlers, |
2459 | - user_ctx = erlang:erase(pre_rewrite_user_ctx) |
2460 | - }, |
2461 | - |
2462 | - HandlerFun = couch_util:dict_find(HandlerKey, UrlHandlers, DefaultFun), |
2463 | - {ok, AuthHandlers} = application:get_env(couch, auth_handlers), |
2464 | - |
2465 | - {ok, Resp} = |
2466 | - try |
2467 | - case authenticate_request(HttpReq, AuthHandlers) of |
2468 | - #httpd{} = Req -> |
2469 | - HandlerFun(Req); |
2470 | - Response -> |
2471 | - Response |
2472 | - end |
2473 | - catch |
2474 | - throw:{http_head_abort, Resp0} -> |
2475 | - {ok, Resp0}; |
2476 | - throw:{invalid_json, S} -> |
2477 | - ?LOG_ERROR("attempted upload of invalid JSON (set log_level to debug to log it)", []), |
2478 | - ?LOG_DEBUG("Invalid JSON: ~p",[S]), |
2479 | - send_error(HttpReq, {bad_request, invalid_json}); |
2480 | - throw:unacceptable_encoding -> |
2481 | - ?LOG_ERROR("unsupported encoding method for the response", []), |
2482 | - send_error(HttpReq, {not_acceptable, "unsupported encoding"}); |
2483 | - throw:bad_accept_encoding_value -> |
2484 | - ?LOG_ERROR("received invalid Accept-Encoding header", []), |
2485 | - send_error(HttpReq, bad_request); |
2486 | - exit:normal -> |
2487 | - exit(normal); |
2488 | - exit:snappy_nif_not_loaded -> |
2489 | - ErrorReason = "To access the database or view index, Apache CouchDB" |
2490 | - " must be built with Erlang OTP R13B04 or higher.", |
2491 | - ?LOG_ERROR("~s", [ErrorReason]), |
2492 | - send_error(HttpReq, {bad_otp_release, ErrorReason}); |
2493 | - throw:Error -> |
2494 | - Stack = erlang:get_stacktrace(), |
2495 | - ?LOG_DEBUG("Minor error in HTTP request: ~p",[Error]), |
2496 | - ?LOG_DEBUG("Stacktrace: ~p",[Stack]), |
2497 | - send_error(HttpReq, Error); |
2498 | - error:badarg -> |
2499 | - Stack = erlang:get_stacktrace(), |
2500 | - ?LOG_ERROR("Badarg error in HTTP request",[]), |
2501 | - ?LOG_INFO("Stacktrace: ~p",[Stack]), |
2502 | - send_error(HttpReq, badarg); |
2503 | - error:function_clause -> |
2504 | - Stack = erlang:get_stacktrace(), |
2505 | - ?LOG_ERROR("function_clause error in HTTP request",[]), |
2506 | - ?LOG_INFO("Stacktrace: ~p",[Stack]), |
2507 | - send_error(HttpReq, function_clause); |
2508 | - Tag:Error -> |
2509 | - Stack = erlang:get_stacktrace(), |
2510 | - ?LOG_ERROR("Uncaught error in HTTP request: ~p",[{Tag, Error}]), |
2511 | - ?LOG_INFO("Stacktrace: ~p",[Stack]), |
2512 | - send_error(HttpReq, Error) |
2513 | - end, |
2514 | - RequestTime = round(timer:now_diff(now(), Begin)/1000), |
2515 | - couch_stats_collector:record({couchdb, request_time}, RequestTime), |
2516 | - couch_stats_collector:increment({httpd, requests}), |
2517 | - {ok, Resp}. |
2518 | - |
2519 | -% Try authentication handlers in order until one sets a user_ctx |
2520 | -% the auth funs also have the option of returning a response |
2521 | -% move this to couch_httpd_auth? |
2522 | -authenticate_request(#httpd{user_ctx=#user_ctx{}} = Req, _AuthHandlers) -> |
2523 | - Req; |
2524 | -authenticate_request(#httpd{} = Req, []) -> |
2525 | - case couch_config:get("couch_httpd_auth", "require_valid_user", "false") of |
2526 | - "true" -> |
2527 | - throw({unauthorized, <<"Authentication required.">>}); |
2528 | - "false" -> |
2529 | - Req#httpd{user_ctx=#user_ctx{}} |
2530 | - end; |
2531 | -authenticate_request(#httpd{} = Req, [{AuthFun, AuthSrc} | RestAuthHandlers]) -> |
2532 | - R = case AuthFun(Req) of |
2533 | - #httpd{user_ctx=#user_ctx{}=UserCtx}=Req2 -> |
2534 | - Req2#httpd{user_ctx=UserCtx#user_ctx{handler=AuthSrc}}; |
2535 | - Else -> Else |
2536 | - end, |
2537 | - authenticate_request(R, RestAuthHandlers); |
2538 | -authenticate_request(Response, _AuthSrcs) -> |
2539 | - Response. |
2540 | - |
2541 | -increment_method_stats(Method) -> |
2542 | - couch_stats_collector:increment({httpd_request_methods, Method}). |
2543 | - |
2544 | -validate_referer(Req) -> |
2545 | - Host = host_for_request(Req), |
2546 | - Referer = header_value(Req, "Referer", fail), |
2547 | - case Referer of |
2548 | - fail -> |
2549 | - throw({bad_request, <<"Referer header required.">>}); |
2550 | - Referer -> |
2551 | - {_,RefererHost,_,_,_} = mochiweb_util:urlsplit(Referer), |
2552 | - if |
2553 | - RefererHost =:= Host -> ok; |
2554 | - true -> throw({bad_request, <<"Referer header must match host.">>}) |
2555 | - end |
2556 | - end. |
2557 | - |
2558 | -validate_ctype(Req, Ctype) -> |
2559 | - case header_value(Req, "Content-Type") of |
2560 | - undefined -> |
2561 | - throw({bad_ctype, "Content-Type must be "++Ctype}); |
2562 | - ReqCtype -> |
2563 | - case string:tokens(ReqCtype, ";") of |
2564 | - [Ctype] -> ok; |
2565 | - [Ctype, _Rest] -> ok; |
2566 | - _Else -> |
2567 | - throw({bad_ctype, "Content-Type must be "++Ctype}) |
2568 | - end |
2569 | - end. |
2570 | - |
2571 | -% Utilities |
2572 | - |
2573 | -partition(Path) -> |
2574 | - mochiweb_util:partition(Path, "/"). |
2575 | - |
2576 | -header_value(#httpd{mochi_req=MochiReq}, Key) -> |
2577 | - MochiReq:get_header_value(Key). |
2578 | - |
2579 | -header_value(#httpd{mochi_req=MochiReq}, Key, Default) -> |
2580 | - case MochiReq:get_header_value(Key) of |
2581 | - undefined -> Default; |
2582 | - Value -> Value |
2583 | - end. |
2584 | - |
2585 | -primary_header_value(#httpd{mochi_req=MochiReq}, Key) -> |
2586 | - MochiReq:get_primary_header_value(Key). |
2587 | - |
2588 | -accepted_encodings(#httpd{mochi_req=MochiReq}) -> |
2589 | - case MochiReq:accepted_encodings(["gzip", "identity"]) of |
2590 | - bad_accept_encoding_value -> |
2591 | - throw(bad_accept_encoding_value); |
2592 | - [] -> |
2593 | - throw(unacceptable_encoding); |
2594 | - EncList -> |
2595 | - EncList |
2596 | - end. |
2597 | - |
2598 | -serve_file(Req, RelativePath, DocumentRoot) -> |
2599 | - serve_file(Req, RelativePath, DocumentRoot, []). |
2600 | - |
2601 | -serve_file(#httpd{mochi_req=MochiReq}=Req, RelativePath, DocumentRoot, ExtraHeaders) -> |
2602 | - log_request(Req, 200), |
2603 | - {ok, MochiReq:serve_file(RelativePath, DocumentRoot, |
2604 | - server_header() ++ couch_httpd_auth:cookie_auth_header(Req, []) ++ ExtraHeaders)}. |
2605 | - |
2606 | -qs_value(Req, Key) -> |
2607 | - qs_value(Req, Key, undefined). |
2608 | - |
2609 | -qs_value(Req, Key, Default) -> |
2610 | - couch_util:get_value(Key, qs(Req), Default). |
2611 | - |
2612 | -qs_json_value(Req, Key, Default) -> |
2613 | - case qs_value(Req, Key, Default) of |
2614 | - Default -> |
2615 | - Default; |
2616 | - Result -> |
2617 | - ?JSON_DECODE(Result) |
2618 | - end. |
2619 | - |
2620 | -qs(#httpd{mochi_req=MochiReq}) -> |
2621 | - MochiReq:parse_qs(). |
2622 | - |
2623 | -path(#httpd{mochi_req=MochiReq}) -> |
2624 | - MochiReq:get(path). |
2625 | - |
2626 | -host_for_request(#httpd{mochi_req=MochiReq}) -> |
2627 | - XHost = couch_config:get("httpd", "x_forwarded_host", "X-Forwarded-Host"), |
2628 | - case MochiReq:get_header_value(XHost) of |
2629 | - undefined -> |
2630 | - case MochiReq:get_header_value("Host") of |
2631 | - undefined -> |
2632 | - {ok, {Address, Port}} = inet:sockname(MochiReq:get(socket)), |
2633 | - inet_parse:ntoa(Address) ++ ":" ++ integer_to_list(Port); |
2634 | - Value1 -> |
2635 | - Value1 |
2636 | - end; |
2637 | - Value -> Value |
2638 | - end. |
2639 | - |
2640 | -absolute_uri(#httpd{mochi_req=MochiReq}=Req, Path) -> |
2641 | - Host = host_for_request(Req), |
2642 | - XSsl = couch_config:get("httpd", "x_forwarded_ssl", "X-Forwarded-Ssl"), |
2643 | - Scheme = case MochiReq:get_header_value(XSsl) of |
2644 | - "on" -> "https"; |
2645 | - _ -> |
2646 | - XProto = couch_config:get("httpd", "x_forwarded_proto", "X-Forwarded-Proto"), |
2647 | - case MochiReq:get_header_value(XProto) of |
2648 | - %% Restrict to "https" and "http" schemes only |
2649 | - "https" -> "https"; |
2650 | - _ -> case MochiReq:get(scheme) of |
2651 | - https -> "https"; |
2652 | - http -> "http" |
2653 | - end |
2654 | - end |
2655 | - end, |
2656 | - Scheme ++ "://" ++ Host ++ Path. |
2657 | - |
2658 | -unquote(UrlEncodedString) -> |
2659 | - mochiweb_util:unquote(UrlEncodedString). |
2660 | - |
2661 | -quote(UrlDecodedString) -> |
2662 | - mochiweb_util:quote_plus(UrlDecodedString). |
2663 | - |
2664 | -parse_form(#httpd{mochi_req=MochiReq}) -> |
2665 | - mochiweb_multipart:parse_form(MochiReq). |
2666 | - |
2667 | -recv(#httpd{mochi_req=MochiReq}, Len) -> |
2668 | - MochiReq:recv(Len). |
2669 | - |
2670 | -recv_chunked(#httpd{mochi_req=MochiReq}, MaxChunkSize, ChunkFun, InitState) -> |
2671 | - % Fun is called once with each chunk |
2672 | - % Fun({Length, Binary}, State) |
2673 | - % called with Length == 0 on the last time. |
2674 | - MochiReq:stream_body(MaxChunkSize, ChunkFun, InitState). |
2675 | - |
2676 | -body_length(Req) -> |
2677 | - case header_value(Req, "Transfer-Encoding") of |
2678 | - undefined -> |
2679 | - case header_value(Req, "Content-Length") of |
2680 | - undefined -> undefined; |
2681 | - Length -> list_to_integer(Length) |
2682 | - end; |
2683 | - "chunked" -> chunked; |
2684 | - Unknown -> {unknown_transfer_encoding, Unknown} |
2685 | - end. |
2686 | - |
2687 | -body(#httpd{mochi_req=MochiReq, req_body=undefined} = Req) -> |
2688 | - case body_length(Req) of |
2689 | - undefined -> |
2690 | - MaxSize = list_to_integer( |
2691 | - couch_config:get("couchdb", "max_document_size", "4294967296")), |
2692 | - MochiReq:recv_body(MaxSize); |
2693 | - chunked -> |
2694 | - ChunkFun = fun({0, _Footers}, Acc) -> |
2695 | - lists:reverse(Acc); |
2696 | - ({_Len, Chunk}, Acc) -> |
2697 | - [Chunk | Acc] |
2698 | - end, |
2699 | - recv_chunked(Req, 8192, ChunkFun, []); |
2700 | - Len -> |
2701 | - MochiReq:recv_body(Len) |
2702 | - end; |
2703 | -body(#httpd{req_body=ReqBody}) -> |
2704 | - ReqBody. |
2705 | - |
2706 | -json_body(Httpd) -> |
2707 | - ?JSON_DECODE(body(Httpd)). |
2708 | - |
2709 | -json_body_obj(Httpd) -> |
2710 | - case json_body(Httpd) of |
2711 | - {Props} -> {Props}; |
2712 | - _Else -> |
2713 | - throw({bad_request, "Request body must be a JSON object"}) |
2714 | - end. |
2715 | - |
2716 | - |
2717 | - |
2718 | -doc_etag(#doc{revs={Start, [DiskRev|_]}}) -> |
2719 | - "\"" ++ ?b2l(couch_doc:rev_to_str({Start, DiskRev})) ++ "\"". |
2720 | - |
2721 | -make_etag(Term) -> |
2722 | - <<SigInt:128/integer>> = couch_util:md5(term_to_binary(Term)), |
2723 | - iolist_to_binary([$", io_lib:format("~.36B", [SigInt]), $"]). |
2724 | - |
2725 | -etag_match(Req, CurrentEtag) when is_binary(CurrentEtag) -> |
2726 | - etag_match(Req, binary_to_list(CurrentEtag)); |
2727 | - |
2728 | -etag_match(Req, CurrentEtag) -> |
2729 | - EtagsToMatch = string:tokens( |
2730 | - header_value(Req, "If-None-Match", ""), ", "), |
2731 | - lists:member(CurrentEtag, EtagsToMatch). |
2732 | - |
2733 | -etag_respond(Req, CurrentEtag, RespFun) -> |
2734 | - case etag_match(Req, CurrentEtag) of |
2735 | - true -> |
2736 | - % the client has this in their cache. |
2737 | - send_response(Req, 304, [{"ETag", CurrentEtag}], <<>>); |
2738 | - false -> |
2739 | - % Run the function. |
2740 | - RespFun() |
2741 | - end. |
2742 | - |
2743 | -verify_is_server_admin(#httpd{user_ctx=UserCtx}) -> |
2744 | - verify_is_server_admin(UserCtx); |
2745 | -verify_is_server_admin(#user_ctx{roles=Roles}) -> |
2746 | - case lists:member(<<"_admin">>, Roles) of |
2747 | - true -> ok; |
2748 | - false -> throw({unauthorized, <<"You are not a server admin.">>}) |
2749 | - end. |
2750 | - |
2751 | -log_request(#httpd{mochi_req=MochiReq,peer=Peer}, Code) -> |
2752 | - ?LOG_INFO("~s - - ~s ~s ~B", [ |
2753 | - Peer, |
2754 | - MochiReq:get(method), |
2755 | - MochiReq:get(raw_path), |
2756 | - Code |
2757 | - ]). |
2758 | - |
2759 | - |
2760 | -start_response_length(#httpd{mochi_req=MochiReq}=Req, Code, Headers, Length) -> |
2761 | - log_request(Req, Code), |
2762 | - couch_stats_collector:increment({httpd_status_codes, Code}), |
2763 | - Resp = MochiReq:start_response_length({Code, Headers ++ server_header() ++ couch_httpd_auth:cookie_auth_header(Req, Headers), Length}), |
2764 | - case MochiReq:get(method) of |
2765 | - 'HEAD' -> throw({http_head_abort, Resp}); |
2766 | - _ -> ok |
2767 | - end, |
2768 | - {ok, Resp}. |
2769 | - |
2770 | -start_response(#httpd{mochi_req=MochiReq}=Req, Code, Headers) -> |
2771 | - log_request(Req, Code), |
2772 | - couch_stats_collector:increment({httpd_status_cdes, Code}), |
2773 | - CookieHeader = couch_httpd_auth:cookie_auth_header(Req, Headers), |
2774 | - Headers2 = Headers ++ server_header() ++ CookieHeader, |
2775 | - Resp = MochiReq:start_response({Code, Headers2}), |
2776 | - case MochiReq:get(method) of |
2777 | - 'HEAD' -> throw({http_head_abort, Resp}); |
2778 | - _ -> ok |
2779 | - end, |
2780 | - {ok, Resp}. |
2781 | - |
2782 | -send(Resp, Data) -> |
2783 | - Resp:send(Data), |
2784 | - {ok, Resp}. |
2785 | - |
2786 | -no_resp_conn_header([]) -> |
2787 | - true; |
2788 | -no_resp_conn_header([{Hdr, _}|Rest]) -> |
2789 | - case string:to_lower(Hdr) of |
2790 | - "connection" -> false; |
2791 | - _ -> no_resp_conn_header(Rest) |
2792 | - end. |
2793 | - |
2794 | -http_1_0_keep_alive(Req, Headers) -> |
2795 | - KeepOpen = Req:should_close() == false, |
2796 | - IsHttp10 = Req:get(version) == {1, 0}, |
2797 | - NoRespHeader = no_resp_conn_header(Headers), |
2798 | - case KeepOpen andalso IsHttp10 andalso NoRespHeader of |
2799 | - true -> [{"Connection", "Keep-Alive"} | Headers]; |
2800 | - false -> Headers |
2801 | - end. |
2802 | - |
2803 | -start_chunked_response(#httpd{mochi_req=MochiReq}=Req, Code, Headers) -> |
2804 | - log_request(Req, Code), |
2805 | - couch_stats_collector:increment({httpd_status_codes, Code}), |
2806 | - Headers2 = http_1_0_keep_alive(MochiReq, Headers), |
2807 | - Resp = MochiReq:respond({Code, Headers2 ++ server_header() ++ couch_httpd_auth:cookie_auth_header(Req, Headers2), chunked}), |
2808 | - case MochiReq:get(method) of |
2809 | - 'HEAD' -> throw({http_head_abort, Resp}); |
2810 | - _ -> ok |
2811 | - end, |
2812 | - {ok, Resp}. |
2813 | - |
2814 | -send_chunk(Resp, Data) -> |
2815 | - case iolist_size(Data) of |
2816 | - 0 -> ok; % do nothing |
2817 | - _ -> Resp:write_chunk(Data) |
2818 | - end, |
2819 | - {ok, Resp}. |
2820 | - |
2821 | -last_chunk(Resp) -> |
2822 | - Resp:write_chunk([]), |
2823 | - {ok, Resp}. |
2824 | - |
2825 | -send_response(#httpd{mochi_req=MochiReq}=Req, Code, Headers, Body) -> |
2826 | - log_request(Req, Code), |
2827 | - couch_stats_collector:increment({httpd_status_codes, Code}), |
2828 | - Headers2 = http_1_0_keep_alive(MochiReq, Headers), |
2829 | - if Code >= 400 -> |
2830 | - ?LOG_DEBUG("httpd ~p error response:~n ~s", [Code, Body]); |
2831 | - true -> ok |
2832 | - end, |
2833 | - {ok, MochiReq:respond({Code, Headers2 ++ server_header() ++ couch_httpd_auth:cookie_auth_header(Req, Headers2), Body})}. |
2834 | - |
2835 | -send_method_not_allowed(Req, Methods) -> |
2836 | - send_error(Req, 405, [{"Allow", Methods}], <<"method_not_allowed">>, ?l2b("Only " ++ Methods ++ " allowed")). |
2837 | - |
2838 | -send_json(Req, Value) -> |
2839 | - send_json(Req, 200, Value). |
2840 | - |
2841 | -send_json(Req, Code, Value) -> |
2842 | - send_json(Req, Code, [], Value). |
2843 | - |
2844 | -send_json(Req, Code, Headers, Value) -> |
2845 | - initialize_jsonp(Req), |
2846 | - DefaultHeaders = [ |
2847 | - {"Content-Type", negotiate_content_type(Req)}, |
2848 | - {"Cache-Control", "must-revalidate"} |
2849 | - ], |
2850 | - Body = [start_jsonp(), ?JSON_ENCODE(Value), end_jsonp(), $\n], |
2851 | - send_response(Req, Code, DefaultHeaders ++ Headers, Body). |
2852 | - |
2853 | -start_json_response(Req, Code) -> |
2854 | - start_json_response(Req, Code, []). |
2855 | - |
2856 | -start_json_response(Req, Code, Headers) -> |
2857 | - initialize_jsonp(Req), |
2858 | - DefaultHeaders = [ |
2859 | - {"Content-Type", negotiate_content_type(Req)}, |
2860 | - {"Cache-Control", "must-revalidate"} |
2861 | - ], |
2862 | - {ok, Resp} = start_chunked_response(Req, Code, DefaultHeaders ++ Headers), |
2863 | - case start_jsonp() of |
2864 | - [] -> ok; |
2865 | - Start -> send_chunk(Resp, Start) |
2866 | - end, |
2867 | - {ok, Resp}. |
2868 | - |
2869 | -end_json_response(Resp) -> |
2870 | - send_chunk(Resp, end_jsonp() ++ [$\n]), |
2871 | - last_chunk(Resp). |
2872 | - |
2873 | -initialize_jsonp(Req) -> |
2874 | - case get(jsonp) of |
2875 | - undefined -> put(jsonp, qs_value(Req, "callback", no_jsonp)); |
2876 | - _ -> ok |
2877 | - end, |
2878 | - case get(jsonp) of |
2879 | - no_jsonp -> []; |
2880 | - [] -> []; |
2881 | - CallBack -> |
2882 | - try |
2883 | - % make sure jsonp is configured on (default off) |
2884 | - case couch_config:get("httpd", "allow_jsonp", "false") of |
2885 | - "true" -> |
2886 | - validate_callback(CallBack); |
2887 | - _Else -> |
2888 | - put(jsonp, no_jsonp) |
2889 | - end |
2890 | - catch |
2891 | - Error -> |
2892 | - put(jsonp, no_jsonp), |
2893 | - throw(Error) |
2894 | - end |
2895 | - end. |
2896 | - |
2897 | -start_jsonp() -> |
2898 | - case get(jsonp) of |
2899 | - no_jsonp -> []; |
2900 | - [] -> []; |
2901 | - CallBack -> CallBack ++ "(" |
2902 | - end. |
2903 | - |
2904 | -end_jsonp() -> |
2905 | - case erlang:erase(jsonp) of |
2906 | - no_jsonp -> []; |
2907 | - [] -> []; |
2908 | - _ -> ");" |
2909 | - end. |
2910 | - |
2911 | -validate_callback(CallBack) when is_binary(CallBack) -> |
2912 | - validate_callback(binary_to_list(CallBack)); |
2913 | -validate_callback([]) -> |
2914 | - ok; |
2915 | -validate_callback([Char | Rest]) -> |
2916 | - case Char of |
2917 | - _ when Char >= $a andalso Char =< $z -> ok; |
2918 | - _ when Char >= $A andalso Char =< $Z -> ok; |
2919 | - _ when Char >= $0 andalso Char =< $9 -> ok; |
2920 | - _ when Char == $. -> ok; |
2921 | - _ when Char == $_ -> ok; |
2922 | - _ when Char == $[ -> ok; |
2923 | - _ when Char == $] -> ok; |
2924 | - _ -> |
2925 | - throw({bad_request, invalid_callback}) |
2926 | - end, |
2927 | - validate_callback(Rest). |
2928 | - |
2929 | - |
2930 | -error_info({Error, Reason}) when is_list(Reason) -> |
2931 | - error_info({Error, ?l2b(Reason)}); |
2932 | -error_info(bad_request) -> |
2933 | - {400, <<"bad_request">>, <<>>}; |
2934 | -error_info({bad_request, Reason}) -> |
2935 | - {400, <<"bad_request">>, Reason}; |
2936 | -error_info({query_parse_error, Reason}) -> |
2937 | - {400, <<"query_parse_error">>, Reason}; |
2938 | -% Prior art for md5 mismatch resulting in a 400 is from AWS S3 |
2939 | -error_info(md5_mismatch) -> |
2940 | - {400, <<"content_md5_mismatch">>, <<"Possible message corruption.">>}; |
2941 | -error_info(not_found) -> |
2942 | - {404, <<"not_found">>, <<"missing">>}; |
2943 | -error_info({not_found, Reason}) -> |
2944 | - {404, <<"not_found">>, Reason}; |
2945 | -error_info({not_acceptable, Reason}) -> |
2946 | - {406, <<"not_acceptable">>, Reason}; |
2947 | -error_info(conflict) -> |
2948 | - {409, <<"conflict">>, <<"Document update conflict.">>}; |
2949 | -error_info({forbidden, Msg}) -> |
2950 | - {403, <<"forbidden">>, Msg}; |
2951 | -error_info({unauthorized, Msg}) -> |
2952 | - {401, <<"unauthorized">>, Msg}; |
2953 | -error_info(file_exists) -> |
2954 | - {412, <<"file_exists">>, <<"The database could not be " |
2955 | - "created, the file already exists.">>}; |
2956 | -error_info({bad_ctype, Reason}) -> |
2957 | - {415, <<"bad_content_type">>, Reason}; |
2958 | -error_info(requested_range_not_satisfiable) -> |
2959 | - {416, <<"requested_range_not_satisfiable">>, <<"Requested range not satisfiable">>}; |
2960 | -error_info({error, illegal_database_name}) -> |
2961 | - {400, <<"illegal_database_name">>, <<"Only lowercase characters (a-z), " |
2962 | - "digits (0-9), and any of the characters _, $, (, ), +, -, and / " |
2963 | - "are allowed. Must begin with a letter.">>}; |
2964 | -error_info({missing_stub, Reason}) -> |
2965 | - {412, <<"missing_stub">>, Reason}; |
2966 | -error_info({Error, Reason}) -> |
2967 | - ?LOG_ERROR("Uncaught server error: ~p", [{Error, Reason}]), |
2968 | - {500, couch_util:to_binary(Error), couch_util:to_binary(Reason)}; |
2969 | -error_info(Error) -> |
2970 | - ?LOG_ERROR("Uncaught server error: ~p", [Error]), |
2971 | - {500, <<"unknown_error">>, couch_util:to_binary(Error)}. |
2972 | - |
2973 | -error_headers(#httpd{mochi_req=MochiReq}=Req, Code, ErrorStr, ReasonStr) -> |
2974 | - if Code == 401 -> |
2975 | - % this is where the basic auth popup is triggered |
2976 | - case MochiReq:get_header_value("X-CouchDB-WWW-Authenticate") of |
2977 | - undefined -> |
2978 | - case couch_config:get("httpd", "WWW-Authenticate", nil) of |
2979 | - nil -> |
2980 | - % If the client is a browser and the basic auth popup isn't turned on |
2981 | - % redirect to the session page. |
2982 | - case ErrorStr of |
2983 | - <<"unauthorized">> -> |
2984 | - case couch_config:get("couch_httpd_auth", "authentication_redirect", nil) of |
2985 | - nil -> {Code, []}; |
2986 | - AuthRedirect -> |
2987 | - case couch_config:get("couch_httpd_auth", "require_valid_user", "false") of |
2988 | - "true" -> |
2989 | - % send the browser popup header no matter what if we are require_valid_user |
2990 | - {Code, [{"WWW-Authenticate", "Basic realm=\"server\""}]}; |
2991 | - _False -> |
2992 | - case MochiReq:accepts_content_type("application/json") of |
2993 | - true -> |
2994 | - {Code, []}; |
2995 | - false -> |
2996 | - case MochiReq:accepts_content_type("text/html") of |
2997 | - true -> |
2998 | - % Redirect to the path the user requested, not |
2999 | - % the one that is used internally. |
3000 | - UrlReturnRaw = case MochiReq:get_header_value("x-couchdb-vhost-path") of |
3001 | - undefined -> |
3002 | - MochiReq:get(path); |
3003 | - VHostPath -> |
3004 | - VHostPath |
3005 | - end, |
3006 | - RedirectLocation = lists:flatten([ |
3007 | - AuthRedirect, |
3008 | - "?return=", couch_util:url_encode(UrlReturnRaw), |
3009 | - "&reason=", couch_util:url_encode(ReasonStr) |
3010 | - ]), |
3011 | - {302, [{"Location", absolute_uri(Req, RedirectLocation)}]}; |
3012 | - false -> |
3013 | - {Code, []} |
3014 | - end |
3015 | - end |
3016 | - end |
3017 | - end; |
3018 | - _Else -> |
3019 | - {Code, []} |
3020 | - end; |
3021 | - Type -> |
3022 | - {Code, [{"WWW-Authenticate", Type}]} |
3023 | - end; |
3024 | - Type -> |
3025 | - {Code, [{"WWW-Authenticate", Type}]} |
3026 | - end; |
3027 | - true -> |
3028 | - {Code, []} |
3029 | - end. |
3030 | - |
3031 | -send_error(_Req, {already_sent, Resp, _Error}) -> |
3032 | - {ok, Resp}; |
3033 | - |
3034 | -send_error(Req, Error) -> |
3035 | - {Code, ErrorStr, ReasonStr} = error_info(Error), |
3036 | - {Code1, Headers} = error_headers(Req, Code, ErrorStr, ReasonStr), |
3037 | - send_error(Req, Code1, Headers, ErrorStr, ReasonStr). |
3038 | - |
3039 | -send_error(Req, Code, ErrorStr, ReasonStr) -> |
3040 | - send_error(Req, Code, [], ErrorStr, ReasonStr). |
3041 | - |
3042 | -send_error(Req, Code, Headers, ErrorStr, ReasonStr) -> |
3043 | - send_json(Req, Code, Headers, |
3044 | - {[{<<"error">>, ErrorStr}, |
3045 | - {<<"reason">>, ReasonStr}]}). |
3046 | - |
3047 | -% give the option for list functions to output html or other raw errors |
3048 | -send_chunked_error(Resp, {_Error, {[{<<"body">>, Reason}]}}) -> |
3049 | - send_chunk(Resp, Reason), |
3050 | - last_chunk(Resp); |
3051 | - |
3052 | -send_chunked_error(Resp, Error) -> |
3053 | - {Code, ErrorStr, ReasonStr} = error_info(Error), |
3054 | - JsonError = {[{<<"code">>, Code}, |
3055 | - {<<"error">>, ErrorStr}, |
3056 | - {<<"reason">>, ReasonStr}]}, |
3057 | - send_chunk(Resp, ?l2b([$\n,?JSON_ENCODE(JsonError),$\n])), |
3058 | - last_chunk(Resp). |
3059 | - |
3060 | -send_redirect(Req, Path) -> |
3061 | - send_response(Req, 301, [{"Location", absolute_uri(Req, Path)}], <<>>). |
3062 | - |
3063 | -negotiate_content_type(Req) -> |
3064 | - case get(jsonp) of |
3065 | - no_jsonp -> negotiate_content_type1(Req); |
3066 | - [] -> negotiate_content_type1(Req); |
3067 | - _Callback -> "text/javascript" |
3068 | - end. |
3069 | - |
3070 | -negotiate_content_type1(#httpd{mochi_req=MochiReq}) -> |
3071 | - %% Determine the appropriate Content-Type header for a JSON response |
3072 | - %% depending on the Accept header in the request. A request that explicitly |
3073 | - %% lists the correct JSON MIME type will get that type, otherwise the |
3074 | - %% response will have the generic MIME type "text/plain" |
3075 | - AcceptedTypes = case MochiReq:get_header_value("Accept") of |
3076 | - undefined -> []; |
3077 | - AcceptHeader -> string:tokens(AcceptHeader, ", ") |
3078 | - end, |
3079 | - case lists:member("application/json", AcceptedTypes) of |
3080 | - true -> "application/json"; |
3081 | - false -> "text/plain; charset=utf-8" |
3082 | - end. |
3083 | - |
3084 | -server_header() -> |
3085 | - [{"Server", "CouchDB/" ++ couch_server:get_version() ++ |
3086 | - " (Erlang OTP/" ++ erlang:system_info(otp_release) ++ ")"}]. |
3087 | - |
3088 | - |
3089 | --record(mp, {boundary, buffer, data_fun, callback}). |
3090 | - |
3091 | - |
3092 | -parse_multipart_request(ContentType, DataFun, Callback) -> |
3093 | - Boundary0 = iolist_to_binary(get_boundary(ContentType)), |
3094 | - Boundary = <<"\r\n--", Boundary0/binary>>, |
3095 | - Mp = #mp{boundary= Boundary, |
3096 | - buffer= <<>>, |
3097 | - data_fun=DataFun, |
3098 | - callback=Callback}, |
3099 | - {Mp2, _NilCallback} = read_until(Mp, <<"--", Boundary0/binary>>, |
3100 | - fun nil_callback/1), |
3101 | - #mp{buffer=Buffer, data_fun=DataFun2, callback=Callback2} = |
3102 | - parse_part_header(Mp2), |
3103 | - {Buffer, DataFun2, Callback2}. |
3104 | - |
3105 | -nil_callback(_Data)-> |
3106 | - fun nil_callback/1. |
3107 | - |
3108 | -get_boundary({"multipart/" ++ _, Opts}) -> |
3109 | - case couch_util:get_value("boundary", Opts) of |
3110 | - S when is_list(S) -> |
3111 | - S |
3112 | - end; |
3113 | -get_boundary(ContentType) -> |
3114 | - {"multipart/" ++ _ , Opts} = mochiweb_util:parse_header(ContentType), |
3115 | - get_boundary({"multipart/", Opts}). |
3116 | - |
3117 | - |
3118 | - |
3119 | -split_header(<<>>) -> |
3120 | - []; |
3121 | -split_header(Line) -> |
3122 | - {Name, [$: | Value]} = lists:splitwith(fun (C) -> C =/= $: end, |
3123 | - binary_to_list(Line)), |
3124 | - [{string:to_lower(string:strip(Name)), |
3125 | - mochiweb_util:parse_header(Value)}]. |
3126 | - |
3127 | -read_until(#mp{data_fun=DataFun, buffer=Buffer}=Mp, Pattern, Callback) -> |
3128 | - case find_in_binary(Pattern, Buffer) of |
3129 | - not_found -> |
3130 | - Callback2 = Callback(Buffer), |
3131 | - {Buffer2, DataFun2} = DataFun(), |
3132 | - Buffer3 = iolist_to_binary(Buffer2), |
3133 | - read_until(Mp#mp{data_fun=DataFun2,buffer=Buffer3}, Pattern, Callback2); |
3134 | - {partial, 0} -> |
3135 | - {NewData, DataFun2} = DataFun(), |
3136 | - read_until(Mp#mp{data_fun=DataFun2, |
3137 | - buffer= iolist_to_binary([Buffer,NewData])}, |
3138 | - Pattern, Callback); |
3139 | - {partial, Skip} -> |
3140 | - <<DataChunk:Skip/binary, Rest/binary>> = Buffer, |
3141 | - Callback2 = Callback(DataChunk), |
3142 | - {NewData, DataFun2} = DataFun(), |
3143 | - read_until(Mp#mp{data_fun=DataFun2, |
3144 | - buffer= iolist_to_binary([Rest | NewData])}, |
3145 | - Pattern, Callback2); |
3146 | - {exact, 0} -> |
3147 | - PatternLen = size(Pattern), |
3148 | - <<_:PatternLen/binary, Rest/binary>> = Buffer, |
3149 | - {Mp#mp{buffer= Rest}, Callback}; |
3150 | - {exact, Skip} -> |
3151 | - PatternLen = size(Pattern), |
3152 | - <<DataChunk:Skip/binary, _:PatternLen/binary, Rest/binary>> = Buffer, |
3153 | - Callback2 = Callback(DataChunk), |
3154 | - {Mp#mp{buffer= Rest}, Callback2} |
3155 | - end. |
3156 | - |
3157 | - |
3158 | -parse_part_header(#mp{callback=UserCallBack}=Mp) -> |
3159 | - {Mp2, AccCallback} = read_until(Mp, <<"\r\n\r\n">>, |
3160 | - fun(Next) -> acc_callback(Next, []) end), |
3161 | - HeaderData = AccCallback(get_data), |
3162 | - |
3163 | - Headers = |
3164 | - lists:foldl(fun(Line, Acc) -> |
3165 | - split_header(Line) ++ Acc |
3166 | - end, [], re:split(HeaderData,<<"\r\n">>, [])), |
3167 | - NextCallback = UserCallBack({headers, Headers}), |
3168 | - parse_part_body(Mp2#mp{callback=NextCallback}). |
3169 | - |
3170 | -parse_part_body(#mp{boundary=Prefix, callback=Callback}=Mp) -> |
3171 | - {Mp2, WrappedCallback} = read_until(Mp, Prefix, |
3172 | - fun(Data) -> body_callback_wrapper(Data, Callback) end), |
3173 | - Callback2 = WrappedCallback(get_callback), |
3174 | - Callback3 = Callback2(body_end), |
3175 | - case check_for_last(Mp2#mp{callback=Callback3}) of |
3176 | - {last, #mp{callback=Callback3}=Mp3} -> |
3177 | - Mp3#mp{callback=Callback3(eof)}; |
3178 | - {more, Mp3} -> |
3179 | - parse_part_header(Mp3) |
3180 | - end. |
3181 | - |
3182 | -acc_callback(get_data, Acc)-> |
3183 | - iolist_to_binary(lists:reverse(Acc)); |
3184 | -acc_callback(Data, Acc)-> |
3185 | - fun(Next) -> acc_callback(Next, [Data | Acc]) end. |
3186 | - |
3187 | -body_callback_wrapper(get_callback, Callback) -> |
3188 | - Callback; |
3189 | -body_callback_wrapper(Data, Callback) -> |
3190 | - Callback2 = Callback({body, Data}), |
3191 | - fun(Next) -> body_callback_wrapper(Next, Callback2) end. |
3192 | - |
3193 | - |
3194 | -check_for_last(#mp{buffer=Buffer, data_fun=DataFun}=Mp) -> |
3195 | - case Buffer of |
3196 | - <<"--",_/binary>> -> {last, Mp}; |
3197 | - <<_, _, _/binary>> -> {more, Mp}; |
3198 | - _ -> % not long enough |
3199 | - {Data, DataFun2} = DataFun(), |
3200 | - check_for_last(Mp#mp{buffer= <<Buffer/binary, Data/binary>>, |
3201 | - data_fun = DataFun2}) |
3202 | - end. |
3203 | - |
3204 | -find_in_binary(B, Data) when size(B) > 0 -> |
3205 | - case size(Data) - size(B) of |
3206 | - Last when Last < 0 -> |
3207 | - partial_find(B, Data, 0, size(Data)); |
3208 | - Last -> |
3209 | - find_in_binary(B, size(B), Data, 0, Last) |
3210 | - end. |
3211 | - |
3212 | -find_in_binary(B, BS, D, N, Last) when N =< Last-> |
3213 | - case D of |
3214 | - <<_:N/binary, B:BS/binary, _/binary>> -> |
3215 | - {exact, N}; |
3216 | - _ -> |
3217 | - find_in_binary(B, BS, D, 1 + N, Last) |
3218 | - end; |
3219 | -find_in_binary(B, BS, D, N, Last) when N =:= 1 + Last -> |
3220 | - partial_find(B, D, N, BS - 1). |
3221 | - |
3222 | -partial_find(_B, _D, _N, 0) -> |
3223 | - not_found; |
3224 | -partial_find(B, D, N, K) -> |
3225 | - <<B1:K/binary, _/binary>> = B, |
3226 | - case D of |
3227 | - <<_Skip:N/binary, B1/binary>> -> |
3228 | - {partial, N}; |
3229 | - _ -> |
3230 | - partial_find(B, D, 1 + N, K - 1) |
3231 | - end. |
3232 | - |
3233 | - |
3234 | |
3235 | === removed directory '.pc/logrotate_as_couchdb.patch' |
3236 | === removed directory '.pc/logrotate_as_couchdb.patch/etc' |
3237 | === removed directory '.pc/logrotate_as_couchdb.patch/etc/logrotate.d' |
3238 | === removed file '.pc/logrotate_as_couchdb.patch/etc/logrotate.d/couchdb.tpl.in' |
3239 | --- .pc/logrotate_as_couchdb.patch/etc/logrotate.d/couchdb.tpl.in 2012-11-18 12:24:24 +0000 |
3240 | +++ .pc/logrotate_as_couchdb.patch/etc/logrotate.d/couchdb.tpl.in 1970-01-01 00:00:00 +0000 |
3241 | @@ -1,9 +0,0 @@ |
3242 | -%localstatelogdir%/*.log { |
3243 | - weekly |
3244 | - rotate 10 |
3245 | - copytruncate |
3246 | - delaycompress |
3247 | - compress |
3248 | - notifempty |
3249 | - missingok |
3250 | -} |
3251 | |
3252 | === removed directory '.pc/wait_for_couchdb_stop.patch' |
3253 | === removed directory '.pc/wait_for_couchdb_stop.patch/etc' |
3254 | === removed directory '.pc/wait_for_couchdb_stop.patch/etc/init' |
3255 | === removed file '.pc/wait_for_couchdb_stop.patch/etc/init/couchdb.tpl.in' |
3256 | --- .pc/wait_for_couchdb_stop.patch/etc/init/couchdb.tpl.in 2012-11-18 12:24:24 +0000 |
3257 | +++ .pc/wait_for_couchdb_stop.patch/etc/init/couchdb.tpl.in 1970-01-01 00:00:00 +0000 |
3258 | @@ -1,157 +0,0 @@ |
3259 | -#!/bin/sh -e |
3260 | - |
3261 | -# Licensed under the Apache License, Version 2.0 (the "License"); you may not |
3262 | -# use this file except in compliance with the License. You may obtain a copy of |
3263 | -# the License at |
3264 | -# |
3265 | -# http://www.apache.org/licenses/LICENSE-2.0 |
3266 | -# |
3267 | -# Unless required by applicable law or agreed to in writing, software |
3268 | -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
3269 | -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
3270 | -# License for the specific language governing permissions and limitations under |
3271 | -# the License. |
3272 | - |
3273 | -### BEGIN INIT INFO |
3274 | -# Provides: couchdb |
3275 | -# Required-Start: $local_fs $remote_fs |
3276 | -# Required-Stop: $local_fs $remote_fs |
3277 | -# Default-Start: 2 3 4 5 |
3278 | -# Default-Stop: 0 1 6 |
3279 | -# Short-Description: Apache CouchDB init script |
3280 | -# Description: Apache CouchDB init script for the database server. |
3281 | -### END INIT INFO |
3282 | - |
3283 | -SCRIPT_OK=0 |
3284 | -SCRIPT_ERROR=1 |
3285 | - |
3286 | -DESCRIPTION="database server" |
3287 | -NAME=couchdb |
3288 | -SCRIPT_NAME=`basename $0` |
3289 | -COUCHDB=%bindir%/%couchdb_command_name% |
3290 | -CONFIGURATION_FILE=%sysconfdir%/default/couchdb |
3291 | -RUN_DIR=%localstaterundir% |
3292 | -LSB_LIBRARY=/lib/lsb/init-functions |
3293 | - |
3294 | -if test ! -x $COUCHDB; then |
3295 | - exit $SCRIPT_ERROR |
3296 | -fi |
3297 | - |
3298 | -if test -r $CONFIGURATION_FILE; then |
3299 | - . $CONFIGURATION_FILE |
3300 | -fi |
3301 | - |
3302 | -log_daemon_msg () { |
3303 | - # Dummy function to be replaced by LSB library. |
3304 | - |
3305 | - echo $@ |
3306 | -} |
3307 | - |
3308 | -log_end_msg () { |
3309 | - # Dummy function to be replaced by LSB library. |
3310 | - |
3311 | - if test "$1" != "0"; then |
3312 | - echo "Error with $DESCRIPTION: $NAME" |
3313 | - fi |
3314 | - return $1 |
3315 | -} |
3316 | - |
3317 | -if test -r $LSB_LIBRARY; then |
3318 | - . $LSB_LIBRARY |
3319 | -fi |
3320 | - |
3321 | -run_command () { |
3322 | - command="$1" |
3323 | - if test -n "$COUCHDB_OPTIONS"; then |
3324 | - command="$command $COUCHDB_OPTIONS" |
3325 | - fi |
3326 | - if test -n "$COUCHDB_USER"; then |
3327 | - if su $COUCHDB_USER -c "$command"; then |
3328 | - return $SCRIPT_OK |
3329 | - else |
3330 | - return $SCRIPT_ERROR |
3331 | - fi |
3332 | - else |
3333 | - if $command; then |
3334 | - return $SCRIPT_OK |
3335 | - else |
3336 | - return $SCRIPT_ERROR |
3337 | - fi |
3338 | - fi |
3339 | -} |
3340 | - |
3341 | -start_couchdb () { |
3342 | - # Start Apache CouchDB as a background process. |
3343 | - |
3344 | - test -e "$RUN_DIR" || \ |
3345 | - install -m 755 -o "$COUCHDB_USER" -g "$COUCHDB_USER" -d "$RUN_DIR" |
3346 | - command="$COUCHDB -b" |
3347 | - if test -n "$COUCHDB_STDOUT_FILE"; then |
3348 | - command="$command -o $COUCHDB_STDOUT_FILE" |
3349 | - fi |
3350 | - if test -n "$COUCHDB_STDERR_FILE"; then |
3351 | - command="$command -e $COUCHDB_STDERR_FILE" |
3352 | - fi |
3353 | - if test -n "$COUCHDB_RESPAWN_TIMEOUT"; then |
3354 | - command="$command -r $COUCHDB_RESPAWN_TIMEOUT" |
3355 | - fi |
3356 | - run_command "$command" > /dev/null |
3357 | -} |
3358 | - |
3359 | -stop_couchdb () { |
3360 | - # Stop the running Apache CouchDB process. |
3361 | - |
3362 | - run_command "$COUCHDB -d" > /dev/null |
3363 | -} |
3364 | - |
3365 | -display_status () { |
3366 | - # Display the status of the running Apache CouchDB process. |
3367 | - |
3368 | - run_command "$COUCHDB -s" |
3369 | -} |
3370 | - |
3371 | -parse_script_option_list () { |
3372 | - # Parse arguments passed to the script and take appropriate action. |
3373 | - |
3374 | - case "$1" in |
3375 | - start) |
3376 | - log_daemon_msg "Starting $DESCRIPTION" $NAME |
3377 | - if start_couchdb; then |
3378 | - log_end_msg $SCRIPT_OK |
3379 | - else |
3380 | - log_end_msg $SCRIPT_ERROR |
3381 | - fi |
3382 | - ;; |
3383 | - stop) |
3384 | - log_daemon_msg "Stopping $DESCRIPTION" $NAME |
3385 | - if stop_couchdb; then |
3386 | - log_end_msg $SCRIPT_OK |
3387 | - else |
3388 | - log_end_msg $SCRIPT_ERROR |
3389 | - fi |
3390 | - ;; |
3391 | - restart|force-reload) |
3392 | - log_daemon_msg "Restarting $DESCRIPTION" $NAME |
3393 | - if stop_couchdb; then |
3394 | - if start_couchdb; then |
3395 | - log_end_msg $SCRIPT_OK |
3396 | - else |
3397 | - log_end_msg $SCRIPT_ERROR |
3398 | - fi |
3399 | - else |
3400 | - log_end_msg $SCRIPT_ERROR |
3401 | - fi |
3402 | - ;; |
3403 | - status) |
3404 | - display_status |
3405 | - ;; |
3406 | - *) |
3407 | - cat << EOF >&2 |
3408 | -Usage: $SCRIPT_NAME {start|stop|restart|force-reload|status} |
3409 | -EOF |
3410 | - exit $SCRIPT_ERROR |
3411 | - ;; |
3412 | - esac |
3413 | -} |
3414 | - |
3415 | -parse_script_option_list $@ |
3416 | |
3417 | === modified file 'AUTHORS' |
3418 | --- AUTHORS 2012-07-30 22:49:59 +0000 |
3419 | +++ AUTHORS 2013-08-30 22:06:57 +0000 |
3420 | @@ -20,5 +20,11 @@ |
3421 | * Bob Dionne <bitdiddle@apache.org> |
3422 | * Dave Cottlehuber <dch@apache.org> |
3423 | * Jason Smith <jhs@apache.org> |
3424 | + * Joan Touzet <joant@ieee.org> |
3425 | + * Dale Harvey <dale@apache.org> |
3426 | + * Dirkjan Ochtman <djc@apache.org> |
3427 | + * Alexander Shorin <kxepal@apache.org> |
3428 | + * Garren Smith <garren@apache.org> |
3429 | + * Sue Lockwood <deathbear@apache.org> |
3430 | |
3431 | For a list of other credits see the `THANKS` file. |
3432 | |
3433 | === modified file 'BUGS' |
3434 | --- BUGS 2009-04-14 16:32:45 +0000 |
3435 | +++ BUGS 2013-08-30 22:06:57 +0000 |
3436 | @@ -1,6 +1,8 @@ |
3437 | Apache CouchDB BUGS |
3438 | =================== |
3439 | |
3440 | -Please see the [documentation][1] on how to report bugs with Apache CouchDB. |
3441 | - |
3442 | -[1] http://couchdb.apache.org/community/issues.html |
3443 | +Visit our issue tracker: |
3444 | + |
3445 | + https://issues.apache.org/jira/browse/CouchDB |
3446 | + |
3447 | +You can use this to report bugs, request features, or suggest enhancements. |
3448 | |
3449 | === removed file 'CHANGES' |
3450 | --- CHANGES 2012-07-30 22:49:59 +0000 |
3451 | +++ CHANGES 1970-01-01 00:00:00 +0000 |
3452 | @@ -1,874 +0,0 @@ |
3453 | -Apache CouchDB CHANGES |
3454 | -====================== |
3455 | - |
3456 | -Version 1.2.0 |
3457 | -------------- |
3458 | - |
3459 | -Authentication: |
3460 | - |
3461 | - * Fix use of OAuth with VHosts and URL rewriting. |
3462 | - * OAuth secrets can now be stored in the users system database |
3463 | - as an alternative to key value pairs in the .ini configuration. |
3464 | - By default this is disabled (secrets are stored in the .ini) |
3465 | - but can be enabled via the .ini configuration key `use_users_db` |
3466 | - in the `couch_httpd_oauth` section. |
3467 | - * Documents in the _users database are no longer publicly |
3468 | - readable. |
3469 | - * Confidential information in the _replication database is no |
3470 | - longer publicly readable. |
3471 | - * Password hashes are now calculated by CouchDB. Clients are no |
3472 | - longer required to do this manually. |
3473 | - * Cookies used for authentication can be made persistent by enabling |
3474 | - the .ini configuration key `allow_persistent_cookies' in the |
3475 | - `couch_httpd_auth` section. |
3476 | - |
3477 | -Build System: |
3478 | - |
3479 | - * cURL is no longer required to build CouchDB as it is only |
3480 | - used by the command line JS test runner. If cURL is available |
3481 | - when building CouchJS you can enable the HTTP bindings by |
3482 | - passing -H on the command line. |
3483 | - * Temporarily made `make check` pass with R15B. A more thorough |
3484 | - fix is in the works (COUCHDB-1424). |
3485 | - * Fixed --with-js-include and --with-js-lib options. |
3486 | - * Added --with-js-lib-name option. |
3487 | - |
3488 | -HTTP Interface: |
3489 | - |
3490 | - * Added a native JSON parser. |
3491 | - * The _active_tasks API now offers more granular fields. Each |
3492 | - task type is now able to expose different properties. |
3493 | - * Added built-in changes feed filter `_view`. |
3494 | - * Fixes to the `_changes` feed heartbeat option which caused |
3495 | - heartbeats to be missed when used with a filter. This caused |
3496 | - timeouts of continuous pull replications with a filter. |
3497 | - * Properly restart the SSL socket on configuration changes. |
3498 | - |
3499 | -Replicator: |
3500 | - |
3501 | - * A new replicator implementation. It offers more performance and |
3502 | - configuration options. |
3503 | - * Passing non-string values to query_params is now a 400 bad |
3504 | - request. This is to reduce the surprise that all parameters |
3505 | - are converted to strings internally. |
3506 | - * Added optional field `since_seq` to replication objects/documents. |
3507 | - It allows to bootstrap a replication from a specific source sequence |
3508 | - number. |
3509 | - * Simpler replication cancellation. In addition to the current method, |
3510 | - replications can now be canceled by specifying the replication ID |
3511 | - instead of the original replication object/document. |
3512 | - |
3513 | -Storage System: |
3514 | - |
3515 | - * Added optional database and view index file compression (using Google's |
3516 | - snappy or zlib's deflate). This feature is enabled by default, but it |
3517 | - can be disabled by adapting local.ini accordingly. The on-disk format |
3518 | - is upgraded on compaction and new DB/view creation to support this. |
3519 | - * Several performance improvements, most notably regarding database writes |
3520 | - and view indexing. |
3521 | - * Computation of the size of the latest MVCC snapshot data and all its |
3522 | - supporting metadata, both for database and view index files. This |
3523 | - information is exposed as the `data_size` attribute in the database and |
3524 | - view group information URIs. |
3525 | - * The size of the buffers used for database and view compaction is now |
3526 | - configurable. |
3527 | - * Added support for automatic database and view compaction. This feature |
3528 | - is disabled by default, but it can be enabled via the .ini configuration. |
3529 | - * Performance improvements for the built-in changes feed filters `_doc_ids` |
3530 | - and `_design'. |
3531 | - |
3532 | -View Server: |
3533 | - |
3534 | - * Add CoffeeScript (http://coffeescript.org/) as a first class view server |
3535 | - language. |
3536 | - * Fixed old index file descriptor leaks after a view cleanup. |
3537 | - * The requested_path property keeps the pre-rewrite path even when no VHost |
3538 | - configuration is matched. |
3539 | - * Fixed incorrect reduce query results when using pagination parameters. |
3540 | - * Made icu_driver work with Erlang R15B and later. |
3541 | - * Avoid invalidating view indexes when running out of file descriptors. |
3542 | - |
3543 | -OAuth: |
3544 | - |
3545 | - * Updated bundled erlang_oauth library to the latest version. |
3546 | - |
3547 | -Futon: |
3548 | - |
3549 | - * The `Status` screen (active tasks) now displays two new task status |
3550 | - fields: `Started on` and `Updated on`. |
3551 | - * Futon remembers view code every time it is saved, allowing to save an |
3552 | - edit that amounts to a revert. |
3553 | - |
3554 | -Log System: |
3555 | - |
3556 | - * Log correct stacktrace in all cases. |
3557 | - * Improvements to log messages for file-related errors. |
3558 | - |
3559 | -Version 1.1.1 |
3560 | -------------- |
3561 | - |
3562 | -* Support SpiderMonkey 1.8.5 |
3563 | -* Add configurable maximum to the number of bytes returned by _log. |
3564 | -* Allow CommonJS modules to be an empty string. |
3565 | -* Bump minimum Erlang version to R13B02. |
3566 | -* Do not run deleted validate_doc_update functions. |
3567 | -* ETags for views include current sequence if include_docs=true. |
3568 | -* Fix bug where duplicates can appear in _changes feed. |
3569 | -* Fix bug where update handlers break after conflict resolution. |
3570 | -* Fix bug with _replicator where include "filter" could crash couch. |
3571 | -* Fix crashes when compacting large views. |
3572 | -* Fix file descriptor leak in _log |
3573 | -* Fix missing revisions in _changes?style=all_docs. |
3574 | -* Improve handling of compaction at max_dbs_open limit. |
3575 | -* JSONP responses now send "text/javascript" for Content-Type. |
3576 | -* Link to ICU 4.2 on Windows. |
3577 | -* Permit forward slashes in path to update functions. |
3578 | -* Reap couchjs processes that hit reduce_overflow error. |
3579 | -* Status code can be specified in update handlers. |
3580 | -* Support provides() in show functions. |
3581 | -* _view_cleanup when ddoc has no views now removes all index files. |
3582 | -* max_replication_retry_count now supports "infinity". |
3583 | -* Fix replication crash when source database has a document with empty ID. |
3584 | -* Fix deadlock when assigning couchjs processes to serve requests. |
3585 | -* Fixes to the document multipart PUT API. |
3586 | -* Fixes regarding file descriptor leaks for databases with views. |
3587 | - |
3588 | -Version 1.1.0 |
3589 | -------------- |
3590 | - |
3591 | -All CHANGES for 1.0.2 and 1.0.3 also apply to 1.1.0. |
3592 | - |
3593 | -HTTP Interface: |
3594 | - |
3595 | - * Native SSL support. |
3596 | - * Added support for HTTP range requests for attachments. |
3597 | - * Added built-in filters for `_changes`: `_doc_ids` and `_design`. |
3598 | - * Added configuration option for TCP_NODELAY aka "Nagle". |
3599 | - * Allow POSTing arguments to `_changes`. |
3600 | - * Allow `keys` parameter for GET requests to views. |
3601 | - * Allow wildcards in vhosts definitions. |
3602 | - * More granular ETag support for views. |
3603 | - * More flexible URL rewriter. |
3604 | - * Added support for recognizing "Q values" and media parameters in |
3605 | - HTTP Accept headers. |
3606 | - * Validate doc ids that come from a PUT to a URL. |
3607 | - |
3608 | -Externals: |
3609 | - |
3610 | - * Added OS Process module to manage daemons outside of CouchDB. |
3611 | - * Added HTTP Proxy handler for more scalable externals. |
3612 | - |
3613 | -Replicator: |
3614 | - |
3615 | - * Added `_replicator` database to manage replications. |
3616 | - * Fixed issues when an endpoint is a remote database accessible via SSL. |
3617 | - * Added support for continuous by-doc-IDs replication. |
3618 | - * Fix issue where revision info was omitted when replicating attachments. |
3619 | - * Integrity of attachment replication is now verified by MD5. |
3620 | - |
3621 | -Storage System: |
3622 | - |
3623 | - * Multiple micro-optimizations when reading data. |
3624 | - |
3625 | -View Server: |
3626 | - |
3627 | - * Added CommonJS support to map functions. |
3628 | - * Added `stale=update_after` query option that triggers a view update after |
3629 | - returning a `stale=ok` response. |
3630 | - * Warn about empty result caused by `startkey` and `endkey` limiting. |
3631 | - * Built-in reduce function `_sum` now accepts lists of integers as input. |
3632 | - * Added view query aliases start_key, end_key, start_key_doc_id and |
3633 | - end_key_doc_id. |
3634 | - |
3635 | -Futon: |
3636 | - |
3637 | - * Added a "change password"-feature to Futon. |
3638 | - |
3639 | -URL Rewriter & Vhosts: |
3640 | - |
3641 | - * Fix for variable substituion |
3642 | - |
3643 | -Version 1.0.3 |
3644 | -------------- |
3645 | - |
3646 | -General: |
3647 | - |
3648 | - * Fixed compatibility issues with Erlang R14B02. |
3649 | - |
3650 | -HTTP Interface: |
3651 | - |
3652 | - * Fix bug that allows invalid UTF-8 after valid escapes. |
3653 | - * The query parameter `include_docs` now honors the parameter `conflicts`. |
3654 | - This applies to queries against map views, _all_docs and _changes. |
3655 | - * Added support for inclusive_end with reduce views. |
3656 | - |
3657 | -Storage System: |
3658 | - |
3659 | - * More performant queries against _changes and _all_docs when using the |
3660 | - `include_docs` parameter. |
3661 | - |
3662 | -Replicator: |
3663 | - |
3664 | - * Enabled replication over IPv6. |
3665 | - * Fixed for crashes in continuous and filtered changes feeds. |
3666 | - * Fixed error when restarting replications in OTP R14B02. |
3667 | - * Upgrade ibrowse to version 2.2.0. |
3668 | - * Fixed bug when using a filter and a limit of 1. |
3669 | - |
3670 | -Security: |
3671 | - |
3672 | - * Fixed OAuth signature computation in OTP R14B02. |
3673 | - * Handle passwords with : in them. |
3674 | - |
3675 | -Futon: |
3676 | - |
3677 | - * Made compatible with jQuery 1.5.x. |
3678 | - |
3679 | -Etap Test Suite: |
3680 | - |
3681 | - * Etap tests no longer require use of port 5984. They now use a randomly |
3682 | - selected port so they won't clash with a running CouchDB. |
3683 | - |
3684 | -Windows: |
3685 | - |
3686 | - * Windows builds now require ICU >= 4.4.0 and Erlang >= R14B03. See |
3687 | - COUCHDB-1152, and COUCHDB-963 + OTP-9139 for more information. |
3688 | - |
3689 | -Version 1.0.2 |
3690 | -------------- |
3691 | - |
3692 | -Futon: |
3693 | - |
3694 | - * Make test suite work with Safari and Chrome. |
3695 | - * Fixed animated progress spinner. |
3696 | - * Fix raw view document link due to overzealous URI encoding. |
3697 | - * Spell javascript correctly in loadScript(uri). |
3698 | - |
3699 | -Storage System: |
3700 | - |
3701 | - * Fix leaking file handles after compacting databases and views. |
3702 | - * Fix databases forgetting their validation function after compaction. |
3703 | - * Fix occasional timeout errors after successfully compacting large databases. |
3704 | - * Fix ocassional error when writing to a database that has just been compacted. |
3705 | - * Fix occasional timeout errors on systems with slow or heavily loaded IO. |
3706 | - * Fix for OOME when compactions include documents with many conflicts. |
3707 | - * Fix for missing attachment compression when MIME types included parameters. |
3708 | - * Preserve purge metadata during compaction to avoid spurious view rebuilds. |
3709 | - * Fix spurious conflicts introduced when uploading an attachment after |
3710 | - a doc has been in a conflict. See COUCHDB-902 for details. |
3711 | - * Fix for frequently edited documents in multi-master deployments being |
3712 | - duplicated in _changes and _all_docs. See COUCHDDB-968 for details on how |
3713 | - to repair. |
3714 | - * Significantly higher read and write throughput against database and |
3715 | - view index files. |
3716 | - |
3717 | -Log System: |
3718 | - |
3719 | - * Reduce lengthy stack traces. |
3720 | - * Allow logging of native <xml> types. |
3721 | - |
3722 | -HTTP Interface: |
3723 | - |
3724 | - * Allow reduce=false parameter in map-only views. |
3725 | - * Fix parsing of Accept headers. |
3726 | - * Fix for multipart GET APIs when an attachment was created during a |
3727 | - local-local replication. See COUCHDB-1022 for details. |
3728 | - |
3729 | -Replicator: |
3730 | - |
3731 | - * Updated ibrowse library to 2.1.2 fixing numerous replication issues. |
3732 | - * Make sure that the replicator respects HTTP settings defined in the config. |
3733 | - * Fix error when the ibrowse connection closes unexpectedly. |
3734 | - * Fix authenticated replication (with HTTP basic auth) of design documents |
3735 | - with attachments. |
3736 | - * Various fixes to make replication more resilient for edge-cases. |
3737 | - |
3738 | -View Server: |
3739 | - |
3740 | - * Don't trigger view updates when requesting `_design/doc/_info`. |
3741 | - * Fix for circular references in CommonJS requires. |
3742 | - * Made isArray() function available to functions executed in the query server. |
3743 | - * Documents are now sealed before being passed to map functions. |
3744 | - * Force view compaction failure when duplicated document data exists. When |
3745 | - this error is seen in the logs users should rebuild their views from |
3746 | - scratch to fix the issue. See COUCHDB-999 for details. |
3747 | - |
3748 | -Version 1.0.1 |
3749 | -------------- |
3750 | - |
3751 | -Storage System: |
3752 | - |
3753 | - * Fix data corruption bug COUCHDB-844. Please see |
3754 | - http://couchdb.apache.org/notice/1.0.1.html for details. |
3755 | - |
3756 | -Replicator: |
3757 | - |
3758 | - * Added support for replication via an HTTP/HTTPS proxy. |
3759 | - * Fix pull replication of attachments from 0.11 to 1.0.x. |
3760 | - * Make the _changes feed work with non-integer seqnums. |
3761 | - |
3762 | -HTTP Interface: |
3763 | - |
3764 | - * Expose `committed_update_seq` for monitoring purposes. |
3765 | - * Show fields saved along with _deleted=true. Allows for auditing of deletes. |
3766 | - * More robust Accept-header detection. |
3767 | - |
3768 | -Authentication: |
3769 | - |
3770 | - * Enable basic-auth popup when required to access the server, to prevent |
3771 | - people from getting locked out. |
3772 | - |
3773 | -Futon: |
3774 | - |
3775 | - * User interface element for querying stale (cached) views. |
3776 | - |
3777 | -Build and System Integration: |
3778 | - |
3779 | - * Included additional source files for distribution. |
3780 | - |
3781 | -Version 1.0.0 |
3782 | -------------- |
3783 | - |
3784 | -Security: |
3785 | - |
3786 | - * Added authentication caching, to avoid repeated opening and closing of the |
3787 | - users database for each request requiring authentication. |
3788 | - |
3789 | -Storage System: |
3790 | - |
3791 | - * Small optimization for reordering result lists. |
3792 | - * More efficient header commits. |
3793 | - * Use O_APPEND to save lseeks. |
3794 | - * Faster implementation of pread_iolist(). Further improves performance on |
3795 | - concurrent reads. |
3796 | - |
3797 | -View Server: |
3798 | - |
3799 | - * Faster default view collation. |
3800 | - * Added option to include update_seq in view responses. |
3801 | - |
3802 | -Version 0.11.2 |
3803 | --------------- |
3804 | - |
3805 | -Replicator: |
3806 | - |
3807 | - * Fix bug when pushing design docs by non-admins, which was hanging the |
3808 | - replicator for no good reason. |
3809 | - * Fix bug when pulling design documents from a source that requires |
3810 | - basic-auth. |
3811 | - |
3812 | -HTTP Interface: |
3813 | - |
3814 | - * Better error messages on invalid URL requests. |
3815 | - |
3816 | -Authentication: |
3817 | - |
3818 | - * User documents can now be deleted by admins or the user. |
3819 | - |
3820 | -Security: |
3821 | - |
3822 | - * Avoid potential DOS attack by guarding all creation of atoms. |
3823 | - |
3824 | -Futon: |
3825 | - |
3826 | - * Add some Futon files that were missing from the Makefile. |
3827 | - |
3828 | -Version 0.11.1 |
3829 | --------------- |
3830 | - |
3831 | -HTTP Interface: |
3832 | - |
3833 | - * Mask passwords in active tasks and logging. |
3834 | - * Update mochijson2 to allow output of BigNums not in float form. |
3835 | - * Added support for X-HTTP-METHOD-OVERRIDE. |
3836 | - * Better error message for database names. |
3837 | - * Disable jsonp by default. |
3838 | - * Accept gzip encoded standalone attachments. |
3839 | - * Made max_concurrent_connections configurable. |
3840 | - * Made changes API more robust. |
3841 | - * Send newly generated document rev to callers of an update function. |
3842 | - |
3843 | -Futon: |
3844 | - |
3845 | - * Use "expando links" for over-long document values in Futon. |
3846 | - * Added continuous replication option. |
3847 | - * Added option to replicating test results anonymously to a community |
3848 | - CouchDB instance. |
3849 | - * Allow creation and deletion of config entries. |
3850 | - * Fixed display issues with doc ids that have escaped characters. |
3851 | - * Fixed various UI issues. |
3852 | - |
3853 | -Build and System Integration: |
3854 | - |
3855 | - * Output of `couchdb --help` has been improved. |
3856 | - * Fixed compatibility with the Erlang R14 series. |
3857 | - * Fixed warnings on Linux builds. |
3858 | - * Fixed build error when aclocal needs to be called during the build. |
3859 | - * Require ICU 4.3.1. |
3860 | - * Fixed compatibility with Solaris. |
3861 | - |
3862 | -Security: |
3863 | - |
3864 | - * Added authentication redirect URL to log in clients. |
3865 | - * Fixed query parameter encoding issue in oauth.js. |
3866 | - * Made authentication timeout configurable. |
3867 | - * Temporary views are now admin-only resources. |
3868 | - |
3869 | -Storage System: |
3870 | - |
3871 | - * Don't require a revpos for attachment stubs. |
3872 | - * Added checking to ensure when a revpos is sent with an attachment stub, |
3873 | - it's correct. |
3874 | - * Make file deletions async to avoid pauses during compaction and db |
3875 | - deletion. |
3876 | - * Fixed for wrong offset when writing headers and converting them to blocks, |
3877 | - only triggered when header is larger than 4k. |
3878 | - * Preserve _revs_limit and instance_start_time after compaction. |
3879 | - |
3880 | -Configuration System: |
3881 | - |
3882 | - * Fixed timeout with large .ini files. |
3883 | - |
3884 | -JavaScript Clients: |
3885 | - |
3886 | - * Added tests for couch.js and jquery.couch.js |
3887 | - * Added changes handler to jquery.couch.js. |
3888 | - * Added cache busting to jquery.couch.js if the user agent is msie. |
3889 | - * Added support for multi-document-fetch (via _all_docs) to jquery.couch.js. |
3890 | - * Added attachment versioning to jquery.couch.js. |
3891 | - * Added option to control ensure_full_commit to jquery.couch.js. |
3892 | - * Added list functionality to jquery.couch.js. |
3893 | - * Fixed issues where bulkSave() wasn't sending a POST body. |
3894 | - |
3895 | -View Server: |
3896 | - |
3897 | - * Provide a UUID to update functions (and all other functions) that they can |
3898 | - use to create new docs. |
3899 | - * Upgrade CommonJS modules support to 1.1.1. |
3900 | - * Fixed erlang filter funs and normalize filter fun API. |
3901 | - * Fixed hang in view shutdown. |
3902 | - |
3903 | -Log System: |
3904 | - |
3905 | - * Log HEAD requests as HEAD, not GET. |
3906 | - * Keep massive JSON blobs out of the error log. |
3907 | - * Fixed a timeout issue. |
3908 | - |
3909 | -Replication System: |
3910 | - |
3911 | - * Refactored various internal APIs related to attachment streaming. |
3912 | - * Fixed hanging replication. |
3913 | - * Fixed keepalive issue. |
3914 | - |
3915 | -URL Rewriter & Vhosts: |
3916 | - |
3917 | - * Allow more complex keys in rewriter. |
3918 | - * Allow global rewrites so system defaults are available in vhosts. |
3919 | - * Allow isolation of databases with vhosts. |
3920 | - * Fix issue with passing variables to query parameters. |
3921 | - |
3922 | -Test Suite: |
3923 | - |
3924 | - * Made the test suite overall more reliable. |
3925 | - |
3926 | -Version 0.11.0 |
3927 | --------------- |
3928 | - |
3929 | -Security: |
3930 | - |
3931 | - * Fixed CVE-2010-0009: Apache CouchDB Timing Attack Vulnerability. |
3932 | - * Added default cookie-authentication and users database. |
3933 | - * Added Futon user interface for user signup and login. |
3934 | - * Added per-database reader access control lists. |
3935 | - * Added per-database security object for configuration data in validation |
3936 | - functions. |
3937 | - * Added proxy authentication handler |
3938 | - |
3939 | -HTTP Interface: |
3940 | - |
3941 | - * Provide Content-MD5 header support for attachments. |
3942 | - * Added URL Rewriter handler. |
3943 | - * Added virtual host handling. |
3944 | - |
3945 | -View Server: |
3946 | - |
3947 | - * Added optional 'raw' binary collation for faster view builds where Unicode |
3948 | - collation is not important. |
3949 | - * Improved view index build time by reducing ICU collation callouts. |
3950 | - * Improved view information objects. |
3951 | - * Bug fix for partial updates during view builds. |
3952 | - * Move query server to a design-doc based protocol. |
3953 | - * Use json2.js for JSON serialization for compatiblity with native JSON. |
3954 | - * Major refactoring of couchjs to lay the groundwork for disabling cURL |
3955 | - support. The new HTTP interaction acts like a synchronous XHR. Example usage |
3956 | - of the new system is in the JavaScript CLI test runner. |
3957 | - |
3958 | -Replication: |
3959 | - |
3960 | - * Added option to implicitly create replication target databases. |
3961 | - * Avoid leaking file descriptors on automatic replication restarts. |
3962 | - * Added option to replicate a list of documents by id. |
3963 | - * Allow continuous replication to be cancelled. |
3964 | - |
3965 | -Storage System: |
3966 | - |
3967 | - * Adds batching of multiple updating requests, to improve throughput with many |
3968 | - writers. Removed the now redundant couch_batch_save module. |
3969 | - * Adds configurable compression of attachments. |
3970 | - |
3971 | -Runtime Statistics: |
3972 | - |
3973 | - * Statistics are now calculated for a moving window instead of non-overlapping |
3974 | - timeframes. |
3975 | - * Fixed a problem with statistics timers and system sleep. |
3976 | - * Moved statistic names to a term file in the priv directory. |
3977 | - |
3978 | -Futon: |
3979 | - |
3980 | - * Added a button for view compaction. |
3981 | - * JSON strings are now displayed as-is in the document view, without the escaping of |
3982 | - new-lines and quotes. That dramatically improves readability of multi-line |
3983 | - strings. |
3984 | - * Same goes for editing of JSON string values. When a change to a field value is |
3985 | - submitted, and the value is not valid JSON it is assumed to be a string. This |
3986 | - improves editing of multi-line strings a lot. |
3987 | - * Hitting tab in textareas no longer moves focus to the next form field, but simply |
3988 | - inserts a tab character at the current caret position. |
3989 | - * Fixed some font declarations. |
3990 | - |
3991 | -Build and System Integration: |
3992 | - |
3993 | - * Updated and improved source documentation. |
3994 | - * Fixed distribution preparation for building on Mac OS X. |
3995 | - * Added support for building a Windows installer as part of 'make dist'. |
3996 | - * Bug fix for building couch.app's module list. |
3997 | - * ETap tests are now run during make distcheck. This included a number of |
3998 | - updates to the build system to properly support VPATH builds. |
3999 | - * Gavin McDonald setup a build-bot instance. More info can be found at |
4000 | - http://ci.apache.org/buildbot.html |
4001 | - |
4002 | -Version 0.10.1 |
4003 | --------------- |
4004 | - |
4005 | -Replicator: |
4006 | - |
4007 | - * Stability enhancements regarding redirects, timeouts, OAuth. |
4008 | - |
4009 | -Query Server: |
4010 | - |
4011 | - * Avoid process leaks |
4012 | - * Allow list and view to span languages |
4013 | - |
4014 | -Stats: |
4015 | - |
4016 | - * Eliminate new process flood on system wake |
4017 | - |
4018 | -Build and System Integration: |
4019 | - |
4020 | - * Test suite now works with the distcheck target. |
4021 | - |
4022 | -Version 0.10.0 |
4023 | --------------- |
4024 | - |
4025 | -Storage Format: |
4026 | - |
4027 | - * Add move headers with checksums to the end of database files for extra robust |
4028 | - storage and faster storage. |
4029 | - |
4030 | -View Server: |
4031 | - |
4032 | - * Added native Erlang views for high-performance applications. |
4033 | - |
4034 | -HTTP Interface: |
4035 | - |
4036 | - * Added optional cookie-based authentication handler. |
4037 | - * Added optional two-legged OAuth authentication handler. |
4038 | - |
4039 | -Build and System Integration: |
4040 | - |
4041 | - * Changed `couchdb` script configuration options. |
4042 | - * Added default.d and local.d configuration directories to load sequence. |
4043 | - |
4044 | - |
4045 | -Version 0.9.2 |
4046 | -------------- |
4047 | - |
4048 | -Replication: |
4049 | - |
4050 | - * Fix replication with 0.10 servers initiated by an 0.9 server (COUCHDB-559). |
4051 | - |
4052 | -Build and System Integration: |
4053 | - |
4054 | - * Remove branch callbacks to allow building couchjs against newer versions of |
4055 | - Spidermonkey. |
4056 | - |
4057 | -Version 0.9.1 |
4058 | -------------- |
4059 | - |
4060 | -Build and System Integration: |
4061 | - |
4062 | - * PID file directory is now created by the SysV/BSD daemon scripts. |
4063 | - * Fixed the environment variables shown by the configure script. |
4064 | - * Fixed the build instructions shown by the configure script. |
4065 | - * Updated ownership and permission advice in `README` for better security. |
4066 | - |
4067 | -Configuration and stats system: |
4068 | - |
4069 | - * Corrected missing configuration file error message. |
4070 | - * Fixed incorrect recording of request time. |
4071 | - |
4072 | -Database Core: |
4073 | - |
4074 | - * Document validation for underscore prefixed variables. |
4075 | - * Made attachment storage less sparse. |
4076 | - * Fixed problems when a database with delayed commits pending is considered |
4077 | - idle, and subject to losing changes when shutdown. (COUCHDB-334) |
4078 | - |
4079 | -External Handlers: |
4080 | - |
4081 | - * Fix POST requests. |
4082 | - |
4083 | -Futon: |
4084 | - |
4085 | - * Redirect when loading a deleted view URI from the cookie. |
4086 | - |
4087 | -HTTP Interface: |
4088 | - |
4089 | - * Attachment requests respect the "rev" query-string parameter. |
4090 | - |
4091 | -JavaScript View Server: |
4092 | - |
4093 | - * Useful JavaScript Error messages. |
4094 | - |
4095 | -Replication: |
4096 | - |
4097 | - * Added support for Unicode characters transmitted as UTF-16 surrogate pairs. |
4098 | - * URL-encode attachment names when necessary. |
4099 | - * Pull specific revisions of an attachment, instead of just the latest one. |
4100 | - * Work around a rare chunk-merging problem in ibrowse. |
4101 | - * Work with documents containing Unicode characters outside the Basic |
4102 | - Multilingual Plane. |
4103 | - |
4104 | -Version 0.9.0 |
4105 | -------------- |
4106 | - |
4107 | -Futon Utility Client: |
4108 | - |
4109 | - * Added pagination to the database listing page. |
4110 | - * Implemented attachment uploading from the document page. |
4111 | - * Added page that shows the current configuration, and allows modification of |
4112 | - option values. |
4113 | - * Added a JSON "source view" for document display. |
4114 | - * JSON data in view rows is now syntax highlighted. |
4115 | - * Removed the use of an iframe for better integration with browser history and |
4116 | - bookmarking. |
4117 | - * Full database listing in the sidebar has been replaced by a short list of |
4118 | - recent databases. |
4119 | - * The view editor now allows selection of the view language if there is more |
4120 | - than one configured. |
4121 | - * Added links to go to the raw view or document URI. |
4122 | - * Added status page to display currently running tasks in CouchDB. |
4123 | - * JavaScript test suite split into multiple files. |
4124 | - * Pagination for reduce views. |
4125 | - |
4126 | -Design Document Resource Paths: |
4127 | - |
4128 | - * Added httpd_design_handlers config section. |
4129 | - * Moved _view to httpd_design_handlers. |
4130 | - * Added ability to render documents as non-JSON content-types with _show and |
4131 | - _list functions, which are also httpd_design_handlers. |
4132 | - |
4133 | -HTTP Interface: |
4134 | - |
4135 | - * Added client side UUIDs for idempotent document creation |
4136 | - * HTTP COPY for documents |
4137 | - * Streaming of chunked attachment PUTs to disk |
4138 | - * Remove negative count feature |
4139 | - * Add include_docs option for view queries |
4140 | - * Add multi-key view post for views |
4141 | - * Query parameter validation |
4142 | - * Use stale=ok to request potentially cached view index |
4143 | - * External query handler module for full-text or other indexers. |
4144 | - * Etags for attachments, views, shows and lists |
4145 | - * Show and list functions for rendering documents and views as developer |
4146 | - controlled content-types. |
4147 | - * Attachment names may use slashes to allow uploading of nested directories |
4148 | - (useful for static web hosting). |
4149 | - * Option for a view to run over design documents. |
4150 | - * Added newline to JSON responses. Closes bike-shed. |
4151 | - |
4152 | -Replication: |
4153 | - |
4154 | - * Using ibrowse. |
4155 | - * Checkpoint replications so failures are less expensive. |
4156 | - * Automatically retry of failed replications. |
4157 | - * Stream attachments in pull-replication. |
4158 | - |
4159 | -Database Core: |
4160 | - |
4161 | - * Faster B-tree implementation. |
4162 | - * Changed internal JSON term format. |
4163 | - * Improvements to Erlang VM interactions under heavy load. |
4164 | - * User context and administrator role. |
4165 | - * Update validations with design document validation functions. |
4166 | - * Document purge functionality. |
4167 | - * Ref-counting for database file handles. |
4168 | - |
4169 | -Build and System Integration: |
4170 | - |
4171 | - * The `couchdb` script now supports system chainable configuration files. |
4172 | - * The Mac OS X daemon script now redirects STDOUT and STDERR like SysV/BSD. |
4173 | - * The build and system integration have been improved for portability. |
4174 | - * Added COUCHDB_OPTIONS to etc/default/couchdb file. |
4175 | - * Remove COUCHDB_INI_FILE and COUCHDB_PID_FILE from etc/default/couchdb file. |
4176 | - * Updated `configure.ac` to manually link `libm` for portability. |
4177 | - * Updated `configure.ac` to extended default library paths. |
4178 | - * Removed inets configuration files. |
4179 | - * Added command line test runner. |
4180 | - * Created dev target for make. |
4181 | - |
4182 | -Configuration and stats system: |
4183 | - |
4184 | - * Separate default and local configuration files. |
4185 | - * HTTP interface for configuration changes. |
4186 | - * Statistics framework with HTTP query API. |
4187 | - |
4188 | -Version 0.8.1-incubating |
4189 | ------------------------- |
4190 | - |
4191 | -Database Core: |
4192 | - |
4193 | - * Fix for replication problems where the write queues can get backed up if the |
4194 | - writes aren't happening fast enough to keep up with the reads. For a large |
4195 | - replication, this can exhaust memory and crash, or slow down the machine |
4196 | - dramatically. The fix keeps only one document in the write queue at a time. |
4197 | - * Fix for databases sometimes incorrectly reporting that they contain 0 |
4198 | - documents after compaction. |
4199 | - * CouchDB now uses ibrowse instead of inets for its internal HTTP client |
4200 | - implementation. This means better replication stability. |
4201 | - |
4202 | -HTTP Interface: |
4203 | - |
4204 | - * Fix for chunked responses where chunks were always being split into multiple |
4205 | - TCP packets, which caused problems with the test suite under Safari, and in |
4206 | - some other cases. |
4207 | - * Fix for an invalid JSON response body being returned for some kinds of |
4208 | - views. (COUCHDB-84) |
4209 | - * Fix for connections not getting closed after rejecting a chunked request. |
4210 | - (COUCHDB-55) |
4211 | - * CouchDB can now be bound to IPv6 addresses. |
4212 | - * The HTTP `Server` header now contains the versions of CouchDB and Erlang. |
4213 | - |
4214 | -JavaScript View Server: |
4215 | - |
4216 | - * Sealing of documents has been disabled due to an incompatibility with |
4217 | - SpiderMonkey 1.9. |
4218 | - * Improve error handling for undefined values emitted by map functions. |
4219 | - (COUCHDB-83) |
4220 | - |
4221 | -Build and System Integration: |
4222 | - |
4223 | - * The `couchdb` script no longer uses `awk` for configuration checks as this |
4224 | - was causing portability problems. |
4225 | - * Updated `sudo` example in `README` to use the `-i` option, this fixes |
4226 | - problems when invoking from a directory the `couchdb` user cannot access. |
4227 | - |
4228 | -Futon: |
4229 | - |
4230 | - * The view selector dropdown should now work in Opera and Internet Explorer |
4231 | - even when it includes optgroups for design documents. (COUCHDB-81) |
4232 | - |
4233 | -Version 0.8.0-incubating |
4234 | ------------------------- |
4235 | - |
4236 | -Database Core: |
4237 | - |
4238 | - * The view engine has been completely decoupled from the storage engine. Index |
4239 | - data is now stored in separate files, and the format of the main database |
4240 | - file has changed. |
4241 | - * Databases can now be compacted to reclaim space used for deleted documents |
4242 | - and old document revisions. |
4243 | - * Support for incremental map/reduce views has been added. |
4244 | - * To support map/reduce, the structure of design documents has changed. View |
4245 | - values are now JSON objects containing at least a `map` member, and |
4246 | - optionally a `reduce` member. |
4247 | - * View servers are now identified by name (for example `javascript`) instead of |
4248 | - by media type. |
4249 | - * Automatically generated document IDs are now based on proper UUID generation |
4250 | - using the crypto module. |
4251 | - * The field `content-type` in the JSON representation of attachments has been |
4252 | - renamed to `content_type` (underscore). |
4253 | - |
4254 | -HTTP Interface: |
4255 | - |
4256 | - * CouchDB now uses MochiWeb instead of inets for the HTTP server |
4257 | - implementation. Among other things, this means that the extra configuration |
4258 | - files needed for inets (such as `couch_httpd.conf`) are no longer used. |
4259 | - * The HTTP interface now completely supports the `HEAD` method. (COUCHDB-3) |
4260 | - * Improved compliance of `Etag` handling with the HTTP specification. |
4261 | - (COUCHDB-13) |
4262 | - * Etags are no longer included in responses to document `GET` requests that |
4263 | - include query string parameters causing the JSON response to change without |
4264 | - the revision or the URI having changed. |
4265 | - * The bulk document update API has changed slightly on both the request and the |
4266 | - response side. In addition, bulk updates are now atomic. |
4267 | - * CouchDB now uses `TCP_NODELAY` to fix performance problems with persistent |
4268 | - connections on some platforms due to nagling. |
4269 | - * Including a `?descending=false` query string parameter in requests to views |
4270 | - no longer raises an error. |
4271 | - * Requests to unknown top-level reserved URLs (anything with a leading |
4272 | - underscore) now return a `unknown_private_path` error instead of the |
4273 | - confusing `illegal_database_name`. |
4274 | - * The Temporary view handling now expects a JSON request body, where the JSON |
4275 | - is an object with at least a `map` member, and optional `reduce` and |
4276 | - `language` members. |
4277 | - * Temporary views no longer determine the view server based on the Content-Type |
4278 | - header of the `POST` request, but rather by looking for a `language` member |
4279 | - in the JSON body of the request. |
4280 | - * The status code of responses to `DELETE` requests is now 200 to reflect that |
4281 | - that the deletion is performed synchronously. |
4282 | - |
4283 | -JavaScript View Server: |
4284 | - |
4285 | - * SpiderMonkey is no longer included with CouchDB, but rather treated as a |
4286 | - normal external dependency. A simple C program (`_couchjs`) is provided that |
4287 | - links against an existing SpiderMonkey installation and uses the interpreter |
4288 | - embedding API. |
4289 | - * View functions using the default JavaScript view server can now do logging |
4290 | - using the global `log(message)` function. Log messages are directed into the |
4291 | - CouchDB log at `INFO` level. (COUCHDB-59) |
4292 | - * The global `map(key, value)` function made available to view code has been |
4293 | - renamed to `emit(key, value)`. |
4294 | - * Fixed handling of exceptions raised by view functions. |
4295 | - |
4296 | -Build and System Integration: |
4297 | - |
4298 | - * CouchDB can automatically respawn following a server crash. |
4299 | - * Database server no longer refuses to start with a stale PID file. |
4300 | - * System logrotate configuration provided. |
4301 | - * Improved handling of ICU shared libraries. |
4302 | - * The `couchdb` script now automatically enables SMP support in Erlang. |
4303 | - * The `couchdb` and `couchjs` scripts have been improved for portability. |
4304 | - * The build and system integration have been improved for portability. |
4305 | - |
4306 | -Futon: |
4307 | - |
4308 | - * When adding a field to a document, Futon now just adds a field with an |
4309 | - autogenerated name instead of prompting for the name with a dialog. The name |
4310 | - is automatically put into edit mode so that it can be changed immediately. |
4311 | - * Fields are now sorted alphabetically by name when a document is displayed. |
4312 | - * Futon can be used to create and update permanent views. |
4313 | - * The maximum number of rows to display per page on the database page can now |
4314 | - be adjusted. |
4315 | - * Futon now uses the XMLHTTPRequest API asynchronously to communicate with the |
4316 | - CouchDB HTTP server, so that most operations no longer block the browser. |
4317 | - * View results sorting can now be switched between ascending and descending by |
4318 | - clicking on the `Key` column header. |
4319 | - * Fixed a bug where documents that contained a `@` character could not be |
4320 | - viewed. (COUCHDB-12) |
4321 | - * The database page now provides a `Compact` button to trigger database |
4322 | - compaction. (COUCHDB-38) |
4323 | - * Fixed portential double encoding of document IDs and other URI segments in |
4324 | - many instances. (COUCHDB-39) |
4325 | - * Improved display of attachments. |
4326 | - * The JavaScript Shell has been removed due to unresolved licensing issues. |
4327 | |
4328 | === modified file 'DEVELOPERS' |
4329 | --- DEVELOPERS 2010-07-26 10:24:11 +0000 |
4330 | +++ DEVELOPERS 2013-08-30 22:06:57 +0000 |
4331 | @@ -1,6 +1,10 @@ |
4332 | Apache CouchDB DEVELOPERS |
4333 | ========================= |
4334 | |
4335 | +Before you start here, read `INSTALL.Unix` (or `INSTALL.Windows`) and |
4336 | +follow the setup instructions including the installation of all the |
4337 | +listed dependencies for your system. |
4338 | + |
4339 | Only follow these instructions if you are building from a source checkout. |
4340 | |
4341 | If you're unsure what this means, ignore this document. |
4342 | @@ -10,30 +14,109 @@ |
4343 | |
4344 | You will need the following installed: |
4345 | |
4346 | + * GNU Libtool (http://www.gnu.org/software/libtool/) |
4347 | * GNU Automake (>=1.6.3) (http://www.gnu.org/software/automake/) |
4348 | - * GNU Autoconf (>=2.59) (http://www.gnu.org/software/autoconf/) |
4349 | - * GNU Libtool (http://www.gnu.org/software/libtool/) |
4350 | + * GNU Autoconf (>=2.63) (http://www.gnu.org/software/autoconf/) |
4351 | + * GNU Autoconf Archive (http://www.gnu.org/software/autoconf-archive/) |
4352 | + * pkg-config (http://www.freedesktop.org/wiki/Software/pkg-config) |
4353 | + |
4354 | +You may also need: |
4355 | + |
4356 | + * Sphinx (http://sphinx.pocoo.org/) |
4357 | + * LaTex (http://www.latex-project.org/) |
4358 | + * GNU Texinfo (http://www.gnu.org/software/texinfo/) |
4359 | * GNU help2man (http://www.gnu.org/software/help2man/) |
4360 | - |
4361 | -The `help2man` tool is optional, but will generate `man` pages for you. |
4362 | + * GnuPG (http://www.gnupg.org/) |
4363 | + * md5sum (http://www.microbrew.org/tools/md5sha1sum/) |
4364 | + * sha1sum (http://www.microbrew.org/tools/md5sha1sum/) |
4365 | + |
4366 | +The first of these optional dependencies are required for building the |
4367 | +documentation. The last three are needed to build releases. |
4368 | + |
4369 | +You will need these optional dependencies installed if: |
4370 | + |
4371 | + * You are working on the documentation, or |
4372 | + * You are preparing a distribution archive |
4373 | + |
4374 | +However, you do not need them if: |
4375 | + |
4376 | + * You are building from a distribution archive, or |
4377 | + * You don't care about building the documentation |
4378 | + |
4379 | + |
4380 | +Here is a list of *optional* dependencies for various operating systems. |
4381 | +Installation will be easiest, when you install them all. |
4382 | |
4383 | Debian-based (inc. Ubuntu) Systems |
4384 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4385 | |
4386 | -You can install the dependencies by running: |
4387 | - |
4388 | - apt-get install automake autoconf libtool help2man |
4389 | - |
4390 | -Be sure to update the version numbers to match your system's available packages. |
4391 | + sudo apt-get install help2man |
4392 | + sudo apt-get install python-sphinx |
4393 | + sudo apt-get install texlive-latex-base |
4394 | + sudo apt-get install texlive-latex-recommended |
4395 | + sudo apt-get install texlive-latex-extra |
4396 | + sudo apt-get install texlive-fonts-recommended |
4397 | + sudo apt-get install texinfo |
4398 | + sudo apt-get install gnupg |
4399 | + |
4400 | +Gentoo-based Systems |
4401 | +~~~~~~~~~~~~~~~~~~~~ |
4402 | + |
4403 | + sudo emerge texinfo |
4404 | + sudo emerge gnupg |
4405 | + sudo emerge coreutils |
4406 | + sudo emerge pkgconfig |
4407 | + sudo emerge help2man |
4408 | + sudo USE=latex emerge sphinx |
4409 | + |
4410 | +RedHat-based (Fedora, Centos, RHEL) Systems |
4411 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4412 | + |
4413 | + sudo yum install help2man |
4414 | + sudo yum install python-sphinx |
4415 | + sudo yum install python-docutils |
4416 | + sudo yum install python-pygments |
4417 | + sudo yum install texlive-latex |
4418 | + sudo yum install texlive-latex-fonts |
4419 | + sudo yum install texinfo |
4420 | + sudo yum install gnupg |
4421 | |
4422 | Mac OS X |
4423 | ~~~~~~~~ |
4424 | |
4425 | -You can install the dependencies by running: |
4426 | - |
4427 | - port install automake autoconf libtool help2man |
4428 | - |
4429 | -You will need MacPorts installed to use the `port` command. |
4430 | +Install Homebrew, if you do not have it already: |
4431 | + |
4432 | + https://github.com/mxcl/homebrew |
4433 | + |
4434 | +Unless you want to install the optional dependencies, skip to the next section. |
4435 | + |
4436 | +Install what else we can with Homebrew: |
4437 | + |
4438 | + brew install help2man |
4439 | + brew install gnupg |
4440 | + brew install md5sha1sum |
4441 | + |
4442 | +If you don't already have pip installed, install it: |
4443 | + |
4444 | + sudo easy_install pip |
4445 | + |
4446 | +Now, install the required Python packages: |
4447 | + |
4448 | + sudo pip install sphinx |
4449 | + sudo pip install docutils |
4450 | + sudo pip install pygments |
4451 | + |
4452 | +Download MaxTeX from here: |
4453 | + |
4454 | + http://www.tug.org/mactex/ |
4455 | + |
4456 | +Follow the instructions to get a working LaTeX install on your system. |
4457 | + |
4458 | +Windows |
4459 | +~~~~~~~ |
4460 | + |
4461 | +Follow the instructions in INSTALL.Windows and build all components from |
4462 | +source, using the same Visual C++ compiler and runtime. |
4463 | |
4464 | Bootstrapping |
4465 | ------------- |
4466 | @@ -44,6 +127,33 @@ |
4467 | |
4468 | You must repeat this step every time you update your source checkout. |
4469 | |
4470 | +Configuring |
4471 | +----------- |
4472 | + |
4473 | +Configure the source by running: |
4474 | + |
4475 | + ./configure |
4476 | + |
4477 | +Note that this will not fail when the optional dependencies are missing. |
4478 | + |
4479 | +To ensure the optional dependencies are installed, run: |
4480 | + |
4481 | + ./configure --enable-strictness |
4482 | + |
4483 | +If you don't care about docs and want to skip the whole thing, run: |
4484 | + |
4485 | + ./configure --disable-docs |
4486 | + |
4487 | +If you're working on the build system itself, you can run: |
4488 | + |
4489 | + ./configure --disable-tests |
4490 | + |
4491 | +This skips the tests allowing quicker `make' cycles. |
4492 | + |
4493 | +If you want to build it into different destination than `/usr/local`. |
4494 | + |
4495 | + ./configure --prefix=/<your directory path> |
4496 | + |
4497 | Testing |
4498 | ------- |
4499 | |
4500 | @@ -60,13 +170,13 @@ |
4501 | Releasing |
4502 | --------- |
4503 | |
4504 | +The release procedure is documented here: |
4505 | + |
4506 | + https://wiki.apache.org/couchdb/Release_Procedure |
4507 | + |
4508 | Unix-like Systems |
4509 | ~~~~~~~~~~~~~~~~~ |
4510 | |
4511 | -Configure the source by running: |
4512 | - |
4513 | - ./configure |
4514 | - |
4515 | Prepare the release artefacts by running: |
4516 | |
4517 | make distcheck |
4518 | @@ -80,10 +190,6 @@ |
4519 | Microsoft Windows |
4520 | ~~~~~~~~~~~~~~~~~ |
4521 | |
4522 | -Configure the source by running: |
4523 | - |
4524 | - ./configure |
4525 | - |
4526 | Prepare the release artefacts by running: |
4527 | |
4528 | make dist |
4529 | |
4530 | === modified file 'INSTALL' |
4531 | --- INSTALL 2012-07-30 22:49:54 +0000 |
4532 | +++ INSTALL 2013-08-30 22:06:57 +0000 |
4533 | @@ -1,19 +1,25 @@ |
4534 | Installation Instructions |
4535 | ************************* |
4536 | |
4537 | -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, |
4538 | -2006 Free Software Foundation, Inc. |
4539 | +Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, |
4540 | +Inc. |
4541 | |
4542 | -This file is free documentation; the Free Software Foundation gives |
4543 | -unlimited permission to copy, distribute and modify it. |
4544 | + Copying and distribution of this file, with or without modification, |
4545 | +are permitted in any medium without royalty provided the copyright |
4546 | +notice and this notice are preserved. This file is offered as-is, |
4547 | +without warranty of any kind. |
4548 | |
4549 | Basic Installation |
4550 | ================== |
4551 | |
4552 | -Briefly, the shell commands `./configure; make; make install' should |
4553 | + Briefly, the shell commands `./configure; make; make install' should |
4554 | configure, build, and install this package. The following |
4555 | more-detailed instructions are generic; see the `README' file for |
4556 | -instructions specific to this package. |
4557 | +instructions specific to this package. Some packages provide this |
4558 | +`INSTALL' file but do not implement all of the features documented |
4559 | +below. The lack of an optional feature in a given package is not |
4560 | +necessarily a bug. More recommendations for GNU packages can be found |
4561 | +in *note Makefile Conventions: (standards)Makefile Conventions. |
4562 | |
4563 | The `configure' shell script attempts to guess correct values for |
4564 | various system-dependent variables used during compilation. It uses |
4565 | @@ -42,7 +48,7 @@ |
4566 | you want to change it or regenerate `configure' using a newer version |
4567 | of `autoconf'. |
4568 | |
4569 | -The simplest way to compile this package is: |
4570 | + The simplest way to compile this package is: |
4571 | |
4572 | 1. `cd' to the directory containing the package's source code and type |
4573 | `./configure' to configure the package for your system. |
4574 | @@ -53,12 +59,22 @@ |
4575 | 2. Type `make' to compile the package. |
4576 | |
4577 | 3. Optionally, type `make check' to run any self-tests that come with |
4578 | - the package. |
4579 | + the package, generally using the just-built uninstalled binaries. |
4580 | |
4581 | 4. Type `make install' to install the programs and any data files and |
4582 | - documentation. |
4583 | - |
4584 | - 5. You can remove the program binaries and object files from the |
4585 | + documentation. When installing into a prefix owned by root, it is |
4586 | + recommended that the package be configured and built as a regular |
4587 | + user, and only the `make install' phase executed with root |
4588 | + privileges. |
4589 | + |
4590 | + 5. Optionally, type `make installcheck' to repeat any self-tests, but |
4591 | + this time using the binaries in their final installed location. |
4592 | + This target does not install anything. Running this target as a |
4593 | + regular user, particularly if the prior `make install' required |
4594 | + root privileges, verifies that the installation completed |
4595 | + correctly. |
4596 | + |
4597 | + 6. You can remove the program binaries and object files from the |
4598 | source code directory by typing `make clean'. To also remove the |
4599 | files that `configure' created (so you can compile the package for |
4600 | a different kind of computer), type `make distclean'. There is |
4601 | @@ -67,12 +83,22 @@ |
4602 | all sorts of other programs in order to regenerate files that came |
4603 | with the distribution. |
4604 | |
4605 | + 7. Often, you can also type `make uninstall' to remove the installed |
4606 | + files again. In practice, not all packages have tested that |
4607 | + uninstallation works correctly, even though it is required by the |
4608 | + GNU Coding Standards. |
4609 | + |
4610 | + 8. Some packages, particularly those that use Automake, provide `make |
4611 | + distcheck', which can by used by developers to test that all other |
4612 | + targets like `make install' and `make uninstall' work correctly. |
4613 | + This target is generally not run by end users. |
4614 | + |
4615 | Compilers and Options |
4616 | ===================== |
4617 | |
4618 | -Some systems require unusual options for compilation or linking that the |
4619 | -`configure' script does not know about. Run `./configure --help' for |
4620 | -details on some of the pertinent environment variables. |
4621 | + Some systems require unusual options for compilation or linking that |
4622 | +the `configure' script does not know about. Run `./configure --help' |
4623 | +for details on some of the pertinent environment variables. |
4624 | |
4625 | You can give `configure' initial values for configuration parameters |
4626 | by setting variables in the command line or in the environment. Here |
4627 | @@ -85,25 +111,41 @@ |
4628 | Compiling For Multiple Architectures |
4629 | ==================================== |
4630 | |
4631 | -You can compile the package for more than one kind of computer at the |
4632 | + You can compile the package for more than one kind of computer at the |
4633 | same time, by placing the object files for each architecture in their |
4634 | own directory. To do this, you can use GNU `make'. `cd' to the |
4635 | directory where you want the object files and executables to go and run |
4636 | the `configure' script. `configure' automatically checks for the |
4637 | -source code in the directory that `configure' is in and in `..'. |
4638 | +source code in the directory that `configure' is in and in `..'. This |
4639 | +is known as a "VPATH" build. |
4640 | |
4641 | With a non-GNU `make', it is safer to compile the package for one |
4642 | architecture at a time in the source code directory. After you have |
4643 | installed the package for one architecture, use `make distclean' before |
4644 | reconfiguring for another architecture. |
4645 | |
4646 | + On MacOS X 10.5 and later systems, you can create libraries and |
4647 | +executables that work on multiple system types--known as "fat" or |
4648 | +"universal" binaries--by specifying multiple `-arch' options to the |
4649 | +compiler but only a single `-arch' option to the preprocessor. Like |
4650 | +this: |
4651 | + |
4652 | + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ |
4653 | + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ |
4654 | + CPP="gcc -E" CXXCPP="g++ -E" |
4655 | + |
4656 | + This is not guaranteed to produce working output in all cases, you |
4657 | +may have to build one architecture at a time and combine the results |
4658 | +using the `lipo' tool if you have problems. |
4659 | + |
4660 | Installation Names |
4661 | ================== |
4662 | |
4663 | -By default, `make install' installs the package's commands under |
4664 | + By default, `make install' installs the package's commands under |
4665 | `/usr/local/bin', include files under `/usr/local/include', etc. You |
4666 | can specify an installation prefix other than `/usr/local' by giving |
4667 | -`configure' the option `--prefix=PREFIX'. |
4668 | +`configure' the option `--prefix=PREFIX', where PREFIX must be an |
4669 | +absolute file name. |
4670 | |
4671 | You can specify separate installation prefixes for |
4672 | architecture-specific files and architecture-independent files. If you |
4673 | @@ -114,16 +156,47 @@ |
4674 | In addition, if you use an unusual directory layout you can give |
4675 | options like `--bindir=DIR' to specify different values for particular |
4676 | kinds of files. Run `configure --help' for a list of the directories |
4677 | -you can set and what kinds of files go in them. |
4678 | +you can set and what kinds of files go in them. In general, the |
4679 | +default for these options is expressed in terms of `${prefix}', so that |
4680 | +specifying just `--prefix' will affect all of the other directory |
4681 | +specifications that were not explicitly provided. |
4682 | + |
4683 | + The most portable way to affect installation locations is to pass the |
4684 | +correct locations to `configure'; however, many packages provide one or |
4685 | +both of the following shortcuts of passing variable assignments to the |
4686 | +`make install' command line to change installation locations without |
4687 | +having to reconfigure or recompile. |
4688 | + |
4689 | + The first method involves providing an override variable for each |
4690 | +affected directory. For example, `make install |
4691 | +prefix=/alternate/directory' will choose an alternate location for all |
4692 | +directory configuration variables that were expressed in terms of |
4693 | +`${prefix}'. Any directories that were specified during `configure', |
4694 | +but not in terms of `${prefix}', must each be overridden at install |
4695 | +time for the entire installation to be relocated. The approach of |
4696 | +makefile variable overrides for each directory variable is required by |
4697 | +the GNU Coding Standards, and ideally causes no recompilation. |
4698 | +However, some platforms have known limitations with the semantics of |
4699 | +shared libraries that end up requiring recompilation when using this |
4700 | +method, particularly noticeable in packages that use GNU Libtool. |
4701 | + |
4702 | + The second method involves providing the `DESTDIR' variable. For |
4703 | +example, `make install DESTDIR=/alternate/directory' will prepend |
4704 | +`/alternate/directory' before all installation names. The approach of |
4705 | +`DESTDIR' overrides is not required by the GNU Coding Standards, and |
4706 | +does not work on platforms that have drive letters. On the other hand, |
4707 | +it does better at avoiding recompilation issues, and works well even |
4708 | +when some directory options were not specified in terms of `${prefix}' |
4709 | +at `configure' time. |
4710 | + |
4711 | +Optional Features |
4712 | +================= |
4713 | |
4714 | If the package supports it, you can cause programs to be installed |
4715 | with an extra prefix or suffix on their names by giving `configure' the |
4716 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. |
4717 | |
4718 | -Optional Features |
4719 | -================= |
4720 | - |
4721 | -Some packages pay attention to `--enable-FEATURE' options to |
4722 | + Some packages pay attention to `--enable-FEATURE' options to |
4723 | `configure', where FEATURE indicates an optional part of the package. |
4724 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE |
4725 | is something like `gnu-as' or `x' (for the X Window System). The |
4726 | @@ -135,14 +208,58 @@ |
4727 | you can use the `configure' options `--x-includes=DIR' and |
4728 | `--x-libraries=DIR' to specify their locations. |
4729 | |
4730 | + Some packages offer the ability to configure how verbose the |
4731 | +execution of `make' will be. For these packages, running `./configure |
4732 | +--enable-silent-rules' sets the default to minimal output, which can be |
4733 | +overridden with `make V=1'; while running `./configure |
4734 | +--disable-silent-rules' sets the default to verbose, which can be |
4735 | +overridden with `make V=0'. |
4736 | + |
4737 | +Particular systems |
4738 | +================== |
4739 | + |
4740 | + On HP-UX, the default C compiler is not ANSI C compatible. If GNU |
4741 | +CC is not installed, it is recommended to use the following options in |
4742 | +order to use an ANSI C compiler: |
4743 | + |
4744 | + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" |
4745 | + |
4746 | +and if that doesn't work, install pre-built binaries of GCC for HP-UX. |
4747 | + |
4748 | + HP-UX `make' updates targets which have the same time stamps as |
4749 | +their prerequisites, which makes it generally unusable when shipped |
4750 | +generated files such as `configure' are involved. Use GNU `make' |
4751 | +instead. |
4752 | + |
4753 | + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot |
4754 | +parse its `<wchar.h>' header file. The option `-nodtk' can be used as |
4755 | +a workaround. If GNU CC is not installed, it is therefore recommended |
4756 | +to try |
4757 | + |
4758 | + ./configure CC="cc" |
4759 | + |
4760 | +and if that doesn't work, try |
4761 | + |
4762 | + ./configure CC="cc -nodtk" |
4763 | + |
4764 | + On Solaris, don't put `/usr/ucb' early in your `PATH'. This |
4765 | +directory contains several dysfunctional programs; working variants of |
4766 | +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' |
4767 | +in your `PATH', put it _after_ `/usr/bin'. |
4768 | + |
4769 | + On Haiku, software installed for all users goes in `/boot/common', |
4770 | +not `/usr/local'. It is recommended to use the following options: |
4771 | + |
4772 | + ./configure --prefix=/boot/common |
4773 | + |
4774 | Specifying the System Type |
4775 | ========================== |
4776 | |
4777 | -There may be some features `configure' cannot figure out automatically, |
4778 | -but needs to determine by the type of machine the package will run on. |
4779 | -Usually, assuming the package is built to be run on the _same_ |
4780 | -architectures, `configure' can figure that out, but if it prints a |
4781 | -message saying it cannot guess the machine type, give it the |
4782 | + There may be some features `configure' cannot figure out |
4783 | +automatically, but needs to determine by the type of machine the package |
4784 | +will run on. Usually, assuming the package is built to be run on the |
4785 | +_same_ architectures, `configure' can figure that out, but if it prints |
4786 | +a message saying it cannot guess the machine type, give it the |
4787 | `--build=TYPE' option. TYPE can either be a short name for the system |
4788 | type, such as `sun4', or a canonical name which has the form: |
4789 | |
4790 | @@ -150,7 +267,8 @@ |
4791 | |
4792 | where SYSTEM can have one of these forms: |
4793 | |
4794 | - OS KERNEL-OS |
4795 | + OS |
4796 | + KERNEL-OS |
4797 | |
4798 | See the file `config.sub' for the possible values of each field. If |
4799 | `config.sub' isn't included in this package, then this package doesn't |
4800 | @@ -168,9 +286,9 @@ |
4801 | Sharing Defaults |
4802 | ================ |
4803 | |
4804 | -If you want to set default values for `configure' scripts to share, you |
4805 | -can create a site shell script called `config.site' that gives default |
4806 | -values for variables like `CC', `cache_file', and `prefix'. |
4807 | + If you want to set default values for `configure' scripts to share, |
4808 | +you can create a site shell script called `config.site' that gives |
4809 | +default values for variables like `CC', `cache_file', and `prefix'. |
4810 | `configure' looks for `PREFIX/share/config.site' if it exists, then |
4811 | `PREFIX/etc/config.site' if it exists. Or, you can set the |
4812 | `CONFIG_SITE' environment variable to the location of the site script. |
4813 | @@ -179,7 +297,7 @@ |
4814 | Defining Variables |
4815 | ================== |
4816 | |
4817 | -Variables not defined in a site shell script can be set in the |
4818 | + Variables not defined in a site shell script can be set in the |
4819 | environment passed to `configure'. However, some packages may run |
4820 | configure again during the build, and the customized values of these |
4821 | variables may be lost. In order to avoid this problem, you should set |
4822 | @@ -198,11 +316,19 @@ |
4823 | `configure' Invocation |
4824 | ====================== |
4825 | |
4826 | -`configure' recognizes the following options to control how it operates. |
4827 | + `configure' recognizes the following options to control how it |
4828 | +operates. |
4829 | |
4830 | `--help' |
4831 | `-h' |
4832 | - Print a summary of the options to `configure', and exit. |
4833 | + Print a summary of all of the options to `configure', and exit. |
4834 | + |
4835 | +`--help=short' |
4836 | +`--help=recursive' |
4837 | + Print a summary of the options unique to this package's |
4838 | + `configure', and exit. The `short' variant lists options used |
4839 | + only in the top level, while the `recursive' variant lists options |
4840 | + also present in any nested packages. |
4841 | |
4842 | `--version' |
4843 | `-V' |
4844 | @@ -229,6 +355,16 @@ |
4845 | Look for the package's source code in directory DIR. Usually |
4846 | `configure' can determine that directory automatically. |
4847 | |
4848 | +`--prefix=DIR' |
4849 | + Use DIR as the installation prefix. *note Installation Names:: |
4850 | + for more details, including other options available for fine-tuning |
4851 | + the installation locations. |
4852 | + |
4853 | +`--no-create' |
4854 | +`-n' |
4855 | + Run the configure checks, but stop before creating any output |
4856 | + files. |
4857 | + |
4858 | `configure' also accepts some other, not widely useful, options. Run |
4859 | `configure --help' for more details. |
4860 | |
4861 | |
4862 | === modified file 'INSTALL.Unix' |
4863 | --- INSTALL.Unix 2012-07-30 22:49:59 +0000 |
4864 | +++ INSTALL.Unix 2013-08-30 22:06:57 +0000 |
4865 | @@ -3,6 +3,16 @@ |
4866 | |
4867 | A high-level guide to Unix-like systems, inc. Mac OS X and Ubuntu. |
4868 | |
4869 | +Community installation guides are available on the wiki: |
4870 | + |
4871 | + http://wiki.apache.org/couchdb/Installation |
4872 | + |
4873 | +This document is the canonical source of installation information. However, many |
4874 | +systems have gotchas that you need to be aware of. In addition, dependencies |
4875 | +frequently change as distributions update their archives. If you're running into |
4876 | +trouble, be sure to check out the wiki. If you have any tips to share, please |
4877 | +also update the wiki so that others can benefit from your experience. |
4878 | + |
4879 | Troubleshooting |
4880 | --------------- |
4881 | |
4882 | @@ -25,69 +35,91 @@ |
4883 | |
4884 | You should have the following installed: |
4885 | |
4886 | - * Erlang OTP (>=R12B5) (http://erlang.org/) |
4887 | - * ICU (http://icu.sourceforge.net/) |
4888 | - * OpenSSL (http://www.openssl.org/) |
4889 | - * Mozilla SpiderMonkey (1.7) (http://www.mozilla.org/js/spidermonkey/) |
4890 | - * GNU Make (http://www.gnu.org/software/make/) |
4891 | - * GNU Compiler Collection (http://gcc.gnu.org/) |
4892 | - * libcurl (http://curl.haxx.se/libcurl/) |
4893 | - * help2man (http://www.gnu.org/s/help2man/) |
4894 | + * Erlang OTP (>=R13B04, <R17) (http://erlang.org/) |
4895 | + * ICU (http://icu-project.org/) |
4896 | + * OpenSSL (http://www.openssl.org/) |
4897 | + * Mozilla SpiderMonkey (1.7) (http://www.mozilla.org/js/spidermonkey/) |
4898 | + * GNU Make (http://www.gnu.org/software/make/) |
4899 | + * GNU Compiler Collection (http://gcc.gnu.org/) |
4900 | + * libcurl (http://curl.haxx.se/libcurl/) |
4901 | + * help2man (http://www.gnu.org/s/help2man/) |
4902 | + * Python (>=2.7) for docs (http://python.org/) |
4903 | + * Python Sphinx (>=1.1.3) (http://pypi.python.org/pypi/Sphinx) |
4904 | |
4905 | -It is recommended that you install Erlang OTP R12B-5 or above where possible. |
4906 | +It is recommended that you install Erlang OTP R13B-4 or above where possible. |
4907 | You will only need libcurl if you plan to run the JavaScript test suite. And |
4908 | help2man is only need if you plan on installing the CouchDB man pages. |
4909 | - |
4910 | -Ubuntu |
4911 | -~~~~~~ |
4912 | - |
4913 | -For up to date instructions, please see: |
4914 | - |
4915 | - http://wiki.apache.org/couchdb/Installing_on_Ubuntu |
4916 | - |
4917 | -Unfortunately, it seems that installing dependancies on Ubuntu is troublesome. |
4918 | +Python and Sphinx are only required for building the online documentation. |
4919 | |
4920 | Debian-based Systems |
4921 | ~~~~~~~~~~~~~~~~~~~~ |
4922 | |
4923 | -You can install the build tools by running: |
4924 | +You can install the dependencies by running: |
4925 | |
4926 | sudo apt-get install build-essential |
4927 | - |
4928 | -You can install the other dependencies by running: |
4929 | - |
4930 | - sudo apt-get install erlang libicu-dev libmozjs-dev libcurl4-openssl-dev |
4931 | + sudo apt-get install erlang-base-hipe |
4932 | + sudo apt-get install erlang-dev |
4933 | + sudo apt-get install erlang-manpages |
4934 | + sudo apt-get install erlang-eunit |
4935 | + sudo apt-get install erlang-nox |
4936 | + sudo apt-get install libicu-dev |
4937 | + sudo apt-get install libmozjs-dev |
4938 | + sudo apt-get install libcurl4-openssl-dev |
4939 | + sudo apt-get install pkg-config |
4940 | + |
4941 | +There are lots of Erlang packages. If there is a problem with your install, try |
4942 | +a different mix. There is more information on the wiki. Additionally, you might |
4943 | +want to install some of the optional Erlang tools which may also be useful. |
4944 | |
4945 | Be sure to update the version numbers to match your system's available packages. |
4946 | |
4947 | +For up to date instructions, please see: |
4948 | + |
4949 | + http://wiki.apache.org/couchdb/Installing_on_Debian |
4950 | + |
4951 | + http://wiki.apache.org/couchdb/Installing_on_Ubuntu |
4952 | + |
4953 | +Unfortunately, it seems that installing dependencies on Ubuntu is troublesome. |
4954 | + |
4955 | +RedHat-based (Fedora, Centos, RHEL) Systems |
4956 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4957 | + |
4958 | +You can install the dependencies by running: |
4959 | + |
4960 | + sudo yum groupinstall "Development Tools" |
4961 | + sudo yum install autoconf |
4962 | + sudo yum install autoconf-archive |
4963 | + sudo yum install automake |
4964 | + sudo yum install libtool |
4965 | + sudo yum install perl-Test-Harness |
4966 | + sudo yum install erlang-etap |
4967 | + sudo yum install erlang-erts |
4968 | + sudo yum install erlang-os_mon |
4969 | + sudo yum install erlang-eunit |
4970 | + sudo yum install libicu-devel |
4971 | + sudo yum install js-devel |
4972 | + sudo yum install curl-devel |
4973 | + sudo yum install pkg-config |
4974 | + |
4975 | +While CouchDB builds against the default js-devel-1.7.0 included in some |
4976 | +distributions, it's recommended to use a more recent js-devel-1.8.5. |
4977 | + |
4978 | Mac OS X |
4979 | ~~~~~~~~ |
4980 | |
4981 | -You can install the build tools by running: |
4982 | - |
4983 | - open /Applications/Installers/Xcode\ Tools/XcodeTools.mpkg |
4984 | +To build CouchDB from source on Mac OS X, you will need to install Xcode. |
4985 | |
4986 | You can install the other dependencies by running: |
4987 | |
4988 | - brew install erlang icu4c spidermonkey curl |
4989 | - |
4990 | -You may want to link ICU so that CouchDB can find the header files automatically: |
4991 | - |
4992 | - brew link icu4c |
4993 | - |
4994 | -The same is true for recent versions of Erlang: |
4995 | - |
4996 | - brew link erlang |
4997 | - |
4998 | -If you are upgrading your version of CouchDB and have an older nspr and |
4999 | -Spidermonkey installed you may encounter an error during the ./configure step |
5000 | -below. This is generally due to nspr being installed without its pkg-config |
So nice. $ bzr diff -r72.. debian/
1) Maintainer: Jason Gerard DeRose <email address hidden>
+XSBC-Original-
This should be whoever owned the package in the previous packaging, which usually means the Debian maintainer, but can sometimes be the previous person in Ubuntu. It shouldn't be whoever's in the changelog.
2)
-case $1 in
- configure)
- if dpkg --compare-versions "$2" lt-nl 1.2.0-2ubuntu1; then
Should you be dropping this? Someone could go from 1.1 to 1.4.
3) version= $(DEB_UPSTREAM_ VERSION) --destdir . orig-source" , and it inherits ORIG_PACKAGE and ORIG_VERSION as Make/environment variables, so it should download orig sources, clean them up, and make a tarball in the current dir that extracts correctly (tar xf ORIG_PACKAGE+ "_"+ORIG_ SOURCE+ ".orig. tar.gz" -> "./"+ORIG_ PACKAGE+ "-"+ORIG_ VERSION) . This assumes you know where the official tarball or sources will be at release.
-get-orig-source:
- uscan --force-download --rename --download-
This rule can be useful. In fact, I'd update it so that it uses the most recent standard: Rule should be
"get-packaged-