Skip to content
Permalink
Browse files

Allow user to specify HTTP protocol version in Get or Post

Required a move to the Apache HTTP Client libraries.
  • Loading branch information...
birchb1024 committed Oct 31, 2015
1 parent 356de25 commit 508ccfd428ec5b8565d0a2576988d05e552a62c2
@@ -15,5 +15,7 @@
<classpathentry kind="lib" path="needed/opencsv-1.8.jar"/>
<classpathentry kind="lib" path="needed/jline-2.11.jar" sourcepath="/home/birchb/workspace/jline/jline2/src/main/java"/>
<classpathentry kind="lib" path="needed/commons-io-2.4.jar"/>
<classpathentry kind="lib" path="/home/birchb/workspace/genyris/needed/httpclient-4.5.1.jar"/>
<classpathentry kind="lib" path="/home/birchb/workspace/genyris/needed/httpcore-4.4.3.jar"/>
<classpathentry kind="output" path="build"/>
</classpath>
659 build.xml

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -12428,7 +12428,7 @@ Triples and graphs allow the programmer to store information about objects
\end_layout

\begin_layout Section
IO - Input and Output
Input and Output
\end_layout

\begin_layout Subsection
@@ -14456,7 +14456,7 @@ web:get


\emph default
<url> [<request headers>]
<url> [<request headers> [<protocol version>]]
\end_layout

\begin_layout Standard
@@ -14466,6 +14466,7 @@ web:get
\emph default
function.
This takes as input a URL string and an optional list of request headers.
The HTTP protocol can be specified as either '1.0' or '1.1' (default).
It sends the GET request to web server then returns a list containing the
response content in a
\emph on
@@ -14498,16 +14499,16 @@ Reader
\begin_layout Standard
The response must have the 200 'OK' status code otherwise an exception is
raised.
Example, fetching the root file from the localhost server on port 80, providing
a 'Basic' authentication header.
Example, fetching the root file from the localhost server on port 80, using
HTTP/1.0 and providing a 'Basic' authentication header.
\end_layout

\begin_layout LyX-Code
web:get 'http://localhost:8080/' =
\end_layout

\begin_layout LyX-Code
^(('authorization' = 'Basic Zm9vOmJhcg=='))
^(('authorization' = 'Basic Zm9vOmJhcg==')) '1.0'
\end_layout

\begin_layout Subsubsection
@@ -14527,7 +14528,7 @@ web:post


\emph default
<url> [<params assoc>] [<request headers>]
<url> [<params assoc>] [<request headers> [<protocol version>]]
\end_layout

\begin_layout Standard
@@ -14538,6 +14539,7 @@ web:post
function.
This takes as input a URL string and an optional lists of request POST
parameters and headers.
The HTTP protocol can be specified as either '1.0' or '1.1' (default).
It sends the POST request to web server then returns a list containing
the response content in a
\emph on
@@ -14570,8 +14572,8 @@ Reader
\begin_layout Standard
The response must have the 200 'OK' status code otherwise an exception is
raised.
For example, to send a POST with two parameters, and read the response
to a string:
For example, to send a HTTP/1.1 POST with two parameters, a basic auth login,
and read the response to a string:
\end_layout

\begin_layout LyX-Code
@@ -14602,6 +14604,10 @@ The response must have the 200 'OK' status code otherwise an exception is
'authorization' = 'Basic Zm9vOmJhcg=='
\end_layout

\begin_layout LyX-Code
~ 1.1
\end_layout

\begin_layout LyX-Code
var receivedData
\end_layout
Binary file not shown.
Binary file not shown.
@@ -1,18 +1,29 @@
package org.genyris.web;

import java.net.URLConnection;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpMessage;
import org.apache.http.HttpVersion;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.entity.BufferedHttpEntity;
import org.genyris.core.Exp;
import org.genyris.core.Pair;
import org.genyris.core.StrinG;
import org.genyris.exception.AccessException;
import org.genyris.exception.GenyrisException;
import org.genyris.interp.ApplicableFunction;
import org.genyris.interp.Closure;
import org.genyris.interp.Environment;
import org.genyris.interp.Interpreter;
import org.genyris.interp.UnboundException;
import org.genyris.io.readerstream.ReaderStream;

public abstract class HTTPclientFunction extends ApplicableFunction {

String charset = "UTF-8";

public HTTPclientFunction(Interpreter interp, String name, boolean eager) {
super(interp, name, eager);
@@ -21,20 +32,59 @@ public HTTPclientFunction(Interpreter interp, String name, boolean eager) {
public abstract Exp bindAndExecute(Closure proc, Exp[] arguments, Environment envForBindOperations)
throws GenyrisException;

protected Exp getResponseHeadersAsList(URLConnection conn) throws GenyrisException {
//
// Go into an HTTPresponse and retrieve headers as a nested list.
//
Exp headerList = NIL;
int headerIndex = 1;
String headerName;
while( (headerName = conn.getHeaderFieldKey(headerIndex)) != null ) {
StrinG headerValue = new StrinG(conn.getHeaderField(headerIndex));
Exp thisHeader = Pair.cons(new StrinG(headerName), headerValue);
headerList = Pair.cons(thisHeader, headerList);
headerIndex += 1;
// protected Exp getResponseHeadersAsList(URLConnection conn) throws GenyrisException {
// //
// // Go into an HTTPresponse and retrieve headers as a nested list.
// //
// Exp headerList = NIL;
// int headerIndex = 1;
// String headerName;
// while( (headerName = conn.getHeaderFieldKey(headerIndex)) != null ) {
// StrinG headerValue = new StrinG(conn.getHeaderField(headerIndex));
// Exp thisHeader = Pair.cons(new StrinG(headerName), headerValue);
// headerList = Pair.cons(thisHeader, headerList);
// headerIndex += 1;
// }
// return Pair.reverse(headerList, NIL);
// }

protected Exp processResponse(String URI, CloseableHttpResponse response) throws IOException {
try {
HttpEntity entity = response.getEntity();
entity = new BufferedHttpEntity(entity);
Header[] responseHeaders = response.getAllHeaders();
Exp headerList = NIL;
for (int i = responseHeaders.length - 1; i >= 0; i--) {
headerList = Pair.cons(Pair.cons(
new StrinG(responseHeaders[i].getName()), new StrinG(
responseHeaders[i].getValue())), headerList);
}
return Pair.cons2(new ReaderStream( new InputStreamReader(entity.getContent()), URI),
headerList, NIL);
} finally {
response.close();
}
}

protected void addHeadersToRequest(Exp headers, String charset, HttpMessage httpGetOrPost)
throws AccessException {

httpGetOrPost.setHeader("Content-Type",
"application/x-www-form-urlencoded;charset=" + charset);
while (headers != NIL) {
httpGetOrPost.setHeader(headers.car().car().toString(), headers.car().cdr()
.toString());
headers = headers.cdr();
}
}

protected HttpVersion parseProtocol(Exp protocol) {
String protocolstring = protocol.toString();
HttpVersion httpVersion = HttpVersion.HTTP_1_1;
if ( protocolstring.equals("1.0") ) {
httpVersion = HttpVersion.HTTP_1_0;
}
return Pair.reverse(headerList, NIL);
return httpVersion;
}

public static void bindFunctionsAndMethods(Interpreter interpreter)
@@ -5,24 +5,20 @@
//
package org.genyris.web;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import org.apache.http.HttpVersion;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.genyris.core.Constants;
import org.genyris.core.Exp;
import org.genyris.core.Pair;
import org.genyris.core.StrinG;
import org.genyris.exception.GenyrisException;
import org.genyris.interp.Closure;
import org.genyris.interp.Environment;
import org.genyris.interp.Interpreter;
import org.genyris.io.readerstream.ReaderStream;

public class HTTPgetFunction extends HTTPclientFunction {

@@ -32,40 +28,44 @@ public HTTPgetFunction(Interpreter interp) {

public Exp bindAndExecute(Closure proc, Exp[] arguments,
Environment envForBindOperations) throws GenyrisException {
checkArguments(arguments, 1, 2);
checkArguments(arguments, 1, 3);
Class[] types = {StrinG.class};
checkArgumentTypes(types, arguments);
String URI = arguments[0].toString();
Exp headers = (arguments.length == 2 ? arguments[1] : NIL);
Exp headers = (arguments.length >= 2 ? arguments[1] : NIL);
if( ! (headers == NIL || headers instanceof org.genyris.core.Pair) ) {
throw new GenyrisException("Headers must be a list.");
}
Exp protocol = (arguments.length >= 3 ? arguments[2] : NIL);
if( ! (protocol == NIL || protocol instanceof org.genyris.core.StrinG) ) {
throw new GenyrisException("Protocol must be a String.");
}
HttpVersion httpVersion = parseProtocol(protocol);

CloseableHttpClient httpclient = HttpClients.createDefault();

try {
URL url = new URL(URI);
URLConnection conn = url.openConnection();
if(!(conn instanceof HttpURLConnection)) {
throw new GenyrisException("Not an HttpURLConnection: " + conn);
}
HttpURLConnection httpConn = (HttpURLConnection)conn;
while (headers != NIL) {
conn.addRequestProperty(headers.car().car().toString(), headers.car().cdr().toString());
headers = headers.cdr();
}
httpConn.connect();
if (httpConn.getResponseCode() != 200) {
throw new GenyrisException("Server returned non 200 Response Code: " + Integer.toString(httpConn.getResponseCode()));
}
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
Exp headerList = getResponseHeadersAsList(conn);
return Pair.cons2(new ReaderStream((Reader) in, URI), headerList, NIL);

} catch (MalformedURLException e1) {
throw new GenyrisException(e1.getMessage());
HttpGet httpGet = new HttpGet(URI);
httpGet.setProtocolVersion(httpVersion);

addHeadersToRequest(headers, charset, httpGet);

CloseableHttpResponse response = httpclient.execute(httpGet);

return processResponse(URI, response);
} catch (IOException e) {
throw new GenyrisException(e.getMessage());
} catch (java.lang.RuntimeException e) {
if(e.getMessage().equals("java.lang.IllegalArgumentException: protocol = http host = null"))
throw new GenyrisException("Proably got a 302 redirection to a bad URL?" + e.getMessage());
else
throw e;
throw new GenyrisException(e.toString());
}
finally {
try {
httpclient.close();
} catch (IOException ignored) {
ignored.printStackTrace();
}
}

}
}
Oops, something went wrong.

0 comments on commit 508ccfd

Please sign in to comment.
You can’t perform that action at this time.