1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.transport;
45
46 import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_REPORT_STATUS;
47 import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_SIDE_BAND_64K;
48 import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_OTHER_REASON;
49 import static org.junit.Assert.assertEquals;
50 import static org.junit.Assert.fail;
51
52 import java.io.IOException;
53 import java.io.StringWriter;
54 import java.util.HashMap;
55 import java.util.Map;
56
57 import org.eclipse.jgit.errors.TransportException;
58 import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
59 import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
60 import org.eclipse.jgit.lib.Constants;
61 import org.eclipse.jgit.lib.NullProgressMonitor;
62 import org.eclipse.jgit.lib.ObjectId;
63 import org.eclipse.jgit.lib.ObjectInserter;
64 import org.eclipse.jgit.lib.RefUpdate;
65 import org.eclipse.jgit.lib.Repository;
66 import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
67 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
68 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
69 import org.junit.After;
70 import org.junit.Before;
71 import org.junit.Test;
72
73 public class PushConnectionTest {
74 private URIish uri;
75 private TestProtocol<Object> testProtocol;
76 private Object ctx = new Object();
77 private InMemoryRepository server;
78 private InMemoryRepository client;
79 private ObjectId obj1;
80 private ObjectId obj2;
81 private ObjectId obj3;
82 private String refName = "refs/tags/blob";
83
84 @Before
85 public void setUp() throws Exception {
86 server = newRepo("server");
87 client = newRepo("client");
88 testProtocol = new TestProtocol<>(
89 null,
90 new ReceivePackFactory<Object>() {
91 @Override
92 public ReceivePack create(Object req, Repository db)
93 throws ServiceNotEnabledException,
94 ServiceNotAuthorizedException {
95 return new ReceivePack(db);
96 }
97 });
98 uri = testProtocol.register(ctx, server);
99
100 try (ObjectInserter ins = server.newObjectInserter()) {
101 obj1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("test"));
102 obj3 = ins.insert(Constants.OBJ_BLOB, Constants.encode("not"));
103 ins.flush();
104
105 RefUpdate u = server.updateRef(refName);
106 u.setNewObjectId(obj1);
107 assertEquals(RefUpdate.Result.NEW, u.update());
108 }
109
110 try (ObjectInserter ins = client.newObjectInserter()) {
111 obj2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("file"));
112 ins.flush();
113 }
114 }
115
116 @After
117 public void tearDown() {
118 Transport.unregister(testProtocol);
119 }
120
121 private static InMemoryRepository newRepo(String name) {
122 return new InMemoryRepository(new DfsRepositoryDescription(name));
123 }
124
125 @Test
126 public void testWrongOldIdDoesNotReplace() throws IOException {
127 RemoteRefUpdate rru = new RemoteRefUpdate(null, null, obj2, refName,
128 false, null, obj3);
129
130 Map<String, RemoteRefUpdate> updates = new HashMap<>();
131 updates.put(rru.getRemoteName(), rru);
132
133 try (Transport tn = testProtocol.open(uri, client, "server");
134 PushConnection connection = tn.openPush()) {
135 connection.push(NullProgressMonitor.INSTANCE, updates);
136 }
137
138 assertEquals(REJECTED_OTHER_REASON, rru.getStatus());
139 assertEquals("invalid old id sent", rru.getMessage());
140 }
141
142 @Test
143 public void invalidCommand() throws IOException {
144 try (Transport tn = testProtocol.open(uri, client, "server");
145 InternalPushConnection c = (InternalPushConnection) tn.openPush()) {
146 StringWriter msgs = new StringWriter();
147 PacketLineOut pckOut = c.pckOut;
148
149 @SuppressWarnings("resource")
150 SideBandInputStream in = new SideBandInputStream(c.in,
151 NullProgressMonitor.INSTANCE, msgs, null);
152
153
154 StringBuilder buf = new StringBuilder();
155 buf.append("42");
156 buf.append(' ');
157 buf.append(obj2.name());
158 buf.append(' ');
159 buf.append("refs/heads/A" + obj2.name());
160 buf.append('\0').append(CAPABILITY_SIDE_BAND_64K);
161 buf.append(' ').append(CAPABILITY_REPORT_STATUS);
162 buf.append('\n');
163 pckOut.writeString(buf.toString());
164 pckOut.end();
165
166 try {
167 in.read();
168 fail("expected TransportException");
169 } catch (TransportException e) {
170 assertEquals(
171 "remote: error: invalid protocol: wanted 'old new ref'",
172 e.getMessage());
173 }
174 }
175 }
176
177 @Test
178 public void limitCommandBytes() throws IOException {
179 Map<String, RemoteRefUpdate> updates = new HashMap<>();
180 for (int i = 0; i < 4; i++) {
181 RemoteRefUpdate rru = new RemoteRefUpdate(
182 null, null, obj2, "refs/test/T" + i,
183 false, null, ObjectId.zeroId());
184 updates.put(rru.getRemoteName(), rru);
185 }
186
187 server.getConfig().setInt("receive", null, "maxCommandBytes", 195);
188 try (Transport tn = testProtocol.open(uri, client, "server");
189 PushConnection connection = tn.openPush()) {
190 try {
191 connection.push(NullProgressMonitor.INSTANCE, updates);
192 fail("server did not abort");
193 } catch (TransportException e) {
194 String msg = e.getMessage();
195 assertEquals("remote: Too many commands", msg);
196 }
197 }
198 }
199 }