jttp - Send an HTTP(S) request to a web server and process the response.
Install Apache Maven and run mvn clean package. This will execute the tests and produce the jttp.jar binary.
java [jvm args] -jar /path/to/jttp.jar [-dhNORvV] [-A user[:password]] [-M mimetype] [-o filename] [-p
entity] [-P NONE|COLOR|INDENT|ALL] [--post-process-script-name
scriptname] [--pre-process-script-name scriptname] [-S sessionname]
[-X methodname] [--post-process-script-arg arg]...
[--pre-process-script-arg arg]... [@<filename>...] url
[request_item...]Command line HTTP(S) client, similar to httpie. Offers numerous input and output methods and many authentication options. Input for forms or json can be set as arguments from the command line or as redirected input files. Simple json is generated from command line arguments. For more complex formats, use input redirection.
Jttp may be extended or enhanced by using scripts that execute before and after the request is made. These scripts may be written in Groovy.
url- Request url. Scheme defaults to
http://if the URL doesn't include one. You can also use a shorthand for localhost$ java Jttp.java :8080 # => http://localhost:8080 $ java Jttp.java /foo # => http://localhost/foo request_item- Optional key-value pairs to be included in the request. The separator used determins the type:
':'HTTP headers:Referer:http://example.com Cookie:foo=bar User-Agent:Crawler/1.0'=='URL parameters to be appended to the URI (query string):el==toro marco==polo'='Data fields to be serialized into a JSON object (with-M JSON) or form data (with-M FORM):fizz=buzz bar=baz foo=fu'@'Form file fields:filename@Documents/report.docx
-A,--auth user[:passwd]- If only the username is provided, (e.g.
-A user), Jttp will prompt for the password. -d,--download- Do not print the response body to stdout. Rather, download it and store it in a file. The filename is guessed unless specified with
-o filename. If the value of-ois not an absolute path, the output is saved in a relative directory to the current directory. If nothing is specified and no preference for download directory is set (see PREFERENCES), then the file is saved to${user.home}/.jttp/downloads/<GUESSED-FILENAME> -h,--help- Shows a detailed help message and exits.
-M,--request-mime-type mimetype- Set the request MIME type. Should be one of FORM, JSON or MULTIPART.
-N,--no-verify- Turn off certificate and host name checking. The internal logger will emit a WARNING message when this option is set.
-O,--offline- Build the request and print it, but don't actually send it.
-o,--output filename- Save output to
filenameinstead of stdout. If-dis also set, then only the response body is saved tofilename. -P,--pretty-print NONE|COLOR|INDENT|ALL- Controls output processing. The value can be
NONEto not prettify the output,ALLto apply both colors and indenting (default when printing toSystem.out),COLOR, orINDENT. --post-process-script script_name- Script to run after the request has fetched data but before final output is handled by Jttp.
--post-process-script-arg script_arg- Argument to pass to the
--post-process-script. This can be specified as many times as you need for your script. The args will be passed to the script as an array of Strings to the script in a variable bound to the nameargs. --pre-process-script- Script to run before the request has fetched data but after initial setup has been performed by Jttp.
--pre-process-script-arg- Argument to pass to the
--pre-process-script. This can be specified as many times as you need for your script. The args will be passed to the script as an array of Strings to the script in a variable bound to the nameargs. -p,--print what- String specifying what the output should contain:
"H"- Request headers
"B"- Request body
"h"- Resposne headers
"b"- Response body
-R,--read-only-session- Load the named session, but don't change it when processing the response. Ignored if
-S sessionnameisn't specified. -S,--session sessionname- Create or reuse and update a session. Within a session, headers, request history, cookies and response data are persisted between requests.
By default, session files are stored in:
${user.home}/.jttp/sessions/<HOST>/<SESSION_NAME>.zipThe zip file contains the files:
headers.xml,history.xml, any response data, andcookies.xml. -v,--verbose- Print request and response headers and body. Shortcut for
-p HBhb. -V,--version- Shows the version information and exits.
-X,--request-method methodname- HTTP method to run, one of DELETE, GET (default), HEAD, OPTIONS, POST, PUT, or TRACE.
0- Successful run.
1- One of the following occurred:
- A required option was not set.
- An option with a required argument was missing its argument.
- An exception was thrown/raised.
2- Either no options were set or the
--helpor--versionoption was set.
messages_jttp.properties- Contains all application messages. Useful for i18n messages for this application. This file needs to be in the same directory as
Jttp.java. ${user.home}/.jttp/downloads- Default directory for storing downloaded responses.
${user.home}/.jttp/scripts- Default directory for storing scripts.
${user.home}/.jttp/sessions- Default directory for storing session data.
Jttp does not add preferences when it runs. You should use another tool to add these preferences under the user root with the node name /com/github/argherna/jttp/<subnode>. The last qualifier in the preferences documented is the preference name.
user/com/github/argherna/jttp/directories/base- Base directory for most save information (default is
${user.home}/.jttp). user/com/github/argherna/jttp/directories/downloads- Absolute pathname for storing downloads (from using the
--downloadoption with no--outputoption set; default is${base}/downloadswhere${base}is the value of the base preference above). user/com/github/argherna/jttp/directories/scripts- Directory (under
${base}) where scripts are stored (default is${base}/scripts). user/com/github/argherna/jttp/directories/sessions- Directory (under
${base}) where session files are stored (default is${base}/sessions).
Jttp is implemented with the HttpURLConnection. This means all system properties that apply to it are applicable to Jttp with all desired side-effects.
The Jttp-specific system properties that can be set are:
jttp.indent- Number of spaces to indent output when formatting (default is
2). jttp.keep.tempfiles- When
true, don't delete any temporary files produced by the run (default isfalse).
Other system properties are also used by internal subsystems:
content.types.user.table- Path to a custom filename map (mimetable), used by the
java.net.FileNameMapimplementation to determine file mimetype by looking at the file extension. http.auth.preference- One of
SPNEGO,digest,NTLM, orbasic(which is the default). See the Http Authentication reference below for more information. java.security.auth.login.config- Path to the JAAS configuration file.
java.security.krb5.conf- Path to the Kerberos configuration file. Ignored unless
SPNEGOauthentication is specified. java.util.logging.config.file- Standard Java System Property that points to a logging configuration file.
javax.net.debug- Write SSL debug information to
System.err. See the references below related to debugging SSL. javax.net.ssl.keyStore- Standard Java System Property that points to the keystore to use for client authentication.
javax.net.ssl.keyStorePassword- Standard Java System Property that is the password for the keystore specified by
javax.net.ssl.keyStore. javax.net.ssl.keyStoreType- Standard Java System Property that is the type for the keystore specified by
javax.net.ssl.keyStore(default isJKS). javax.net.ssl.trustStore- Standard Java System Property that points to the truststore to use for server authentication (default is the JRE's
cacertsfile). javax.net.ssl.trustStorePassword- Standard Java System Property that is the password for the truststore specified by
javax.net.ssl.trustStore(default is changeit). javax.net.ssl.trustStoreType- Standard Java System Property that is the type for the truststore specified by
javax.net.ssl.trustStore(default isJKS). javax.security.auth.useSubjectCredsOnly- Set to
falseto make the underlying Kerberos mechanism obtain Kerberos credentials. Jttp does not support a setting oftrue. sun.security.spnego.debug- Writes SPNEGO debug messages to
System.err. Useful for troubleshooting SPNEGO authentication issues. sun.security.krb5.debug- Writes Kerberos debug messages to
System.err. Useful for troubleshooting SPNEGO authentication issues.
Examples are formatted using unix multiline style.
Generate the request but don't send it.
java -jar jttp.jar -Ov http://www.example.comSave session information (useful to keep a cookie-based session going after login).
java -jar jttp.jar \
-S my_session \
https://www.example.com/secureSend a form with a file to upload.
java -jar jttp.jar \
-M FORM POST \
https://www.example.com/expenses \
user=myUserId \
statement@Documents/expenses.xlsxSet a custom header.
java -jar jttp.jar \
http://www.example.com/ua-sniffer \
User-Agent:my-custom-ua/1.2.3.4Note that you can set system properties in a text file (for example call it argsfile), one per line defined as -Dname=value as usual and then pass the filename to the java command with @argsfile. This is a useful shorthand for making repeated requests using the same settings. For illustrative purposes, these examples will specify the system properties on the command line.
Use SPNEGO authentication. Assume a krb5.conf file and JAAS configuation file my-jaas.conf exist at the specified locations.
java -Dhttp.auth.preference=SPNEGO \
-Djava.security.auth.login.config=/secure/my-jaas.conf \
-Djava.security.krb5.conf=/secure/krb5.conf \
-Djavax.security.auth.useSubjectCredsOnly=false \
-jar jttp.jar https://www.example.com/SPNEGO/docUse your keystore to authenticate your client (note the Url for cryptomix.com is a free service to test client authentication).
java -Djavax.net.ssl.keyStore=/home/user/.keystore \
-Djavax.net.ssl.keyStorePassword=changeit \
-jar jttp.jar https://server.cryptomix.com/secure/You can specify scripts to run before and after the actual HTTP request is run. The Groovy scripting language jars are part of the jttp.jar file. If you specify the same script name for both --pre-process-script and --post-process-script, they are executed separately using separate instances of the underlying Java scripting objects. This example shows how to tell Jttp to run a script called pre-auth.groovy before running the HTTP request. You can specify scripts written with different languages for both scripts.
java -jar jttp.jar \
--pre-process-script pre-auth.groovy \
https://authed.example.com/secureYou can specify options to pass to the --pre or --post processing scripts.
java -jar jttp.jar \
--pre-process-script pre-auth.groovy \
--pre-process-script-arg "--userid bob" \
--pre-process-script-arg "--keystore /home/bob/.keystore" \
https://authed.example.com/secureAnd you can specify scripts to run both before and after the HTTP request has been made.
java -jar jttp.jar \
--pre-process-script pre-auth.groovy \
--pre-process-script-arg "--userid bob" \
--pre-process-script-arg "--keystore /home/bob/.keystore" \
--post-process-script post-dbload.groovy \
--post-process-script-arg "--jdbcurl jdbc:hsqldb:mem:mydb" \
--post-process-script-arg "--jdbcuser sa" \
--post-process-script-arg an_arg \
https://authed.example.com/secureJttp was inspired by and has several features and options copied from httpie. The motivation for Jttp was to implement a client using the venerable HttpURLConnection to demonstrate how to use it effectively. The HttpURLConnection is versatile and takes advantage of many built-in features to the Java Runtime through system properties including SPNEGO authentication, client certificate authentication, basic authentication, and custom MIME-type databases. Since the intended use for Jttp is as a command line program, system properties are well-suited for this purpose. StackOverflow provides an excellent essay on how to use HttpURLConnection the way it was intended. This shows that the API does not necessarily have to mirror the actual conversation that takes place between clients and servers but rather acts as a way to send and receive data to process.
Jttp will download all responses to the java.io.tmpdir location (usually $TMPDIR). It will then either read from the file locally to produce output that can be formatted for indentation and color or copy the file to the downloads directory. The temporary files are deleted at the end of the run unless the jttp.keep.tempfiles system property is specified with a value of true. Keeping the temporary files is useful for debugging certain issues that can arise during execution. Otherwise they should just be thrown away.
Jttp binds an object to the scripting engine called jttpScriptObject that gives scripts access to:
- The HttpURLConnection (through the
getHttpURLConnectionmethod) in the current state it's in depending on when the script was executed. If it is executed before the HTTP request is run, you can set headers, etc. You don't have to set the method since Jttp does that for you. If it is executed after the HTTP request is run, you have access to the response headers. It's best practice to use scripting to set headers before the HTTP request is run. It's best practice to not modify any responses or response data in the HttpURLConnection after the HTTP request is run. - The temporary response file (through the
getResponseFilemethod), but only in scripts run after the HTTP request is run. It's best practice to use the temporary file to read and process but not modify. - A logger (through the
logmethod) that will write log messages to the logger used by Jttp atINFOlevel.
Both the java launcher and Jttp recognize at-files (@-files). These are files that you can make that contains either a jvm or program argument (1 per line). Combining with shell aliases, this makes jttp incredibly easy to use. For example, if you have to make repeated requests to a server and you need to take advantage of many of the system properties on the jvm, make a file called /home/user/jttp-args and give it the following:
-Dhttp.auth.preference=SPNEGO
-Djava.security.auth.login.config=/secure/my-jaas.conf
-Djava.security.krb5.conf=/secure/krb5.conf
-Djavax.security.auth.useSubjectCredsOnly=false
-jar
/path/to/jttp
Now run jttp:
java @/home/user/jttp-args https://spnego.example.com/secureYou can edit /home/user/jttp-args to have whatever you want in it. Similarly, you could make an @-file for jttp args, but that has to be a separate file. For example, make a file called /home/user/jttp-pgm-args and give it the following:
-v
-X POST
-M JSON
https://httpbin.org/post
Now run jttp and redirect a file called /home/user/httpbin-post.json as input:
java @/home/user/jttp-args @/home/user/jttp-pgm-args < /home/user/httpbin-post.jsonFinally, you could define a shell alias to make this go even faster. For example, this works in bash and zsh:
alias jttp="java @/home/user/jttp-args"Now you can simply run jttp as follows:
jttp @/home/user/jttp-pgm-args < /home/user/httpbin-post.jsonYou can combine aliases as well in any way you want to make your life easier when running jttp.
- httpie
- Http Authentication
- (Kerberos) Troubleshooting
- Java Logging Configuration
- Debugging SSL/TLS Connections
- (SSL) Debugging Utilities
- How to use java.net.URLConnection to fire and handle HTTP requests?
- Package javax.script
Andy Gherna <mailto: [email protected]>
Report issues at https://github.com/argherna/jttp/issues.
- Support for the
PATCHmethod is server dependent. - HTTP/2 is not supported.
- Asynchronous requests are not supported.
- Rendering issues will occur when
--pretty-print INDENTor--pretty-print ALLor the default settings are set depending on the document received. This is due to the formatting done by Jttp and can be adjusted (you have the code in front of you and I love reviewing pull requests).