You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Thoralf Rickert <th...@m84.de> on 2003/02/21 09:15:30 UTC
HTTPClient Feature Patch
Hi!
I'm not subribed to the list, so please make a CC to my address...
I'm working on a small WebDAV application based on the org.apache.webdav
library. For user feedback it is necessary to know how many bytes a Put
request has already finished (0%...25%...50%...75%...100%) (especially
for big files). Because the WebDAV PutMethod extends the httpclient
PutMethod which extends the
org.apache.commons.httpclient.methods.EntityEnclosingMethod,
I would like to "submit" a small patch, which makes it possible to get
the number of already sent bytes in a "controlling thread"....Here is
the code:
package org.apache.commons.httpclient.methods;
[...]
public abstract class EntityEnclosingMethod extends GetMethod {
[...]
private long writtenBytes = 0;
[...]
protected boolean writeRequestBody(HttpState state,
HttpConnection conn)
throws IOException, HttpException {
[....]
writtenBytes = 0;
byte[] tmp = new byte[4096];
//int total = 0;
int i = 0;
while ((i = instream.read(tmp)) >= 0) {
outstream.write(tmp, 0, i);
//total += i;
writtenBytes += i;
}
[....]
}
/**
* Returns the Number of Request Body Bytes send to the server
*/
public long getWrittenRequestBodyBytes() {
return this.writtenBytes;
}
}
If I would start the HttpConnection in a subthread I could call the
getWrittenRequestBodyBytes() method (or however you call it) during
upload to get the number of transfered bytes. So I can show the user,
that the application still works...
Do you think, that this small patch is useful for you too or do you know
another way?
Thanks,
Thoralf Rickert
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: HTTPClient Feature Patch
Posted by Jeffrey Dever <js...@sympatico.ca>.
Thoralf Rickert wrote:
> Hi!
>
> I'm not subribed to the list, so please make a CC to my address...
>
> I'm working on a small WebDAV application based on the
> org.apache.webdav library. For user feedback it is necessary to know
> how many bytes a Put request has already finished
> (0%...25%...50%...75%...100%) (especially for big files). Because the
> WebDAV PutMethod extends the httpclient PutMethod which extends the
> org.apache.commons.httpclient.methods.EntityEnclosingMethod,
> I would like to "submit" a small patch, which makes it possible to get
> the number of already sent bytes in a "controlling thread"....Here is
> the code:
>
> package org.apache.commons.httpclient.methods;
> [...]
> public abstract class EntityEnclosingMethod extends GetMethod {
> [...]
> private long writtenBytes = 0;
> [...]
> protected boolean writeRequestBody(HttpState state,
> HttpConnection conn)
> throws IOException, HttpException {
>
> [....]
> writtenBytes = 0;
> byte[] tmp = new byte[4096];
> //int total = 0;
> int i = 0;
> while ((i = instream.read(tmp)) >= 0) {
> outstream.write(tmp, 0, i);
> //total += i;
> writtenBytes += i;
> }
> [....]
> }
>
> /**
> * Returns the Number of Request Body Bytes send to the server
> */
> public long getWrittenRequestBodyBytes() {
> return this.writtenBytes;
> }
> }
>
> If I would start the HttpConnection in a subthread I could call the
> getWrittenRequestBodyBytes() method (or however you call it) during
> upload to get the number of transfered bytes. So I can show the user,
> that the application still works...
>
> Do you think, that this small patch is useful for you too or do you
> know another way?
>
> Thanks,
> Thoralf Rickert
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: HTTPClient Feature Patch
Posted by Jeffrey Dever <js...@sympatico.ca>.
This is a good idea, particularly for updating a JProgressBar. Can you
please bring this up on the commons-httpclient-dev@jakarta.apache.org
mailing list?
Thoralf Rickert wrote:
> Hi!
>
> I'm not subribed to the list, so please make a CC to my address...
>
> I'm working on a small WebDAV application based on the
> org.apache.webdav library. For user feedback it is necessary to know
> how many bytes a Put request has already finished
> (0%...25%...50%...75%...100%) (especially for big files). Because the
> WebDAV PutMethod extends the httpclient PutMethod which extends the
> org.apache.commons.httpclient.methods.EntityEnclosingMethod,
> I would like to "submit" a small patch, which makes it possible to get
> the number of already sent bytes in a "controlling thread"....Here is
> the code:
>
> package org.apache.commons.httpclient.methods;
> [...]
> public abstract class EntityEnclosingMethod extends GetMethod {
> [...]
> private long writtenBytes = 0;
> [...]
> protected boolean writeRequestBody(HttpState state,
> HttpConnection conn)
> throws IOException, HttpException {
>
> [....]
> writtenBytes = 0;
> byte[] tmp = new byte[4096];
> //int total = 0;
> int i = 0;
> while ((i = instream.read(tmp)) >= 0) {
> outstream.write(tmp, 0, i);
> //total += i;
> writtenBytes += i;
> }
> [....]
> }
>
> /**
> * Returns the Number of Request Body Bytes send to the server
> */
> public long getWrittenRequestBodyBytes() {
> return this.writtenBytes;
> }
> }
>
> If I would start the HttpConnection in a subthread I could call the
> getWrittenRequestBodyBytes() method (or however you call it) during
> upload to get the number of transfered bytes. So I can show the user,
> that the application still works...
>
> Do you think, that this small patch is useful for you too or do you
> know another way?
>
> Thanks,
> Thoralf Rickert
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: HTTPClient Feature Patch
Posted by Ortwin Glück <or...@nose.ch>.
Thoralf Rickert wrote:
> But what about the #setRequestBody(String body) method. OK, I could use a
> ProgressInputStream(new ByteArrayInputStream(body.getBytes()))
> as the body.
Note: You should use the String.getBytes(String) method to specify an
encoding. Otherwise your code will not be portable to some platforms.
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: HTTPClient Feature Patch
Posted by Thoralf Rickert <th...@m84.de>.
Hi!
> I would recommend against doing it in this way. Primarily because it
> involves polling (the second thread calling getWrittenRequestBodyBytes()
> repeatedly) and because of the added synchronization overhead.
Yes, I would call it just once a second, but nobody knows what someone
else does.
> In my experience it is easier and more reusable to handle this at the
> InputStream level. This involves adding a wrapper class around the
> InputStream that is being put/posted. It would look something like:
>
> class ProgressInputStream extends FilterInputStream {
> [...]
So, maybe I don't need a code change in the class EntityEnclosingMethod,
because I could use the ProgressInputStream instead of a simple
InputStream in the method
EntityEnclosingMethod#setRequestBody(InputStream body)
But what about the #setRequestBody(String body) method. OK, I could use a
ProgressInputStream(new ByteArrayInputStream(body.getBytes()))
as the body.
But especially for my actual problem (the WebDAV client progressbar), I
don't have (real) access to the Source code and the above changes in the
httpclient must be added in every implementation that uses the
#setRequestBody() method.
I think, it would be easier and better to implement a "ProgressObserver"
at the lowest possible position. To avoid waste of resources, it could
be possible to add ProgressListener directly to the
EntityEnclosingMethod. Example:
public abstract class EntityEnclosingMethod extends GetMethod {
[...]
private List progressListeners = new ArrayList();
[...]
public void addProgressListener(ProgressListener listener) {
progressListeners.add(listener);
}
public List getProgressListeners() { return progressListeners; }
protected boolean writeRequestBody(
HttpState state, HttpConnection conn) {
//...
if (progressListeners.isEmpty()) {
InputStream instream = getRequestBody();
} else {
InputStream instream = new ProgressInputStream(
getRequestBody(),
getProgressListeners());
}
// ...
}
public class ProgressInputStream extends FilterInputStream {
// ...
public ProgressInputStream(InputStream is, List progressListeners) {
//...
}
// ...
private void bytesRead(int count) {
bytesRead+=count;
if (progressListeners==null || progressListeners.isEmpty()) return;
for (int i=0; i<progressListeners.size();i++) {
ProgressListener l = (ProgressListener)progressListeners.get(i);
if (bytesRead > l.getThreshold()) {
totalBytesRead += bytesRead;
bytesRead = 0;
l.progressAchieved(totalBytesRead);
}
}
}
}
The EVENT_THRESHOLD value should be part of the ProgressListener, should
be "setable" and should be checked by the ProgressInputStream.
(Different values MUST be possible, for example transfering data over a
slow connection should show the transfer of even 10 Bytes).
public Interface ProgressListener {
public void progressAchieved(long totalBytesRead);
public int getThreshold();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: HTTPClient Feature Patch
Posted by Michael Becke <be...@u.washington.edu>.
I would recommend against doing it in this way. Primarily because it
involves polling (the second thread calling
getWrittenRequestBodyBytes() repeatedly) and because of the added
synchronization overhead.
In my experience it is easier and more reusable to handle this at the
InputStream level. This involves adding a wrapper class around the
InputStream that is being put/posted. It would look something like:
class ProgressInputStream extends FilterInputStream {
private static final long EVENT_THRESHOLD = 1024;
private long bytesRead;
private long totalBytesRead;
private ProgressListener listener;
public ProgressInputStream(InputStream is, ProgressListener listener) {
super(is);
this.listener = listener;
}
private void bytesRead(int count) {
bytesRead+=count;
if (bytesRead > EVENT_THRESHOLD) {
totalBytesRead += bytesRead;
bytesRead = 0;
listener.progressAchieved(totalBytesRead);
}
}
public int read() {
int byte = super.read();
if (byte != -1) {
bytesRead(1);
}
return byte;
}
public int read(byte[] b, int offset, int length) {
int bytesRead = super.read(b, offset, length);
if (bytesRead > 0 ) {
bytesRead(bytesRead);
}
return bytesRead;
}
}
interface ProgressListener {
void progressAchieved(long totalBytesRead);
}
Then you would want to implement the ProgressListener interface with
something that updates the progress in the UI, preferably from another
thread.
Mike
On Friday, February 21, 2003, at 03:15 AM, Thoralf Rickert wrote:
> Hi!
>
> I'm not subribed to the list, so please make a CC to my address...
>
> I'm working on a small WebDAV application based on the
> org.apache.webdav library. For user feedback it is necessary to know
> how many bytes a Put request has already finished
> (0%...25%...50%...75%...100%) (especially for big files). Because the
> WebDAV PutMethod extends the httpclient PutMethod which extends the
> org.apache.commons.httpclient.methods.EntityEnclosingMethod,
> I would like to "submit" a small patch, which makes it possible to get
> the number of already sent bytes in a "controlling thread"....Here is
> the code:
>
> package org.apache.commons.httpclient.methods;
> [...]
> public abstract class EntityEnclosingMethod extends GetMethod {
> [...]
> private long writtenBytes = 0;
> [...]
> protected boolean writeRequestBody(HttpState state,
> HttpConnection conn)
> throws IOException, HttpException {
>
> [....]
> writtenBytes = 0;
> byte[] tmp = new byte[4096];
> //int total = 0;
> int i = 0;
> while ((i = instream.read(tmp)) >= 0) {
> outstream.write(tmp, 0, i);
> //total += i;
> writtenBytes += i;
> }
> [....]
> }
>
> /**
> * Returns the Number of Request Body Bytes send to the server
> */
> public long getWrittenRequestBodyBytes() {
> return this.writtenBytes;
> }
> }
>
> If I would start the HttpConnection in a subthread I could call the
> getWrittenRequestBodyBytes() method (or however you call it) during
> upload to get the number of transfered bytes. So I can show the user,
> that the application still works...
>
> Do you think, that this small patch is useful for you too or do you
> know another way?
>
> Thanks,
> Thoralf Rickert
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org