# # # patch "cmd_scgi.cc" # from [4ed4e031317d7a05b0100ceaff1586d72d7e3314] # to [c35d9cb42306191a437dbd2def99c484d3e85181] # # patch "gsync.cc" # from [4445f0113b5e93e4da95a4df906e80f5fd9f2a5c] # to [429b9da74df1ab003d7097f2460609c1dc2e28cd] # # patch "http_client.cc" # from [e76d0d4432ed71a506f7781aca7cbd61a6efc777] # to [ba03745920c4b8ee284d8616a26324dda9cec46f] # # patch "json_msgs.cc" # from [80c4e3ba2bd3dc6afe4b4097faa4d757c92bcff3] # to [a0600541e56367b0803ad6deec4828b394afc2e9] # # patch "json_msgs.hh" # from [23c8ea42a8e741ecc09731a7a2a326096df6c326] # to [94731c4b1fe5c8b2a48bf27a16bed8aeb0bef035] # ============================================================ --- cmd_scgi.cc 4ed4e031317d7a05b0100ceaff1586d72d7e3314 +++ cmd_scgi.cc c35d9cb42306191a437dbd2def99c484d3e85181 @@ -176,10 +176,10 @@ do_cmd(database & db, json_io::json_obje file_data data; file_delta delta; + db.ensure_open(); if (decode_msg_inquire_request(cmd_obj, request_revs)) { L(FL("inquiring %d revisions") % request_revs.size()); - db.ensure_open(); set response_revs; for (set::const_iterator i = request_revs.begin(); i != request_revs.end(); ++i) @@ -190,7 +190,6 @@ do_cmd(database & db, json_io::json_obje else if (decode_msg_descendants_request(cmd_obj, request_revs)) { L(FL("descendants %d revisions") % request_revs.size()); - db.ensure_open(); rev_ancestry_map parent_to_child_map; db.get_revision_ancestry(parent_to_child_map); @@ -209,19 +208,36 @@ do_cmd(database & db, json_io::json_obje toposort(db, response_set, response_revs); return encode_msg_descendants_response(response_revs); } + else if (decode_msg_get_rev_request(cmd_obj, rid)) + { + db.get_revision(rid, rev); + return encode_msg_get_rev_response(rev); + } else if (decode_msg_put_rev_request(cmd_obj, rid, rev)) { revision_id check; calculate_ident(rev, check); I(rid == check); + //db.put_revision(rid, rev); + // if put fails, encode the reason in the response return encode_msg_put_rev_response(); } + else if (decode_msg_get_file_data_request(cmd_obj, fid)) + { + db.get_file_version(fid, data); + return encode_msg_get_file_data_response(data); + } else if (decode_msg_put_file_data_request(cmd_obj, fid, data)) { // this will check that the id is correct // db.put_file(fid, data); return encode_msg_put_file_data_response(); } + else if (decode_msg_get_file_delta_request(cmd_obj, old_id, new_id)) + { + db.get_arbitrary_file_delta(old_id, new_id, delta); + return encode_msg_get_file_delta_response(delta); + } else if (decode_msg_put_file_delta_request(cmd_obj, old_id, new_id, delta)) { // this should also check that the delta applied to the data with old_id @@ -232,6 +248,11 @@ do_cmd(database & db, json_io::json_obje } else { + string type, vers; + decode_msg_header(cmd_obj, type, vers); + std::cerr << "unknown request type: " << type + << " version: " << vers + << std::endl; return encode_msg_error("unknown request"); } } @@ -251,6 +272,8 @@ process_scgi_transaction(database & db, L(FL("read %d-byte SCGI request") % data.size()); + // std::cerr << "request" << std::endl << data << std::endl; + json_io::input_source in(data, "scgi"); json_io::tokenizer tok(in); json_io::parser p(tok); @@ -266,6 +289,9 @@ process_scgi_transaction(database & db, { json_io::printer out_data; res->write(out_data); + + // std::cerr << "response" << std::endl << out_data.buf.data() << std::endl; + L(FL("sending JSON %d-byte response") % (out_data.buf.size() + 1)); out << "Status: 200 OK\r\n" ============================================================ --- gsync.cc 4445f0113b5e93e4da95a4df906e80f5fd9f2a5c +++ gsync.cc 429b9da74df1ab003d7097f2460609c1dc2e28cd @@ -279,8 +279,12 @@ run_gsync_protocol(lua_hooks & lua, data P(F("%d common revisions") % common_revs.size()); set core_frontier = common_revs; - erase_ancestors(db, core_frontier); + if (core_frontier.empty()) + core_frontier.insert(revision_id()); + else + erase_ancestors(db, core_frontier); + P(F("%d frontier revisions") % core_frontier.size()); set outbound_set; ============================================================ --- http_client.cc e76d0d4432ed71a506f7781aca7cbd61a6efc777 +++ http_client.cc ba03745920c4b8ee284d8616a26324dda9cec46f @@ -246,7 +246,8 @@ void } void -http_channel::push_rev(revision_id const & rid, revision_t const & rev) const +http_channel::push_rev(revision_id const & rid, + revision_t const & rev) const { json_value_t request = encode_msg_put_rev_request(rid, rev); json_value_t response = client.transact_json(request); @@ -257,19 +258,31 @@ http_channel::pull_rev(revision_id const void http_channel::pull_rev(revision_id const & rid, revision_t & rev) const { + json_value_t request = encode_msg_get_rev_request(rid); + json_value_t response = client.transact_json(request); + E(decode_msg_get_rev_response(response, rev), + F("received unexpected reply to 'get_rev_request' message")); } void http_channel::pull_file_data(file_id const & id, - file_data & data) const + file_data & data) const { + json_value_t request = encode_msg_get_file_data_request(id); + json_value_t response = client.transact_json(request); + E(decode_msg_get_file_data_response(response, data), + F("received unexpected reply to 'get_file_data_request' message")); } void http_channel::pull_file_delta(file_id const & old_id, - file_id const & new_id, - file_delta & delta) const + file_id const & new_id, + file_delta & delta) const { + json_value_t request = encode_msg_get_file_delta_request(old_id, new_id); + json_value_t response = client.transact_json(request); + E(decode_msg_get_file_delta_response(response, delta), + F("received unexpected reply to 'get_file_delta_request' message")); } ============================================================ --- json_msgs.cc 80c4e3ba2bd3dc6afe4b4097faa4d757c92bcff3 +++ json_msgs.cc a0600541e56367b0803ad6deec4828b394afc2e9 @@ -82,20 +82,37 @@ namespace symbol const descendants_request("descendants_request"); symbol const descendants_response("descendants_response"); + symbol const get_rev_request("get_rev_request"); + symbol const get_rev_response("get_rev_response"); + symbol const put_rev_request("put_rev_request"); symbol const put_rev_response("put_rev_response"); - symbol const get_rev_request("get_rev_request"); - symbol const get_rev_response("get_rev_request"); + symbol const get_file_data_request("get_file_data_request"); + symbol const get_file_data_response("get_file_data_response"); symbol const put_file_data_request("put_file_data_request"); symbol const put_file_data_response("put_file_data_response"); + symbol const get_file_delta_request("get_file_delta_request"); + symbol const get_file_delta_response("get_file_delta_response"); + symbol const put_file_delta_request("put_file_delta_request"); symbol const put_file_delta_response("put_file_delta_response"); } } +bool +decode_msg_header(json_value_t val, + string & type, + string & vers) +{ + query q(val); + if (q[syms::type].get(type) && q[syms::vers].get(vers)) + return true; + return false; +} + ///////////////////////////////////////////////////////////////////// // message type 'error' ///////////////////////////////////////////////////////////////////// @@ -276,7 +293,7 @@ decode_msg_descendants_response(json_val ///////////////////////////////////////////////////////////////////// -// message type 'rev' +// encode/decode cset ///////////////////////////////////////////////////////////////////// @@ -349,24 +366,24 @@ decode_cset(query q, cset & cs) string path; if (change[syms::delete_node].get(path)) { - cs.nodes_deleted.insert(file_path_external(utf8(path))); + cs.nodes_deleted.insert(file_path_internal(path)); } else if (change[syms::rename].get(path)) { string to; I(change[syms::to].get(to)); - cs.nodes_renamed.insert(make_pair(file_path_external(utf8(path)), - file_path_external(utf8(to)))); + cs.nodes_renamed.insert(make_pair(file_path_internal(path), + file_path_internal(to))); } else if (change[syms::add_dir].get(path)) { - cs.dirs_added.insert(file_path_external(utf8(path))); + cs.dirs_added.insert(file_path_internal(path)); } else if (change[syms::add_file].get(path)) { string content; I(change[syms::content].get(content)); - cs.files_added.insert(make_pair(file_path_external(utf8(path)), + cs.files_added.insert(make_pair(file_path_internal(path), file_id(content))); } else if (change[syms::patch].get(path)) @@ -374,7 +391,7 @@ decode_cset(query q, cset & cs) string from, to; I(change[syms::from].get(from)); I(change[syms::to].get(to)); - cs.deltas_applied.insert(make_pair(file_path_external(utf8(path)), + cs.deltas_applied.insert(make_pair(file_path_internal(path), make_pair(file_id(from), file_id(to)))); } @@ -382,7 +399,7 @@ decode_cset(query q, cset & cs) { string key; I(change[syms::attr].get(key)); - cs.attrs_cleared.insert(make_pair(file_path_external(utf8(path)), + cs.attrs_cleared.insert(make_pair(file_path_internal(path), attr_key(key))); } else if (change[syms::set].get(path)) @@ -390,7 +407,7 @@ decode_cset(query q, cset & cs) string key, val; I(change[syms::attr].get(key)); I(change[syms::value].get(val)); - cs.attrs_set.insert(make_pair(make_pair(file_path_external(utf8(path)), + cs.attrs_set.insert(make_pair(make_pair(file_path_internal(path), attr_key(key)), attr_value(val))); } @@ -400,6 +417,10 @@ decode_cset(query q, cset & cs) } } +///////////////////////////////////////////////////////////////////// +// encode/decode rev +///////////////////////////////////////////////////////////////////// + static void encode_rev(builder b, revision_t const & rev) { @@ -441,7 +462,70 @@ decode_rev(query q, revision_t & rev) } } +///////////////////////////////////////////////////////////////////// +// message type 'get_rev_request' +///////////////////////////////////////////////////////////////////// + json_value_t +encode_msg_get_rev_request(revision_id const & rid) +{ + builder b; + b[syms::type].str(syms::get_rev_request()); + b[syms::vers].str("1"); + b[syms::id].str(rid.inner()()); + return b.v; +} + +bool +decode_msg_get_rev_request(json_value_t val, revision_id & rid) +{ + string type, vers, id; + query q(val); + if (q[syms::type].get(type) && type == syms::get_rev_request() && + q[syms::vers].get(vers) && vers == "1" && + q[syms::id].get(id)) + { + rid = revision_id(id); + return true; + } + return false; +} + +///////////////////////////////////////////////////////////////////// +// message type 'get_rev_response' +///////////////////////////////////////////////////////////////////// + +json_value_t +encode_msg_get_rev_response(revision_t const & rev) +{ + builder b; + b[syms::type].str(syms::get_rev_response()); + b[syms::vers].str("1"); + builder rb = b[syms::rev].obj(); + encode_rev(rb, rev); + return b.v; +} + +bool +decode_msg_get_rev_response(json_value_t val, revision_t & rev) +{ + string type, vers; + query q(val); + if (q[syms::type].get(type) && type == syms::get_rev_response() && + q[syms::vers].get(vers) && vers == "1") + { + query rq = q[syms::rev]; + decode_rev(rq, rev); + return true; + } + return false; +} + +///////////////////////////////////////////////////////////////////// +// message type 'put_rev_request' +///////////////////////////////////////////////////////////////////// + +json_value_t encode_msg_put_rev_request(revision_id const & rid, revision_t const & rev) { builder b; @@ -470,6 +554,10 @@ decode_msg_put_rev_request(json_value_t return false; } +///////////////////////////////////////////////////////////////////// +// message type 'put_rev_response' +///////////////////////////////////////////////////////////////////// + json_value_t encode_msg_put_rev_response() { @@ -495,10 +583,70 @@ decode_msg_put_rev_response(json_value_t } ///////////////////////////////////////////////////////////////////// -// file data +// message type 'get_file_data_request' ///////////////////////////////////////////////////////////////////// json_value_t +encode_msg_get_file_data_request(file_id const & fid) +{ + builder b; + b[syms::type].str(syms::get_file_data_request()); + b[syms::vers].str("1"); + b[syms::id].str(fid.inner()()); + return b.v; +} + +bool +decode_msg_get_file_data_request(json_value_t val, + file_id & fid) +{ + string type, vers, id; + query q(val); + if (q[syms::type].get(type) && type == syms::get_file_data_request() && + q[syms::vers].get(vers) && vers == "1" && + q[syms::id].get(id)) + { + fid = file_id(id); + return true; + } + return false; +} + +///////////////////////////////////////////////////////////////////// +// message type 'get_file_data_response' +///////////////////////////////////////////////////////////////////// + +json_value_t +encode_msg_get_file_data_response(file_data const & data) +{ + builder b; + b[syms::type].str(syms::get_file_data_response()); + b[syms::vers].str("1"); + b[syms::data].str(encode_base64(data.inner())()); + return b.v; +} + +bool +decode_msg_get_file_data_response(json_value_t val, + file_data & data) +{ + string type, vers, dat; + query q(val); + if (q[syms::type].get(type) && type == syms::get_file_data_response() && + q[syms::vers].get(vers) && vers == "1" && + q[syms::data].get(dat)) + { + data = file_data(decode_base64_as(dat)); + return true; + } + return false; +} + +///////////////////////////////////////////////////////////////////// +// message type 'put_file_data_request' +///////////////////////////////////////////////////////////////////// + +json_value_t encode_msg_put_file_data_request(file_id const & fid, file_data const & data) { @@ -529,6 +677,10 @@ decode_msg_put_file_data_request(json_va return false; } +///////////////////////////////////////////////////////////////////// +// message type 'put_file_data_response' +///////////////////////////////////////////////////////////////////// + json_value_t encode_msg_put_file_data_response() { @@ -554,10 +706,75 @@ decode_msg_put_file_data_response(json_v } ///////////////////////////////////////////////////////////////////// -// file delta +// message type 'get_file_delta_request' ///////////////////////////////////////////////////////////////////// json_value_t +encode_msg_get_file_delta_request(file_id const & src_id, + file_id const & dst_id) +{ + builder b; + b[syms::type].str(syms::get_file_delta_request()); + b[syms::vers].str("1"); + b[syms::src_id].str(src_id.inner()()); + b[syms::dst_id].str(dst_id.inner()()); + return b.v; +} + +bool +decode_msg_get_file_delta_request(json_value_t val, + file_id & src_id, + file_id & dst_id) +{ + string type, vers, src, dst; + query q(val); + if (q[syms::type].get(type) && type == syms::get_file_delta_request() && + q[syms::vers].get(vers) && vers == "1" && + q[syms::src_id].get(src) && + q[syms::dst_id].get(dst)) + { + src_id = file_id(src); + dst_id = file_id(dst); + return true; + } + return false; +} + +///////////////////////////////////////////////////////////////////// +// message type 'get_file_delta_response' +///////////////////////////////////////////////////////////////////// + +json_value_t +encode_msg_get_file_delta_response(file_delta const & delta) +{ + builder b; + b[syms::type].str(syms::get_file_delta_response()); + b[syms::vers].str("1"); + b[syms::delta].str(encode_base64(delta.inner())()); + return b.v; +} + +bool +decode_msg_get_file_delta_response(json_value_t val, + file_delta & delta) +{ + string type, vers, del; + query q(val); + if (q[syms::type].get(type) && type == syms::get_file_delta_response() && + q[syms::vers].get(vers) && vers == "1" && + q[syms::delta].get(del)) + { + delta = file_delta(decode_base64_as(del)); + return true; + } + return false; +} + +///////////////////////////////////////////////////////////////////// +// message type 'put_file_delta_request' +///////////////////////////////////////////////////////////////////// + +json_value_t encode_msg_put_file_delta_request(file_id const & src_id, file_id const & dst_id, file_delta const & delta) @@ -593,6 +810,10 @@ decode_msg_put_file_delta_request(json_v return false; } +///////////////////////////////////////////////////////////////////// +// message type 'put_file_delta_response' +///////////////////////////////////////////////////////////////////// + json_value_t encode_msg_put_file_delta_response() { @@ -617,7 +838,6 @@ decode_msg_put_file_delta_response(json_ return false; } - // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- json_msgs.hh 23c8ea42a8e741ecc09731a7a2a326096df6c326 +++ json_msgs.hh 94731c4b1fe5c8b2a48bf27a16bed8aeb0bef035 @@ -25,6 +25,10 @@ bool decode_msg_error(json_io::json_valu json_io::json_value_t encode_msg_error(std::string const & note); bool decode_msg_error(json_io::json_value_t val, std::string & note); +bool decode_msg_header(json_io::json_value_t val, + std::string & type, + std::string & vers); + // inquire json_io::json_value_t encode_msg_inquire_request(std::set const & revs); @@ -63,15 +67,13 @@ bool decode_msg_put_rev_response(json_io // file data -json_io::json_value_t encode_msg_get_file_data(file_id const & fid); -bool decode_msg_get_file_data(json_io::json_value_t val, file_id & fid); +json_io::json_value_t encode_msg_get_file_data_request(file_id const & fid); +bool decode_msg_get_file_data_request(json_io::json_value_t val, file_id & fid); -json_io::json_value_t encode_msg_get_file_delta(file_id const & src_id, - file_id const & dst_id); -bool decode_msg_get_file_delta(json_io::json_value_t val, - file_id & src_id, - file_id & dst_id); +json_io::json_value_t encode_msg_get_file_data_response(file_data const & data); +bool decode_msg_get_file_data_response(json_io::json_value_t val, file_data & data); + json_io::json_value_t encode_msg_put_file_data_request(file_id const & fid, file_data const & data); bool decode_msg_put_file_data_request(json_io::json_value_t val, @@ -83,6 +85,16 @@ bool decode_msg_put_file_data_response(j // file delta +json_io::json_value_t encode_msg_get_file_delta_request(file_id const & src_id, + file_id const & dst_id); +bool decode_msg_get_file_delta_request(json_io::json_value_t val, + file_id & src_id, + file_id & dst_id); + +json_io::json_value_t encode_msg_get_file_delta_response(file_delta const & delta); +bool decode_msg_get_file_delta_response(json_io::json_value_t val, + file_delta & delta); + json_io::json_value_t encode_msg_put_file_delta_request(file_id const & src_id, file_id const & dst_fid, file_delta const & delta);