11

I'm trying create http proxy server on android device. When i trying read response from HTTP server (example1.com) ( example1.com contains content-length in header) If HTTP server contains content-length, then i'm read bytes from content-length else i'm read all bytes of response

byte[] bytes = IOUtils.toByteArray(inFromServer);

The problem is that, when response contains content-length the response reads quickly. If response not contains content-length the response read slowly.

this my code

DataInputStream in = new DataInputStream(inFromServer);
        //BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String line = "";
        String str = "";
        Integer len = 0;
        while(true) {
            line = in.readLine();
            if  (line.indexOf("Content-Length") != -1)
            {
                len = Integer.parseInt( line.split("\\D+")[1] );
                //System.out.println("LINEE="+len);
            }

            out.println(line);
            str = str + line + '\n';
            if(line.isEmpty())  break;
        }
        int i = Integer.valueOf(len);
        String body= "";
        System.out.println("i="+i);
        if (i>0) {
            byte[] buf = new byte[i];
            in.readFully(buf);
            out.write(buf);
            for (byte b:buf) {
                body = body + (char)b;
            }

        }else{

            byte[] bytes = IOUtils.toByteArray(inFromServer);
            out.write(bytes);
        }

out - outStream to browser

Petr
  • 224
  • 2
  • 16
  • Why are you not using a higher level HTTP library? – OneCricketeer Feb 11 '17 at 19:20
  • I'm study the http protocol – Petr Feb 11 '17 at 19:22
  • Okay, and your problem is that there 0 content to read when there's no header, so it goes slower because it reads the entire response? – OneCricketeer Feb 11 '17 at 19:26
  • Yes, most likely a problem in this – Petr Feb 11 '17 at 19:36
  • I'm not sure why that's a problem. Of course it'll be slower because you don't know how much data to read – OneCricketeer Feb 11 '17 at 19:41
  • reading body just about a 5 minutes when reads all bytes – Petr Feb 11 '17 at 19:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/135467/discussion-between-petr-and-cricket-007). – Petr Feb 11 '17 at 19:51
  • What is inFromServer? – greenapps Feb 11 '17 at 20:11
  • 2
    If the response does not contain a content-length it probably is chunked encoding and you need to handle this accordingly. Reading until end of connection should only be done if no chunked encoding and no content-length and the status code means that there is a response body (i.e. not with 304) and the request method says that there is a response body (i.e. not with HEAD). I recommend that you actually study the [standard](https://www.ietf.org/rfc/rfc2616.txt) if you want to learn how the protocol works. – Steffen Ullrich Feb 11 '17 at 20:19
  • Once you declared a DataInputStream and read from it you should read always from it and not fall back on inFromServer. – greenapps Feb 11 '17 at 20:19

2 Answers2

7

Firstly, you should know what http protocal and how it work.

and every http Request like:

  • Request Line
  • Request Header
  • Blank Line
  • Request Body.

and every http Response like:

  • Status Line
  • Response Header
  • Blank Line
  • Response Body.

However we can read the InputStream from http server, we can split every line we read from inputstream end with '/r/n'.

and your code:

while(true) {
    **line = in.readLine();**
    if  (line.indexOf("Content-Length") != -1)
    {
        len = Integer.parseInt( line.split("\\D+")[1] );
            //System.out.println("LINEE="+len);
        }

        out.println(line);
        str = str + line + '\n';
        if(line.isEmpty())  break;
    }
}

and in.readLine() return the every line not end with '/r/n', it return the line end with '/r' or '/n' . Maybe read from the inputstream block in here.

Here is a IOStreamUtils to read line end with '/r/n'.

https://github.com/mayubao/KuaiChuan/blob/master/app/src/main/java/io/github/mayubao/kuaichuan/micro_server/IOStreamUtils.java

Ethan
  • 81
  • 2
7

Try the following code:

// Get server response
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    String line;
    StringBuilder builder = new StringBuilder();
    while ((line = reader.readLine()) != null) {
        builder.append(line);
    }
    String response = builder.toString()
    // Handle response...
}
Eyal Biran
  • 5,656
  • 1
  • 28
  • 29
  • Addition in above code : Code should handle exceptions. In maximum cases if response code is 200, response stream might be null. – dev_kj Feb 22 '17 at 17:07