0

I'm trying to post some data from a Java client using sockets. It talks to localhost running php code, that simply spits out the post params sent to it.

Here is Java Client:

 public static void main(String[] args) throws Exception {

       Socket socket = new Socket("localhost", 8888);
       String reqStr = "testString";

        String urlParameters = URLEncoder.encode("myparam="+reqStr, "UTF-8");
        System.out.println("Params: " + urlParameters);

        try {
            Writer out = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
            out.write("POST /post3.php HTTP/1.1\r\n");  
            out.write("Host: localhost:8888\r\n"); 
            out.write("Content-Length: " + Integer.toString(urlParameters.getBytes().length) + "\r\n");
            out.write("Content-Type: text/html\r\n\n");
            out.write(urlParameters);  
            out.write("\r\n");  
            out.flush();

            InputStream inputstream = socket.getInputStream();
            InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
            BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

            String string = null;
            while ((string = bufferedreader.readLine()) != null) {
               System.out.println("Received " + string);
            }

       } catch(Exception e) {
           e.printStackTrace();
       } finally {
         socket.close(); 
       }
 }

This is how post3.php looks like:

<?php

$post = $_REQUEST;

echo print_r($post, true);
?>

I expect to see an array (myparams => "testString") as the response. But its not passing post args to server. Here is output:

Received HTTP/1.1 200 OK
Received Date: Thu, 25 Aug 2011 20:25:56 GMT
Received Server: Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
Received X-Powered-By: PHP/5.3.6
Received Content-Length: 10
Received Content-Type: text/html
Received 
Received Array
Received (
Received )

Just a FYI, this setup works for GET requests.

Any idea whats going on here?

Daniel
  • 30,896
  • 18
  • 85
  • 139
bianca
  • 7,004
  • 12
  • 43
  • 58
  • 1
    Just wondering...is there any reason you're not using [HTTPClient](http://hc.apache.org/httpcomponents-client-ga/index.html)? – jches Aug 25 '11 at 20:35
  • 1
    Or [Resty](http://beders.github.com/Resty/Resty/Overview.html). – Jochen Bedersdorfer Aug 25 '11 at 20:49
  • @chesles- I'm working sending data over ssl. HttpClient-4's documentation is not very helpful to set up customized SSLSocketFactory. So, I'm trying out the things on plain sockets before I put my head on figuring out SSLSocketFactory customization with HttpClient4. – bianca Aug 25 '11 at 21:07

3 Answers3

1

As Jochen and chesles rightly point out, you are using the wrong Content-Type: header - it should indeed be application/x-www-form-urlencoded. However there are several other issues as well...

  • The last header should be seperated from the body by a blank line between the headers and the body. This should be a complete CRLF (\r\n), in your code it is just a new line (\n). This is an outright protocol violation and I'm a little surprised you haven't just got a 400 Bad Request back from the server, although Apache can be quite forgiving in this respect.
  • You should specify Connection: close to ensure that you are not left hanging around with open sockets, the server will close the connection as soon as the request is complete.
  • The final CRLF sequence is not required. PHP is intelligent enough to sort this out by itself, but other server languages and implementations may not be...

If you are working with any standardised protocol in it's raw state, you should always start by at least scanning over the RFC.

Also, please learn to secure your Apache installs...

DaveRandom
  • 87,921
  • 11
  • 154
  • 174
  • Thanks a lot dave & chesles for taking time to help me out. I need to access a thirdparty server and they asked me to send xml request in key-value pair and to use text/html Content-Type while sending request. Thanks for clearing my understanding. – bianca Aug 25 '11 at 21:48
0

It looks like you are trying to send data in application/x-www-form-urlencoded format, but you are setting the Content-Type to text/html.

Jochen Bedersdorfer
  • 4,093
  • 24
  • 26
  • @bianca By sending some HTML to the server... but why would you want to do that?? – DaveRandom Aug 25 '11 at 21:06
  • @dave, actual server accepts text/html Content-Type. Is there any way to send data as text/html rather application/x-www-form-urlencoded? – bianca Aug 25 '11 at 21:12
  • @bianca When you say 'accepts' do you mean 'is expecting'? And what is the data you need to send to the actual server? Is it POST form parameters (like you are sending here) or is in an HTML document (which is what is implied by setting `Content-Type: text/html`)? – DaveRandom Aug 25 '11 at 21:17
  • @dave, server accepts xml. Apologize, I need to set Content-Type to text/xml. How can I do that? – bianca Aug 25 '11 at 21:29
0

Use

out.write("Content-Type: application/x-www-form-urlencoded\n\n");

instead. As this page states:

The Content-Length and Content-Type headers are critical because they tell the web server how many bytes of data to expect, and what kind, identified by a MIME type.

For sending form data, i.e. data in the format key=value&key2=value2 use application/x-www-form-urlencoded. It doesn't matter if the value contains HTML, XML, or other data; the server will interpret it for you and you'll be able to retrieve the data as usual in the $_POST or $_REQUEST arrays on the PHP end.

Alternatively, you can send your data as raw HTML, XML, etc. using the appropriate Content-Type header, but you then have to retrieve the data manually in PHP by reading the special file php://input:

<?php
echo file_get_contents("php://input");
?>

As an aside, if you're using this for anything sufficiently complex, I would strongly recommend the use of an HTTP client library like HTTPClient.

jches
  • 4,542
  • 24
  • 36
  • My sample code works with this change, but actual server supports text/html Content-Type. Is there any way to send data as text/html rather application/x-www-form-urlencoded? – bianca Aug 25 '11 at 21:11
  • @bianca What exactly are you trying to send to the server? Why do you need to send HTML to the server? Are trying to upload a file? – DaveRandom Aug 25 '11 at 21:14
  • @dave, I want to send XML to the server. Something like this: testXml=testData – bianca Aug 25 '11 at 21:21
  • Even though the data is XML, you're encoding it using the conventional `x-www-form-urlencoded` format of `key=val`. Your `val` just happens to be XML text. – jches Aug 25 '11 at 21:23
  • @bianca In that example, you have wrapped your XML in `key=value` syntax - is this the way it needs to be? Or should it be a plain XML document (i.e. starting with ` – DaveRandom Aug 25 '11 at 21:27
  • @chesles I can't believe it took me 3 minutes longer than you to write that lol! – DaveRandom Aug 25 '11 at 21:28
  • @Dave you did go into a little more detail ;) – jches Aug 25 '11 at 21:33