0

It is a very unusual problem. I just write a test for httpcomponents and httpurlconnection, both post 3 key-value string pairs to a php file and php will combine the 3 string together and return back. Both tests work fine in my own linux server, which is a Debian Linux in a virtual machine. However, when I upload the php file to my site, which is hosted by webhostingpad.com, only the httpcomponents test works. The httpurlconnection one will get 403 forbidden as error code.

Anyone has any hint what I should do?

Here are my files:

<?php
$s1 = $_POST['s1'];
$s2 = $_POST['s2'];
$s3 = $_POST['s3'];

echo "$s1 $s2$s3";

httpcomponents

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new HttpPostTask().execute();
    }

    public class HttpDealing {
        public void post() throws UnknownHostException, IOException, HttpException {
            HttpParams params = new SyncBasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, "UTF-8");
            HttpProtocolParams.setUserAgent(params, "Test/1.1");
            HttpProtocolParams.setUseExpectContinue(params, true);

            HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
                    // Required protocol interceptors
                    new RequestContent(),
                    new RequestTargetHost(),
                    // Recommended protocol interceptors
                    new RequestConnControl(),
                    new RequestUserAgent(),
                    new RequestExpectContinue()});

            HttpRequestExecutor httpexecutor = new HttpRequestExecutor();

            HttpContext context = new BasicHttpContext(null);

            HttpHost host = new HttpHost("192.168.1.107", 80);

            DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
            ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy();

            context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
            context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);

            System.out.println("user-agent is " + context.getAttribute("User-Agent"));
            System.out.println("content-type is " + context.getAttribute("Content-Type"));

            try {

                List<NameValuePair> text_list = new ArrayList<NameValuePair>();  
                text_list.add(new BasicNameValuePair("s1", "Good"));  
                text_list.add(new BasicNameValuePair("s2", "idea"));  
                text_list.add(new BasicNameValuePair("s3", "!"));
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(text_list, "utf-8");

                if (!conn.isOpen()) {
                    Socket socket = new Socket(host.getHostName(), host.getPort());
                    conn.bind(socket, params);
                }
                BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST",
                        "/test_name_post.php");
                request.setEntity(entity);
                System.out.println(">> Request URI: " + request.getRequestLine().getUri());

                request.setParams(params);
                httpexecutor.preProcess(request, httpproc, context);
                HttpResponse response = httpexecutor.execute(request, conn, context);
                response.setParams(params);
                httpexecutor.postProcess(response, httpproc, context);

                System.out.println("<< Response: " + response.getStatusLine());
                System.out.println(EntityUtils.toString(response.getEntity()));
                System.out.println("==============");
                if (!connStrategy.keepAlive(response, context)) {
                    conn.close();
                } else {
                    System.out.println("Connection kept alive...");
                }
            } finally {
                conn.close();
            }
        }
    }

    private class HttpPostTask extends AsyncTask<Void, Void, String> {
        protected String doInBackground (Void... v) {

            HttpDealing http_dealing = new HttpDealing();
            try {
                http_dealing.post();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (HttpException e) {
                e.printStackTrace();
            }

            return null;
        }
    }

}

httpurlconnection:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new HttpPostTask().execute();
    }

    public class HttpDealing {
        public void post() throws IOException {
            URL url = new URL("http://192.168.1.107/test_name_post.php");
            System.out.println("url is " + url.toString());

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setChunkedStreamingMode(0);

            List<AbstractMap.SimpleEntry<String, String>> params = new ArrayList<AbstractMap.SimpleEntry<String, String>>();
            params.add(new AbstractMap.SimpleEntry<String, String>("s1", "Good"));
            params.add(new AbstractMap.SimpleEntry<String, String>("s2", "idea"));
            params.add(new AbstractMap.SimpleEntry<String, String>("s3", "!"));

            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "utf-8"));
            writer.write(getQuery(params));
            writer.flush();
            writer.close();
            os.close();

            System.out.println("user agent is " + conn.getRequestProperty("User-Agent"));
            System.out.println("content type is " + conn.getRequestProperty("Content-Type"));

            conn.connect();

            System.out.println("response code is " + conn.getResponseCode());

            try {
                InputStream in;
                if (conn.getResponseCode() == HttpURLConnection.HTTP_FORBIDDEN) 
                    in = new BufferedInputStream(conn.getErrorStream());
                else 
                    in = new BufferedInputStream(conn.getInputStream());

                System.out.println("result is " + readStream(in));
            } finally {
                conn.disconnect();
            }
        }


        private String getQuery(List<AbstractMap.SimpleEntry<String, String>> params) throws UnsupportedEncodingException
        {
            StringBuilder result = new StringBuilder();
            boolean first = true;

            for (AbstractMap.SimpleEntry<String, String> pair : params)
            {
                if (first)
                    first = false;
                else
                    result.append("&");

                result.append(URLEncoder.encode(pair.getKey(), "utf-8"));
                result.append("=");
                result.append(URLEncoder.encode(pair.getValue(), "utf-8"));
            }

            return result.toString();
        }

        private String readStream(InputStream in) throws IOException {
            String result = "";
            InputStreamReader reader = new InputStreamReader(in, "utf-8");
            char[] buffer = new char[5];
            int count = 0;

            while ((count = reader.read(buffer)) != -1) 
                result += new String(buffer, 0, count);

            return TextUtils.isEmpty(result) ? null : result;
        }
    }

    private class HttpPostTask extends AsyncTask<Void, Void, String> {
        protected String doInBackground(Void... v) {
            HttpDealing http_dealing = new HttpDealing();
            try {
                http_dealing.post();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return null;
        }
    }

}
Owen Zhao
  • 3,205
  • 1
  • 26
  • 43

1 Answers1

0

It is even odder that I have solved the problem by remove

conn.setChunkedStreamingMode(0);

just replace the code:

conn.setDoOutput(true);
conn.setChunkedStreamingMode(0);

to

conn.setRequestMethod("POST");
conn.setDoOutput(true);

However in the android document, it is said

For best performance, you should call either setFixedLengthStreamingMode(int) when the body length is known in advance, or setChunkedStreamingMode(int) when it is not. Otherwise HttpURLConnection will be forced to buffer the complete request body in memory before it is transmitted, wasting (and possibly exhausting) heap and increasing latency.

So I lost the benefit if I do this and if the buffer is too big, my app may crash. Any idea why this happens?

Also, I have noticed that in phpinfo(), the apache has an remote address which is not the ip of my domain, is that what causes the problem?

For setChunkedStreamingMode, it is said by Java Doc.

When output streaming is enabled, authentication and redirection cannot be handled automatically. A HttpRetryException will be thrown when reading the response if authentication or redirection are required. This exception can be queried for the details of the error.

So I need to manually deal with redirections. However, using code from here.

URLConnection con = new URL( url ).openConnection();
System.out.println( "orignal url: " + con.getURL() );
con.connect();
System.out.println( "connected url: " + con.getURL() );
InputStream is = con.getInputStream();
System.out.println( "redirected url: " + con.getURL() );
is.close();

I find out that my url is not redirected. So I guess the problem is not because of redirections.

So here is the new problem. I can remove code

conn.setChunkedStreamingMode(0)

but that is not recomended and cost more memory cosumption and may lead my app to crash if the buffer is too big.

Any ideas?

=============================================================

I find out that although setChunkedStreamingMode() can't use in my case, the setFixedLengthStreamingMode() works fine.

So I use setFixedLengthStreamingMode() and everything works fine now. Still wondering why setChunkedStreamingMode() works in my own server but does not in the webhostingpad.com's server.

Community
  • 1
  • 1
Owen Zhao
  • 3,205
  • 1
  • 26
  • 43