keianhzo,
Do you have an example of how you call this class?
I think I understand, but wanted to doublecheck.
I am using an HttpURLConnection with ChunkedStreaming mode to upload videos
to Facebook.
Using that mode successfully avoids running into memory issues, but I am not
successful in getting a response back from Facebook.
Carmen
> > // Set up URL Connection for streaming
> > HttpURLConnection conn = (HttpURLConnection)
connectURL.openConnection();
> > conn.setDoInput(true);
> > conn.setDoOutput(true);
> > conn.setUseCaches(false);
> > conn.setChunkedStreamingMode(
1000*1024);
> > conn.setRequestMethod("POST");
> > conn.setRequestProperty("Connection", "Keep-Alive");
> > conn.setRequestProperty("Content-Type",
> > "multipart/form-data;boundary="+boundary);
On Tue, Apr 27, 2010 at 7:53 PM, keianhzo <[email protected]> wrote:
> Hi,
>
> I had big headaches with this issue too, and finally opted for using
> sockets to upload big files otherwise any way tried always led me to
> the OutOfMemoryException or BufferOverflowException. So here is the
> code that works for me. All the meat is in the send() method, but I
> post the whole class for a better understanding. Feel free to use it
> or modify it to fit your needs if your find it useful:
>
> public class HttpMultipartClient {
>
> public class Parameter {
>
> private String name;
> private String value;
>
> public Parameter(String n, String v) {
> name = n;
> value = v;
> }
>
> public void setName(String n) {
> name = n;
> }
>
> public void setValue(String v) {
> value = v;
> }
>
> public String getName() {
> return name;
> }
>
> public String getValue() {
> return value;
> }
>
> @Override
> public String toString() {
> return getName() + ":" + getValue();
> }
> }
>
> private static final String TAG = "HttpMultipartClient";
>
> private static final int CONNECTION_TIMEOUT = 10000;
> private static final String END = "\r\n";
> private final String boundary = new Integer(new Random()
> .nextInt(Integer.MAX_VALUE)).toString();
> private final String lastBoundary = END + "--" + boundary + "--" +
> END;
>
> private Socket socket;
> private String host;
> private int port;
> private String path;
> private String method;
> private List<Parameter> headers;
> private List<Parameter> cookies;
> private List<Parameter> fields;
> private String fileName;
> private InputStream fileStream;
> private int fileSize;
> private int responseCode;
> private String responseMessage;
> private String responseBody;
> private List<Parameter> responseHeaders;
>
> private StringBuilder headersBuffer;
> private StringBuilder bodyBuffer;
> private long length = 0;
>
> public HttpMultipartClient(String h, String pth, int p)
> throws IllegalArgumentException {
> if (h == null || h.length() == 0)
> throw new IllegalArgumentException("Invalid host
> name: host=" + h);
> else {
> host = h;
> path = pth;
> port = p;
> socket = new Socket();
> headers = new ArrayList<Parameter>();
> cookies = new ArrayList<Parameter>();
> fields = new ArrayList<Parameter>();
> responseHeaders = new ArrayList<Parameter>();
> responseBody = null;
> }
> }
>
> public void disconnect() throws IOException {
> socket.close();
> }
>
> public void addHeader(String name, String value)
> throws IllegalArgumentException {
> if (name == null || value == null)
> throw new IllegalArgumentException("Header invalid:
> name=" + name
> + ", value=" + value);
> else {
> headers.add(new Parameter(name, value));
> if (Log.isLoggable(TAG, Log.DEBUG))
> Log.d(TAG, "Adding header [" + name + ": " +
> value + "]");
> }
> }
>
> public void addCookie(String name, String value)
> throws IllegalArgumentException {
> if (name == null || value == null)
> throw new IllegalArgumentException("Cookie invalid:
> name=" + name
> + ", value=" + value);
> else {
> cookies.add(new Parameter(name, value));
> if (Log.isLoggable(TAG, Log.DEBUG))
> Log.d(TAG, "Adding cookie [" + name + ": " +
> value + "]");
> }
> }
>
> public void addField(String name, String value)
> throws IllegalArgumentException {
> if (name == null || value == null)
> throw new IllegalArgumentException("Field invalid:
> name=" + name
> + ", value=" + value);
> else {
> fields.add(new Parameter(name, value));
> if (Log.isLoggable(TAG, Log.DEBUG))
> Log.d(TAG, "Adding field [" + name + ": " +
> value + "]");
> }
> }
>
> public void addFile(String fn, InputStream is, int fs) {
> if (is == null)
> throw new IllegalArgumentException("Invalid null
> input stream");
> else {
> fileName = fn;
> fileStream = is;
> fileSize = fs;
> if (Log.isLoggable(TAG, Log.DEBUG))
> Log.d(TAG, "Adding file [filename: " +
> fileName + "]");
> }
> }
>
> private void prepare() {
> preHeaders();
> prepareBody();
> postHeaders();
> }
>
> private void preHeaders() {
> if (Log.isLoggable(TAG, Log.DEBUG))
> Log.d(TAG, "Pre headers");
>
> headersBuffer = new StringBuilder();
> headersBuffer.append(method + " " + path + " HTTP/1.1" +
> END);
> headersBuffer.append("User-Agent: FileSocialClient 1.0" +
> END);
> headersBuffer.append("Host: " + host + END);
> headersBuffer.append("Content-Type: multipart/form-data;
> boundary="
> + boundary + END);
>
> if (!headers.isEmpty()) {
> for (Iterator<Parameter> it = headers.iterator();
> it.hasNext();) {
> Parameter param = it.next();
> headersBuffer.append(param.getName());
> headersBuffer.append(": ");
> headersBuffer.append(param.getValue());
> headersBuffer.append(END);
>
> if (Log.isLoggable(TAG, Log.DEBUG))
> Log.d(TAG, "Header added: " +
> param);
> }
> }
>
> if (!cookies.isEmpty()) {
> headersBuffer.append("Cookie: ");
> for (Iterator<Parameter> it = cookies.iterator();
> it.hasNext();) {
> Parameter param = it.next();
>
> headersBuffer.append(param.getName());
> headersBuffer.append("=");
> headersBuffer.append(param.getValue());
>
> if (it.hasNext())
> headersBuffer.append("; ");
>
> if (Log.isLoggable(TAG, Log.DEBUG))
> Log.d(TAG, "Cookie added: " +
> param);
> }
> headersBuffer.append(END);
> }
>
> headersBuffer.append("Content-Length: ");
> }
>
> private void postHeaders() {
> if (Log.isLoggable(TAG, Log.DEBUG))
> Log.d(TAG, "Post headers");
>
> length = fileSize + lastBoundary.length() +
> bodyBuffer.length();
> headersBuffer.append(length);
> headersBuffer.append(END + END);
> }
>
> private void prepareBody() {
> if (Log.isLoggable(TAG, Log.DEBUG))
> Log.d(TAG, "Preparing body");
>
> bodyBuffer = new StringBuilder();
>
> if (!fields.isEmpty()) {
> for (Parameter param : fields) {
> bodyBuffer.append("--");
> bodyBuffer.append(boundary);
> bodyBuffer.append(END);
> bodyBuffer.append("Content-Disposition:
> form-data; name=\"");
> bodyBuffer.append(param.getName());
> bodyBuffer.append("\"");
> bodyBuffer.append(END);
> bodyBuffer.append(END);
> bodyBuffer.append(param.getValue());
> bodyBuffer.append(END);
>
> if (Log.isLoggable(TAG, Log.DEBUG))
> Log.d(TAG, "Field added: " + param);
> }
> }
>
> if (fileStream != null) {
> bodyBuffer.append("--");
> bodyBuffer.append(boundary);
> bodyBuffer.append(END);
> bodyBuffer.append("Content-Disposition: form-data;
> name=\"");
> bodyBuffer.append("file");
> bodyBuffer.append("\"; filename=\"");
> bodyBuffer.append(fileName);
> bodyBuffer.append("\"");
> bodyBuffer.append(END);
> bodyBuffer.append(END);
> }
> }
>
> public void send() throws IOException {
> prepare();
>
> BufferedReader reader = null;
> try {
> // We send the Http Request
> socket.connect(new InetSocketAddress(host, port));
> // socket.setSoTimeout(CONNECTION_TIMEOUT);
> int bytesSent = 0;
> PrintStream out = new
> PrintStream(socket.getOutputStream());
> out.print(headersBuffer);
> out.print(bodyBuffer);
> bytesSent += headersBuffer.length() +
> headersBuffer.length();
>
> byte[] bytes = new byte[1024 * 65];
> int size;
> while ((size = fileStream.read(bytes)) > 0) {
> bytesSent += size;
> out.write(bytes, 0, size);
> out.flush();
> }
>
> out.print(lastBoundary);
> out.flush();
>
> // We read the response from the server
> reader = new BufferedReader(new
> InputStreamReader(socket.getInputStream()));
> String line = reader.readLine();
> String[] responseLine = line.trim().split(" ",3);
> responseCode = new Integer(responseLine[1]);
> responseMessage = responseLine[2];
>
> boolean headersEnd = false;
> while (( line = reader.readLine()) != null &&
> !headersEnd){
> if (line.length() == 0)
> headersEnd = true;
> else {
> String[] headerLine =
> line.trim().split(":",2);
> responseHeaders.add(new
> Parameter(headerLine[0], headerLine[1]));
> }
> }
>
> StringBuffer payload = new StringBuffer();
> boolean bodyEnd = false;
> while (( line = reader.readLine()) != null &&
> !bodyEnd) {
> if (line.length() == 0)
> bodyEnd = true;
> else
> payload.append(line.trim());
> }
>
> responseBody = payload.toString();
>
> } finally {
> try {
> fileStream.close();
> if (reader != null)
> reader.close();
>
> } catch (IOException e) {
> // TODO Auto-generated catch block
> e.printStackTrace();
> }
> }
> }
>
> public void setRequestMethod(String m) {
> method = m;
> }
>
> public void setPath(String p) {
> path = p;
> }
>
> public String getRequestMethod() {
> return method;
> }
>
> public String getPath() {
> return path;
> }
>
> public int getResponseCode() {
> return responseCode;
> }
>
> public String getResponseMessage() {
> return responseMessage;
> }
>
> public List<Parameter> getResponseHeaders() {
> return responseHeaders;
> }
>
> public String getResponseBody() {
> return responseBody;
> }
> }
>
> Hope it helps!
> Bye!
>
> On Apr 27, 2:50 pm, [email protected] wrote:
> > Hi Carmen,
> >
> > I run into the same OutOfMemoryError issue when uploading video files of
>
> > several MB within my app. I decided to look into this for the next
> version
> > of the app. So, in the unlikely event you still haven't found a solution
>
> > for this, here is how I get an answer from the server, even when using
> > setChunkedStreamingMode:
> >
> > DataInputStream inStream = new DataInputStream ( conn.getInputStream() );
> > String oneLine, fullMsg="", msgStr;
> > while (( oneLine = inStream.readLine()) != null) {
> > if (DEBUG) Log.d(TAG, "Server Response: " + oneLine);
> > fullMsg += oneLine + "\n";}
> >
> > inStream.close();
> >
> > I could have used a StringBuilder for fullMsg, but I have 2 lines at most
>
> > coming from the server.
> >
> > Robert
> > ------http://dailyroads.com/voyager/
> >
> >
> >
> >
> >
> > > If I upload a large file using an HttpURLConnection and
> > > setChunkedStreamingMode the file is successfully uploaded. But, I am
> not
> > > able to read the response from the server.
> > > If I leave out streaming mode line:
> > > conn.setChunkedStreamingMode(1000*1024);
> > > I get an out of memory error on large file, but this works well for
> small
> > > files and I get a response from the server.
> > > Any insights on this?
> > > Carmen
> > > // Set up URL Connection for streaming
> > > HttpURLConnection conn = (HttpURLConnection)
> connectURL.openConnection();
> > > conn.setDoInput(true);
> > > conn.setDoOutput(true);
> > > conn.setUseCaches(false);
> > > conn.setChunkedStreamingMode(1000*1024);
> > > conn.setRequestMethod("POST");
> > > conn.setRequestProperty("Connection", "Keep-Alive");
> > > conn.setRequestProperty("Content-Type",
> > > "multipart/form-data;boundary="+boundary);
> > > // Read response
> > > // this works for small files when not in streaming mode
> > > // for large files, connection is reset by server (time outs)
> > > Reader reader = new InputStreamReader( conn.getInputStream() );
> > > StringBuilder in = new StringBuilder( 32000 );
> > > int x;
> > > while ( (x=reader.read()) != -1 ){
> > > in.append( (char)x );
> > > }
> >
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Android Developers" group.
> > To post to this group, send email to [email protected]
> > To unsubscribe from this group, send email to
> > [email protected]<android-developers%[email protected]>
> > For more options, visit this group athttp://
> groups.google.com/group/android-developers?hl=en
>
> --
> You received this message because you are subscribed to the Google
> Groups "Android Developers" group.
> To post to this group, send email to [email protected]
> To unsubscribe from this group, send email to
> [email protected]<android-developers%[email protected]>
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en
>
--
Carmen
http://www.twitter.com/CarmenDelessio
http://www.talkingandroid.com
http://www.facebook.com/BFFPhoto
http://www.twitter.com/DroidDrop
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en