/*
   Post.java -- simple HTTP POST utility.

   Usage:  java Post http://serviceEndpoint [ @file | string ]

   ( curl ... / curl --data-binary @file ... / curl --data-binary string ... )

$ cat te0t | java Post http://dp3-l3:40000 | od -tcx1
0000000   t   e  \0   t
         74  65  00  74
0000004
$
$ java Post http://dp7-l3:2048 @ab.xml ; echo
<?xml version="1.0" encoding="UTF-8"?>
<a>1<b>2</b>3</a>
$
$ java Post http://dp3-l3:40000 te0t | od -tcx1
0000000   t   e   0   t
         74  65  30  74
0000004
$
*/
import java.io.*;
import java.net.*;

class Post
{
  public static void main(String[] args) throws Exception
  {
    checkParams(args);

    URL url = new URL(args[0]);

    HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
    httpConn.setDoOutput(true);

    // send HTTP POST request
    if (args.length == 1
    {
      copy(System.in, httpConn.getOutputStream());
    }
    else if ( args[1].startsWith("@") ) 
    {
      FileInputStream fin = new FileInputStream( args[1].substring(1) );
      copy(fin, httpConn.getOutputStream());
      fin.close();
    }
    else 
    {
      httpConn.getOutputStream().write( args[1].getBytes() );
    }

    // output HTTP response
    if (httpConn.getResponseCode() >= 400) {
      copy(httpConn.getErrorStream(), System.out);
    } else {
      copy(httpConn.getInputStream(), System.out);
    }
  }


  // parameter check and usage
  private static void checkParams(String[] args) {
    if ( ( args.length < 1 ) || ( args.length > 2 ) ||
         ( !args[0].startsWith("http://") )
       )
    {
      System.err.println(
        "Usage:  java Post http://serviceEndpoint [ @file | string ]"
      );
      System.exit(1);
    }
  }


  // copy method from From E.R. Harold's book "Java I/O"
  public static void copy(InputStream in, OutputStream out)
  throws IOException {
          // do not allow other threads to read from the
          // input or write to the output while copying is
          // taking place
          synchronized (in) {
                  synchronized (out) {
                          byte[] buffer = new byte[256];
                          while (true) {
                                  int bytesRead = in.read(buffer);
                                  if (bytesRead == -1)
                                          break;
                                  out.write(buffer, 0, bytesRead);
                          }
                  }
          }
  }
}