Index: trunk/src/org/openstreetmap/josm/gui/progress/AbstractProgressMonitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/progress/AbstractProgressMonitor.java	(revision 9528)
+++ trunk/src/org/openstreetmap/josm/gui/progress/AbstractProgressMonitor.java	(revision 9529)
@@ -219,5 +219,5 @@
     ==================*/
 
-    abstract void updateProgress(double value);
+    protected abstract void updateProgress(double value);
 
     @Override
Index: trunk/src/org/openstreetmap/josm/io/StreamProgressUpdater.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/StreamProgressUpdater.java	(revision 9528)
+++ trunk/src/org/openstreetmap/josm/io/StreamProgressUpdater.java	(revision 9529)
@@ -27,6 +27,6 @@
 
     private void initProgressMonitor() {
+        progressMonitor.beginTask(taskTitle);
         if (size > 0) {
-            progressMonitor.subTask(taskTitle);
             progressMonitor.setTicksCount((int) size);
         } else {
Index: trunk/src/org/openstreetmap/josm/tools/HttpClient.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/HttpClient.java	(revision 9528)
+++ trunk/src/org/openstreetmap/josm/tools/HttpClient.java	(revision 9529)
@@ -103,6 +103,7 @@
             connection.setFixedLengthStreamingMode(requestBody.length);
             connection.setDoOutput(true);
+            final ProgressMonitor subTaskMonitor = progressMonitor.createSubTaskMonitor(1, false);
             try (OutputStream out = new BufferedOutputStream(
-                    new ProgressOutputStream(connection.getOutputStream(), requestBody.length, progressMonitor))) {
+                    new ProgressOutputStream(connection.getOutputStream(), requestBody.length, subTaskMonitor))) {
                 out.write(requestBody);
             }
@@ -256,6 +257,7 @@
                 in = connection.getErrorStream();
             }
+            monitor.subTask(tr("Fetching content..."));
             if (in != null) {
-                in = new ProgressInputStream(in, getContentLength(), monitor);
+                in = new ProgressInputStream(in, getContentLength(), monitor.createSubTaskMonitor(1, false));
                 in = "gzip".equalsIgnoreCase(getContentEncoding()) ? new GZIPInputStream(in) : in;
                 Compression compression = Compression.NONE;
Index: trunk/test/functional/org/openstreetmap/josm/tools/HttpClientTest.java
===================================================================
--- trunk/test/functional/org/openstreetmap/josm/tools/HttpClientTest.java	(revision 9528)
+++ trunk/test/functional/org/openstreetmap/josm/tools/HttpClientTest.java	(revision 9529)
@@ -17,8 +17,11 @@
 import javax.json.spi.JsonProvider;
 
+import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.openstreetmap.josm.JOSMFixture;
+import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.data.Version;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 
 /**
@@ -27,7 +30,14 @@
 public class HttpClientTest {
 
+    private ProgressMonitor progress;
+
     @BeforeClass
     public static void setUpBeforeClass() {
         JOSMFixture.createFunctionalTestFixture().init();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        progress = TestUtils.newTestProgressMonitor();
     }
 
@@ -51,5 +61,5 @@
     @Test
     public void testGet() throws Exception {
-        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/get?foo=bar")).connect();
+        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/get?foo=bar")).connect(progress);
         assertThat(response.getRequestMethod(), is("GET"));
         assertThat(response.getResponseCode(), is(200));
@@ -70,5 +80,5 @@
     @Test
     public void testUserAgent() throws Exception {
-        try (final InputStream in = HttpClient.create(new URL("https://httpbin.org/user-agent")).connect().getContent();
+        try (final InputStream in = HttpClient.create(new URL("https://httpbin.org/user-agent")).connect(progress).getContent();
              final JsonReader json = JsonProvider.provider().createReader(in)) {
             assertThat(json.readObject().getString("user-agent"), is(Version.getInstance().getFullAgentString()));
@@ -78,5 +88,5 @@
     @Test
     public void testFetchUtf8Content() throws Exception {
-        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/encoding/utf8")).connect();
+        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/encoding/utf8")).connect(progress);
         assertThat(response.getResponseCode(), is(200));
         final String content = response.fetchContent();
@@ -91,5 +101,5 @@
                 .setHeader("Content-Type", "text/plain")
                 .setRequestBody(text.getBytes(StandardCharsets.UTF_8))
-                .connect();
+                .connect(progress);
         assertThat(response.getResponseCode(), is(200));
         try (final InputStream in = response.getContent();
@@ -100,6 +110,19 @@
 
     @Test
+    public void testPostZero() throws Exception {
+        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/post"), "POST")
+                .setHeader("Content-Type", "text/plain")
+                .setRequestBody("".getBytes(StandardCharsets.UTF_8))
+                .connect(progress);
+        assertThat(response.getResponseCode(), is(200));
+        try (final InputStream in = response.getContent();
+             final JsonReader json = JsonProvider.provider().createReader(in)) {
+            assertThat(json.readObject().getString("data"), is(""));
+        }
+    }
+
+    @Test
     public void testRelativeRedirects() throws Exception {
-        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/relative-redirect/5")).connect();
+        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/relative-redirect/5")).connect(progress);
         assertThat(response.getResponseCode(), is(200));
         assertThat(response.getContentLength() > 100, is(true));
@@ -108,5 +131,5 @@
     @Test
     public void testAbsoluteRedirects() throws Exception {
-        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/absolute-redirect/5")).connect();
+        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/absolute-redirect/5")).connect(progress);
         assertThat(response.getResponseCode(), is(200));
         assertThat(response.getContentLength() > 100, is(true));
@@ -115,5 +138,5 @@
     @Test(expected = IOException.class)
     public void testTooMuchRedirects() throws Exception {
-        HttpClient.create(new URL("https://httpbin.org/redirect/5")).setMaxRedirects(4).connect();
+        HttpClient.create(new URL("https://httpbin.org/redirect/5")).setMaxRedirects(4).connect(progress);
     }
 
@@ -121,5 +144,5 @@
     public void test418() throws Exception {
         // https://tools.ietf.org/html/rfc2324
-        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/status/418")).connect();
+        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/status/418")).connect(progress);
         assertThat(response.getResponseCode(), is(418));
         assertThat(response.getResponseMessage(), is("I'M A TEAPOT"));
@@ -130,5 +153,5 @@
     @Test
     public void testRequestInTime() throws Exception {
-        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/delay/3")).setReadTimeout(3500).connect();
+        final HttpClient.Response response = HttpClient.create(new URL("https://httpbin.org/delay/3")).setReadTimeout(3500).connect(progress);
         assertThat(response.getResponseCode(), is(200));
     }
@@ -136,5 +159,5 @@
     @Test(expected = IOException.class)
     public void testTakesTooLong() throws Exception {
-        HttpClient.create(new URL("https://httpbin.org/delay/3")).setReadTimeout(2500).connect();
+        HttpClient.create(new URL("https://httpbin.org/delay/3")).setReadTimeout(2500).connect(progress);
     }
 }
Index: trunk/test/unit/org/openstreetmap/josm/TestUtils.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/TestUtils.java	(revision 9528)
+++ trunk/test/unit/org/openstreetmap/josm/TestUtils.java	(revision 9529)
@@ -4,4 +4,5 @@
 import static org.junit.Assert.fail;
 
+import java.awt.Component;
 import java.io.File;
 import java.io.IOException;
@@ -10,4 +11,8 @@
 import java.util.Comparator;
 
+import org.openstreetmap.josm.gui.progress.AbstractProgressMonitor;
+import org.openstreetmap.josm.gui.progress.CancelHandler;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.gui.progress.ProgressTaskId;
 import org.openstreetmap.josm.io.Compression;
 
@@ -145,3 +150,52 @@
                 dotPos > -1 ? dotPos : dashPos > -1 ? dashPos : 1));
     }
+
+    /**
+     * Returns an instance of {@link AbstractProgressMonitor} which keeps track of the monitor state,
+     * but does not show the progress.
+     * @return a progress monitor
+     */
+    public static ProgressMonitor newTestProgressMonitor() {
+        return new AbstractProgressMonitor(new CancelHandler()) {
+
+            @Override
+            protected void doBeginTask() {
+            }
+
+            @Override
+            protected void doFinishTask() {
+            }
+
+            @Override
+            protected void doSetIntermediate(boolean value) {
+            }
+
+            @Override
+            protected void doSetTitle(String title) {
+            }
+
+            @Override
+            protected void doSetCustomText(String title) {
+            }
+
+            @Override
+            protected void updateProgress(double value) {
+            }
+
+            @Override
+            public void setProgressTaskId(ProgressTaskId taskId) {
+            }
+
+            @Override
+            public ProgressTaskId getProgressTaskId() {
+                return null;
+            }
+
+            @Override
+            public Component getWindowParent() {
+                return null;
+            }
+
+        };
+    }
 }
