Skip to content
Permalink
Browse files

Add web:post function

  • Loading branch information...
birchb1024 committed Oct 26, 2015
1 parent 7cf4759 commit 3ff07af08d565e63c4db3c1e2655dc581afb00a7
@@ -1,5 +1,5 @@
* Genyris License
* Copyright (c) 2008,2009,2010 Peter William Birch
* Copyright (c) 2008-2015 Peter William Birch
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -14422,15 +14422,15 @@ n')
\end_layout

\begin_layout Subsection
Interacting with Web Servers with
Interacting with Web Servers with HTTP
\emph on
HTTP

\begin_inset Index idx
status open

\begin_layout Plain Layout

\emph on
\emph off
HTTP
\end_layout

@@ -14460,10 +14460,18 @@ web:get
\end_layout

\begin_layout Standard
Content can be sent to and fetched from web servers using the web: get function.
Content can be sent to and fetched from web servers using the
\emph on
web:get
\emph default
function.
This takes as input a URL string and an optional list of request headers.
It sends the GET request to web server and the returns the response content
in a Reader stream.
in a
\emph on
Reader
\emph default
stream.
The response must have the 200 'OK' status code otherwise an exception
is raised.
\end_layout
@@ -14481,6 +14489,85 @@ web:get 'http://localhost:8080/' =
^(('authorization' = 'Basic Zm9vOmJhcg=='))
\end_layout

\begin_layout Subsubsection

\emph on
web:post
\begin_inset Index idx
status open

\begin_layout Plain Layout

\emph on
web:post
\end_layout

\end_inset


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

\begin_layout Standard
Content can also be sent to and fetched from web servers using the
\emph on
web:post
\emph default
function.
This takes as input a URL string and an optional lists of request POST
parameters and headers.
It sends the POST request to web server and the returns the response content
in a
\emph on
Reader
\emph default
stream.
The response must have the 200 'OK' status code otherwise an exception
is raised.
\end_layout

\begin_layout Standard
For example, to send a POST with two parameters, and read the response to
a string:
\end_layout

\begin_layout LyX-Code
var response
\end_layout

\begin_layout LyX-Code
web:post 'http://127.0.0.1:7780/'
\end_layout

\begin_layout LyX-Code
data
\end_layout

\begin_layout LyX-Code
a = 'test-web-post'
\end_layout

\begin_layout LyX-Code
x = 908
\end_layout

\begin_layout LyX-Code
data
\end_layout

\begin_layout LyX-Code
'authorization' = 'Basic Zm9vOmJhcg=='
\end_layout

\begin_layout LyX-Code
var receivedData
\end_layout

\begin_layout LyX-Code
response(.readAll)
\end_layout

\begin_layout Section
Programming in the Large
\end_layout
@@ -10,7 +10,7 @@ df httpd-serve (request)
template
html()
head()
title() "Genyris demo"
title() $sys:argv
body()
div() "Hit number: " $counter
pre()
@@ -19,7 +19,7 @@ df httpd-serve (request)


cond
(and sys:argv (equal? (task:id)!name 'main'))
httpd 8000 sys:argv!left
u:format "Server listening on http://127.0.0.1:8000/\nType Ctrl-C to halt."
read
(and sys:argv (equal? (task:id)!name 'main'))
httpd 8000 sys:argv!left
u:format "Server listening on http://127.0.0.1:8000/\nType Ctrl-C to halt."
read
@@ -32,6 +32,7 @@
:load-class-by-name "org.genyris.format.AbstractFormatFunction"
:load-class-by-name "org.genyris.task.TaskFunction"
:load-class-by-name "org.genyris.web.HTTPgetFunction"
:load-class-by-name "org.genyris.web.HTTPpostFunction"
:load-class-by-name "org.genyris.classification.IsInstanceFunction"
:load-class-by-name "org.genyris.test.JunitRunnerFunction"
:load-class-by-name "org.genyris.system.ExitMethod"
@@ -0,0 +1,129 @@
// Copyright 2009 Peter William Birch <birchb@genyis.org>
//
// This software may be used and distributed according to the terms
// of the Genyris License, in the file "LICENSE", incorporated herein by reference.
//
package org.genyris.web;

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

import org.genyris.core.Constants;
import org.genyris.core.Exp;
import org.genyris.core.StrinG;
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 class HTTPpostFunction extends ApplicableFunction {

public HTTPpostFunction(Interpreter interp) {
super(interp, Constants.WEB + "post", true);
}

public Exp bindAndExecute(Closure proc, Exp[] arguments,
Environment envForBindOperations) throws GenyrisException {
String charset = "UTF-8";

checkArguments(arguments, 1, 3);
Class[] types = { StrinG.class };
checkArgumentTypes(types, arguments);
String URI = arguments[0].toString();
Exp params = (arguments.length >= 2 ? arguments[1] : NIL);
Exp headers = (arguments.length == 3 ? arguments[2] : NIL);

try {
URLConnection conn = new URL(URI).openConnection();
if (!(conn instanceof HttpURLConnection)) {
throw new GenyrisException("Not an HttpURLConnection: " + conn);
}
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setRequestMethod("POST");
conn.setDoOutput(true); // Triggers POST.
conn.setRequestProperty("Accept-Charset", charset);
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset=" + charset);
while (headers != NIL) {
conn.addRequestProperty(headers.car().car().toString(), headers.car()
.cdr().toString());
headers = headers.cdr();
}
String query = "";
while (params != NIL) {
query = query.concat(URLEncoder.encode(params.car().car().toString(),
charset));
query = query.concat("=");
query = query.concat(URLEncoder.encode(params.car().cdr().toString(),
charset));
if (params.cdr() != NIL) {
query = query.concat("&");
}
params = params.cdr();
}
query = query.concat("\r\n");

OutputStream output = conn.getOutputStream();
output.write(query.getBytes(charset));
output.flush();
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()));
return new ReaderStream((Reader) in, URI);

} catch (MalformedURLException e) {
throw new GenyrisException(e.getMessage());
} 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;
}
/*
*
* try { URL url = new URL(URI); URLConnection conn =
* url.openConnection();
*
* 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()));
* return new ReaderStream((Reader)in, URI); } catch
* (MalformedURLException e1) { throw new
* GenyrisException(e1.getMessage()); } 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; }
*/
}

public static void bindFunctionsAndMethods(Interpreter interpreter)
throws UnboundException, GenyrisException {
interpreter.bindGlobalProcedureInstance(new HTTPpostFunction(interpreter));
}
}
@@ -3,35 +3,44 @@

def prepend-home (relative-path) (System!HOME (.+ '/' relative-path))

def readPage(url)
var wstream (web:get url)
var count 0
while (wstream(.hasData))
setq count (+ count 1)
write (wstream(.read)) ^-
wstream(.close)
u:format "%nRead %a bytes%n" count
count

def run-web()
var thread (httpd 7776 (prepend-home "test/mocks/www-text.g"))
sleep 1000
thread(.kill)
var threads
list
httpd 7778 (prepend-home "test/mocks/www-text.g") "."
httpd 7779 (prepend-home "test/mocks/www-static.g") "."
httpd 7780 (prepend-home "test/mocks/www-post.g") "."
sleep 1000

def run-web-get()
var thread (httpd 7778 (prepend-home "test/mocks/www-text.g"))
sleep 1000
var result (readPage "http://localhost:7778/")
thread(.kill)
result
def test-web-get()
var response
web:get 'http://127.0.0.1:7778/?A=1&B=2'
var receivedData
response(.readAll)
assertEqual receivedData '~ "hello world"'


def test-web-static-get()
var result (web:get "http://localhost:7779/LICENSE")
var sum (result(.digest "MD5"))
assertEqual sum "73ddde084d8b0dfc11ef415f14ba2cb0"

def run-web-static-get()
var thread (httpd 7778 (prepend-home "test/mocks/www-static.g") ".")
sleep 1000
var result (readPage "http://localhost:7778/LICENSE")

def test-web-post()
var response
web:post 'http://127.0.0.1:7780/'
data
a = 'test-web-post'
x = 908
data
'authorization' = 'Basic Zm9vOmJhcg=='
var receivedData
response(.readAll)
assertEqual receivedData "('a' = 'test-web-post') ('x' = '908')"

test-web-get
test-web-static-get
test-web-post

for thread in threads
thread(.kill)
result

run-web
run-web-get
run-web-static-get

@@ -0,0 +1,16 @@
#
# Server to return POST request parameters
#
@prefix sys "http://www.genyris.org/lang/system#"
@prefix task "http://www.genyris.org/lang/task#"
@prefix u "http://www.genyris.org/lang/utilities#"

df httpd-serve (request)
list 200 "text/plain"
request(.getParameters)

cond
(and sys:argv (equal? (task:id)!name 'main'))
httpd 8000 sys:argv!left
u:format "Server listening on http://127.0.0.1:8000/\nType Ctrl-C to halt."
read
@@ -1,3 +1,3 @@
df httpd-serve (request)
list 200 "text/plain" "hello world"
list 200 "text/plain" ^"hello world"

0 comments on commit 3ff07af

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