Smart CODE
Your on-line guide to the generated code

NAME
SendHandlerProc - POSTing data to a web server, or overriding thin-client data exchange

INTRODUCTION
The SendHandlerProc is the routine that allows you to override the data that is sent to the server. If you are using Internet Smart Code, writing any data in this routine will force the access to be a POST request rather than a GET. This is so that your application can interact with data servers on the World Wide Web, whose default client interface is an HTML form. If you use this stub in Thin-Client Smart Code, the only data that gets sent down to the server is the data you write in this routine.

SYNOPSIS

C


#include "URL.h"

typedef int (*SendHandlerProc) ( URLConnection *,sc_stdcs_t *)
	URLConnection * uc;
	sc_stdcs_t * data;
C++

#include "URL.h"

typedef int (*SendHandlerProc)( URLConnection *, sc_stdcs_c*)
	URLConnection* uc;
	sc_stdcs_c * data;
Java

public class HANDLERNAME_c extends SCOutputDataHandler
{
	public void doit( SCStdCS csdata, OutputStream ostream)
	{}

	public static HANDLERNAME_c getNew_HANDLERNAME_c() {
		return new HANDLERNAME_c();
	}
}

Inputs

Other Notes
HANDLERNAME will be replaced in the generated code by the name you have given to your Send Handler routine.

DESCRIPTION
Query Format
The SendHandler is causing a data POST to a web server. Unless you are making use of a form-handling program of your own, you will need to understand the format of the query that is sent by the standard interface to the server program - the HTML form.

A web browser will take the FORM elements in the HTML form, convert any text into an encoded format, and send the data as name=value pairs, name corresponding to the name tag of the FORM element, and value, its setting/data.

It may also send content headers to the server identifying itself, the URL of the form, and other details. Some servers may take note of this information, and may, for example respond differently to Netscape compared to Internet Explorer. Sophisticated server programs may even refuse to reply to clients that they don't recognise.

The easiest way to find out how the default HTML form interface interacts with the server is to monitor the connection. The following java program will run a simple server that just echoes what is sent to it. To find out what gets sent when you press a form's submit button:

  • load the form into your web browser
  • fill it in
  • run the java server program below - it runs on your local machine on port 2000.
  • go to your web browser's preferences page and change your HTTP proxy to your local machine, port 2000
  • press submit
  • the request will be echoed on the terminal where you are running the java program, for example:

    
    $ javac Server.java
    $ java Server
    Listening on port 2000
    
    GET http://search.yahoo.co.uk/search/ukie?p=search+me&y=u HTTP/1.0
    Referer: http://www.yahoo.co.uk/
    Proxy-Connection: Keep-Alive
    User-Agent: Mozilla/4.05 [en] (X11; I; SunOS 5.5 sun4m)
    Host: search.yahoo.co.uk
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
    Accept-Language: en
    Accept-Charset: iso-8859-1,*,utf-8
    Cookie: INTERSE=192218887821987
    
  • now press the stop button on your browser (it is waiting for a reply that won't happen!) and reset your proxy preferences.
  • This example puts the query in the URL itself and uses the GET method. This can be imitated by setting the "Url Data" field in the Internet Smart Code customizer dialog to be a function, and programming that function to return the appropriate query string. This section concentrates on forms with potentially more than 128 bytes of query data - which will be handled through the POST method - the data being sent on the output stream after the content headers.

    Here is the code for the Java monitor program. Cut it to a file called Server.java, to compile and run it.

    
    import java.net.*;
    import java.io.*;
    
    public class Server extends Thread {
    	ServerSocket ss = null;
    
    	public Server() {
    
    		try {
    			ss = new ServerSocket(2000);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		System.out.println("Listening on port 2000");
    		this.start();
    	}
    
    	public void run() {
    		try {
    			while(true) {
    				Socket client = ss.accept();
    				handleClient( client);
    			}
    		} catch (IOException e) {
    			System.out.println("Exception while listening for connection");
    		}
    	}
    
    	void handleClient( Socket s)
    		throws IOException
    	{
    		DataInputStream in = new DataInputStream(s.getInputStream());
    		while (true) {
    			String line = in.readLine();
    			if (line == null)
    				return;
    			System.out.println( line);
    		}
    	}
    
    	public static void main(String []args) {
    		Server s = new Server();
    	}
    }
    
    Changing Request Headers
    This example uses the URLconnection's setRequestProperty method to modify various request header settings. The C and C++ versions follow the Java API. In the example, the headers are faked to appear as if they are coming from the Netscape browser (Mozilla). By default the URL library identifies itself with its own User-Agent signature.

    Changing Request Headers
    LanguageUsage
    C
    
    (*uc->setRequestProperty)( uc, "Referer", "http://www.ist.co.uk/cgi-bin/example-form");
    (*uc->setRequestProperty)( uc, "User-Agent", ""Mozilla/4.04 [en] (X11; I; SunOS 5.5 sun4m)");
    (*uc->setRequestProperty)( uc, "Accept", "*/*");
    (*uc->setRequestProperty)( uc, "Accept-Language", "en");
    (*uc->setRequestProperty)( uc, "Accept-Charset", "iso-8859-1,*,utf-8");
    (*uc->setRequestProperty)( uc, "Content-type", "application/x-www-form-urlencoded");
         
    C++
    
    uc->setRequestProperty( "Referer", "http://www.ist.co.uk/cgi-bin/example-form");
    uc->setRequestProperty( "User-Agent", ""Mozilla/4.04 [en] (X11; I; SunOS 5.5 sun4m)");
    uc->setRequestProperty( "Accept", "*/*");
    uc->setRequestProperty( "Accept-Language", "en");
    uc->setRequestProperty( "Accept-Charset", "iso-8859-1,*,utf-8");
    uc->setRequestProperty( "Content-type", "application/x-www-form-urlencoded");
         
    Java
    
    uc.setRequestProperty( "Referer", "http://www.ist.co.uk/cgi-bin/example-form");
    uc.setRequestProperty( "User-Agent", ""Mozilla/4.04 [en] (X11; I; SunOS 5.5 sun4m)");
    uc.setRequestProperty( "Accept", "*/*");
    uc.setRequestProperty( "Accept-Language", "en");
    uc.setRequestProperty( "Accept-Charset", "iso-8859-1,*,utf-8");
    uc.setRequestProperty( "Content-type", "application/x-www-form-urlencoded");
         

    Request Type
    The Content-type property is the only one that should be regarded as compulsory. It is the responsibility of the programmer to ensure that the data is encoded using the standard www-form urlencoding.

    The URLconnection's OutputStream
    Sending data to the connection's OutputStream
    LanguageUsage
    C
    
    OutputStream * o  = (*uc->getOutputStream)( uc);
    PrintWriter  * pw = newPrintWriter( o);
    
    (*pw->println)( pw, "firstname=Fred&secondname=Bloggs");
    (*pw->delete)( pw);
         
    C++
    
    OutputStream * o  = uc->getOutputStream();
    PrintWriter  * pw = new PrintWriter( o);
    
    pw->println("firstname=Fred&secondname=Bloggs");
    delete pw;
         
    Java
    
    OutputStream  o  = uc.getOutputStream();
    PrintWriter  pw  = new PrintWriter( o);
    
    pw.println("firstname=Fred&secondname=Bloggs");
         

    USAGE

    EXAMPLES
    POSTing group data to a web server
    LanguageUsage
    C
    
    int
    exampleSendHandler( uc, csdata)
    	URLConnection * uc;
    	sc_stdcs_t * csdata;
    {
    	OutputStream * o;
    	PrintWriter  * pw;
    	MyGroup_t *   mygroup = (MyGroup_t*) csdata->group;
    
    	char buf[128];
    
    	(*uc->setRequestProperty)( uc,
    				"Content-type",
    				"application/x-www-form-urlencoded");
    
    	o  = (*uc->getOutputStream)( uc);
    	pw = newPrintWriter( o);
    
    	(void) sprintf( buf, "selection=%s&toggle=%s",
    				SC_GET(SelectionByName,mygroup->optionMenu1,
    				SC_GET(State,mygroup->toggle1));
    
    	(*pw->println)( pw, buf);
    	(*pw->delete)( pw);
    
    	return 1;
    }
         
    C++
    
    int
    exampleSendHandler( URLConnection * uc, sc_stdcs_c* csdata)
    {
    	OutputStream * o;
    	PrintWriter  * pw;
    	MyGroup_c *    mygroup = (MyGroup_c*) csdata->getGroup();
    
    	char buf[128];
    
    	uc->setRequestProperty("Content-type",
    			"application/x-www-form-urlencoded");
    
    	o  = uc->getOutputStream();
    	pw = new PrintWriter( o);
    
    	(void) sprintf( buf, "selection=%s&toggle=%s",
    				mygroup->optionMenu1->getSelectionByName(),
    				mygroup->toggle1->getState());
    
    	pw->println(buf);
    	delete pw;
    
    	return 1;
    }
         
    Java
    
    public class exampleSendHandler_c extends SCOutputDataHandler
    {
    	public void doit( URLConnection uc, SCStdCS csdata)
    		OutputStream o;
    		PrintWriter  pw; // NB use PrintStream in JDK 1.0
    		MyGroup_c    mygroup = (MyGroup_c) csdata.getGroup();
    
    		uc.setRequestProperty("Content-type",
    				"application/x-www-form-urlencoded");
    
    		o  = uc.getOutputStream();
    		pw = new PrintWriter( o);
    
    		String buf = "selection=" +
    				mygroup.optionMenu1.getSelectionByName(),
    			     "&toggle=" +
    				mygroup.toggle1.getState();
    
    		pw.println(buf);
    	}
    }
         

    SEE ALSO