3

I am hosting a simple PHP echo server locally. I am trying to send a message to the server in Java, and use a GET request to print the response but am getting a 'malformed HTTP request' error. Can anyone tell me how to correctly format the GET request?

//Client code:

import java.io.*;
import java.net.*;

public class TCPclient {

    public static void main(String argv[]) throws Exception {
    String sentence, modifiedSentence;
    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
    Socket clientSocket = new Socket("localhost", 8000);  
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());

    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            sentence = inFromUser.readLine();

            outToServer.writeBytes(sentence + "\n");
            outToServer.writeChars("GET /echo.php HTTP/1.1" +"\n"); 


            modifiedSentence = inFromServer.readLine();
            System.out.println("FROM SERVER: " + modifiedSentence);
            inFromServer.close();
            outToServer.close();
            inFromUser.close();
            clientSocket.close();
            }

}

//PHP Server code:

<?php

/* Simple php echo page 
*/

//      ini_set('display_errors', 'On');
//      error_reporting(E_ALL | E_STRICT);
      if(isset($_GET['source'])) {
        if ($_GET['source'] == "raw")
           echo file_get_contents(basename($_SERVER['PHP_SELF']));
        else
           echo "<pre>" . htmlspecialchars(file_get_contents(basename($_SERVER['PHP_SELF']))) . "</pre>";
      } else if (isset($_GET['message'])){
        echo strtoupper( htmlspecialchars($_GET['message'])) . '\n';
      } else {
?>
      <html>
        <head>
          <title>Error: No input message</title>
        </head>
        <body>
          <h1> No message</h1>
          <p>Echo server called without sending parameter</p>
        </body>
      </html>
<?php
      }
?>
janos
  • 120,954
  • 29
  • 226
  • 236
user2961973
  • 39
  • 1
  • 5

1 Answers1

2

An http server understand words like GET, POST, PUT, DELETE. So here's a problem:

        outToServer.writeBytes(sentence + "\n");
        outToServer.writeChars("GET /echo.php HTTP/1.1" +"\n"); 

The first statement there is telling something to the http server that it doesn't understand: the sentence. Comment out that line and your request becomes valid, and you will get a response.

I guess you want to post the sentence as a parameter to the echo service. You can put it in the query string:

        outToServer.writeChars("GET /echo.php?message=" + sentence + " HTTP/1.0\n\n"); 

I also changed the HTTP version and appended an extra \n as pointed out by the comment of Steffen Ullrich:

Also you must add empty line to mark the end of the header. And the line ending must be \r\n not \n. And you should better do a HTTP/1.0 request not HTTP/1.1 since your code is neither able to deal with HTTP keep-alive nor with HTTP chunked encoding

However, this is not quite enough. You also need to encode some characters, such as spaces. The URL in the get request must be encoded, as pointed out by @zapl in a comment.

I also recommend to test your echo service first using simple telnet:

telnet localhost 8000

There, you can type your message, "GET /echo.php?message=something" and verify it works. Once you find something that works as intended, you can update the Java code accordingly.

janos
  • 120,954
  • 29
  • 226
  • 236
  • I would on top [url encode](http://stackoverflow.com/questions/10786042/java-url-encoding-of-query-string-parameters) `sentence` before sticking it in the [request line](https://tools.ietf.org/html/rfc7230#section-3.1.1) – zapl Oct 08 '15 at 13:09
  • Thanks, you're absolutely right, I forgot to mention that. Fixed now. (I I'll add your links later, I'm on a phone now and it's hard) – janos Oct 08 '15 at 13:16
  • 1
    Also, the client must include Host header in the request as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23 - some servers may accept a request with missing Host header, but some do refuse such requests. – Jiri Tousek Oct 08 '15 at 13:26
  • 1
    Also the must be an empty line to mark the end of the header. And the line ending must be \r\n not \n. And one should better do a HTTP/1.0 request not HTTP/1.1 since the code is neither able to deal with HTTP keep-alive nor with HTTP chunked encoding. – Steffen Ullrich Oct 08 '15 at 13:38
  • Thank you guys, embedded into my answer – janos Oct 08 '15 at 13:43