----------------------------------------------------------------
BEFORE YOU POST, search the faq at <http://java.apache.org/faq/>
WHEN YOU POST, include all relevant version numbers, log files,
and configuration files. Don't make us guess your problem!!!
----------------------------------------------------------------
----------
X-Sun-Data-Type: text
X-Sun-Data-Description: text
X-Sun-Data-Name: text
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 40
Hi Lucas,
We've had the same problem. Now I have implemented ajpv12, without authentication,
in our script language. It worked fine with Apache/JServ1.1, though I won't make
any guarantees, because everything is derived from packet sniffs.
A major caveat is that your data structure into which you write this request before
sending it over the socket must be able to handle nullbytes, so a string won't do.
We used our datatype "stream", similar to Java streams.
A call to the implemented function looks like this:
res = jserv_request(ajpv12_gen_request("POST",
gen_request_entity(),
"csg",
"ergon.ec.servlets.HelloServlet",
env.REMOTE_HOST,
env.REMOTE_ADDR,
env.SERVER_NAME,
env.SERVER_PORT,
env.SERVER_PROTOCOL,
env.DOCUMENT_ROOT,
"text/plain",
"http"));
There is much documentation in the code, so this is a good starter.
Andy
> Does anyone know of a way to hook a java client directly to jserv, without going through
> the apache webserver? I have a project, open source but too embryonic to release yet,
> that depends on having a servlet engine available.
>
> This is equivalent to asking whether anyone has implemented the jserv protocol (on the
> client side) in Java.
>
> Thanks in advance. And apologies if this is in the FAQ and I missed it.
>
> - Lucas Gonze
----------
X-Sun-Data-Type: default
X-Sun-Data-Description: default
X-Sun-Data-Name: ajpv12_noauth.eval
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 330
#START
FILE
ajpv12_noauth.eval
MODULE
ec_xml
SUMMARY
ApacheJserv protocol v1.2, without authentication
DESCRIPTION
NOFILL
@author Andy Deller
@created_on 20000309
@updated_on
@bugs
@to do:
- add parameter string for GET
- urlencode this parameter string
- content type (with POST)? so far text/plain
FILL
ApacheJserv protocol v1.2, without authentication. The
request format has been derived from sniffed packets sent
from Apache to JServ. So some elements are present without
explanations.
The protocol begins with '01'. Every entry, like SERVER_NAME or
REQUEST_METHOD begins with a '00', followed by its length,
coded in binary. Sometimes, six 'ff' are used as separators.
A request is composed of an HTTP and a JServ-specific part.
The latter one is separated from the HTTP request with a
'03', which is the delimiter for JServ request entries.
The request is ended with '04'. If the REQUEST_METHOD is
"POST", the parameters are appended to this '04', if it
is "GET", the parameters are inserted in the HTTP part.
Also important: the content type should never be set
to "text/plain", except for very small requests. Otherwise,
JServ will block and hang reading the request.
#END
global ajpv12_global_ff; /*binary ff (int value 255)*/
global ajpv12_global_four_ff; /*four ff in a row*/
global ajpv12_global_six_ff; /*six ff in a row*/
/* PROCEDURE
Generate an apjv12 request, based on HTTP/1.0
Every parameter is checked for NULL; if it is null, some default
replacement is made.
NOFILL
@param request_method: HTTP request method ("GET" or "POST")
@param request_entity: request parameters in plain text. formatted in
#param content_type, in the form 'param0=value0¶m1=value1&...
¶mn-1=valuen-1', WITHOUT the "?"!
@param servlet_zone: name of the zone to access. Example: for the URL
HOST:8024/csg/servlet/ergon.ec.servlets.HelloServlet, this
would be "csg".
@param servlet_name: name of the servlet to access. Example: for the
URL above, this would be "HelloServlet".
@param remote_host: name of the server sending the request;
in most cases, "localhost" should work fine.
@param remote_addr: IP address of the server. Doesn't seem to have
an influence.
@param server_name: name of the server sending the request
@param server_port: port of the server sending the request,
NOT of the port of JServ. Doesn't seem to have any influence.
@param server_protocol: protocol the server uses, e.g. "HTTP/1.0"
@param document_root: document root of the server sending the
request. Doesn't seem to have an influence.
@param content_type: mime type of request_entity; default is
"plain/text"
@param http_prefix: "http" or "https"; default is "http"
@return stream containing the request
FILL
*/
func ajpv12_gen_request (request_method, request_entity, servlet_zone,
servlet_name, remote_host, remote_addr, server_name, server_port,
server_protocol, document_root, content_type, http_prefix)
{
lrequest_method;
req; /*request stream*/
ajpv12_global_ff = char(255);
ajpv12_global_four_ff = ajpv12_global_ff + ajpv12_global_ff
+ ajpv12_global_ff + ajpv12_global_ff;
ajpv12_global_six_ff = ajpv12_global_four_ff
+ ajpv12_global_ff + ajpv12_global_ff;
lrequest_method = (isnull(request_method)? "GET": request_method);
req = stream("");
stream_append_byte(req, 1); /*begin request*/
ajpv12_gen_http_part(req, lrequest_method, request_entity, servlet_zone,
servlet_name, remote_host, remote_addr, server_name, server_port,
server_protocol, document_root);
ajpv12_gen_jserv_part(req, server_port, lrequest_method,
request_entity, content_type, http_prefix);
return req;
}/*ajpv12_gen_request()*/
/* PROCEDURE
Append HTTP/1.0 request part to stream
NOFILL
@param req: stream to add the HTTP request to
@param request_method: HTTP request method ("GET" or "POST")
@param request_entity: request parameters urlencoded
@param servlet_zone: name of the zone to access.
@param servlet_name: name of the servlet to access.
@param remote_host: name of the server sending the request;
@param remote_addr: IP address of the server.
@param server_name: name of the server sending the request
@param server_port: port of the server sending the request
@param server_protocol: protocol the server uses, e.g. "HTTP/1.0"
@param document_root: document root of the server sending the request
@return implicitly req: instream with the HTTP request part appended
FILL
*/
func ajpv12_gen_http_part (req, request_method, request_entity, servlet_zone,
servlet_name, remote_host, remote_addr, server_name, server_port,
server_protocol, document_root)
{
/*path of servlet; in example above: /csg/servlet...HelloServlet*/
lscript_name = "n/a";
lserver_name = "localhost";
lserver_port = "8080";
lserver_software = "n/a";
lserver_name = (isnull(server_name)? lserver_name: server_name);
lserver_port = (isnull(server_port)? "8080": server_port);
ajpv12_append_entry(req, request_method);
entry = (isnull(servlet_zone)? "root": servlet_zone);
ajpv12_append_entry(req, entry);
entry = (isnull(servlet_name)? "Hello": servlet_name);
ajpv12_append_entry(req, entry);
ajpv12_append_entry(req, lserver_name);
entry = (isnull(document_root)? "dr": document_root);
ajpv12_append_entry(req, entry);
if(!isnull(request_entity) && request_method=="GET") {
stream_append_string(req, ajpv12_global_four_ff);
ajpv12_append_entry(req, request_entity);
}
stream_append_string(req, ajpv12_global_six_ff);
entry = (isnull(remote_addr)? "127.0.0.1": remote_addr); /*localhost*/
ajpv12_append_entry(req, entry);
stream_append_string(req, ajpv12_global_six_ff);
ajpv12_append_entry(req, lserver_port);
ajpv12_append_entry(req, request_method);
ajpv12_append_entry(req, lscript_name);
ajpv12_append_entry(req, lscript_name);
ajpv12_append_entry(req, lscript_name);
ajpv12_append_entry(req, lserver_name);
ajpv12_append_entry(req, lserver_port);
entry = (isnull(server_protocol)? "HTTP/1.0": server_protocol);
ajpv12_append_entry(req, entry);
stream_append_byte(req, 0);
stream_append_byte(req, 0);
ajpv12_append_entry(req, lserver_software);
stream_append_string(req, ajpv12_global_six_ff);
}/*ajpv12_gen_http_part()*/
/* PROCEDURE
Append JServ part of request to stream
NOFILL
@param req: stream to add the string to
@param server_port: port of the server sending the request
@param request_method: HTTP method; currently supported are "GET"
and "POST"
@param request_entity: request parameters urlencoded
@param content_type: mime type of request_entity
@param http_prefix: "http" or "https"; default is "http"
@return implicitly req: instream with the JServ request part appended
FILL
*/
func ajpv12_gen_jserv_part (req, server_port, request_method, request_entity,
content_type, http_prefix)
{
stream_append_byte(req, 3);
ajpv12_append_entry(req, "Accept");
entry = env.HTTP_ACCEPT;
entry = (isnull(entry)? "image/gif, image/jpeg": entry);
ajpv12_append_entry(req, entry);
stream_append_byte(req, 3);
ajpv12_append_entry(req, "Accept-Charset");
entry = env.HTTP_ACCEPT_CHARSET;
entry = (isnull(entry)? "iso-8859-1": entry);
ajpv12_append_entry(req, entry);
stream_append_byte(req, 3);
ajpv12_append_entry(req, "Accept-Encoding");
entry = env.HTTP_ACCEPT_ENCODING;
entry = (isnull(entry)? "n/a": entry);
ajpv12_append_entry(req, entry);
stream_append_byte(req, 3);
ajpv12_append_entry(req, "Accept-Language");
entry = env.HTTP_ACCEPT_LANGUAGE;
entry = (isnull(entry)? "n/a": entry);
ajpv12_append_entry(req, entry);
stream_append_byte(req, 3);
ajpv12_append_entry(req, "Connection");
entry = env.HTTP_CONNECTION;
entry = (isnull(entry)? "n/a": entry);
ajpv12_append_entry(req, entry);
if(request_method == "GET")
ajpv12_gen_jserv_get_part(req);
else
ajpv12_gen_jserv_post_part(req, request_entity, content_type,
server_port, http_prefix);
}/*ajpv12_gen_jserv_part()*/
/* PROCEDURE
Append GET part of JServ part of request to stream
NOFILL
@param req: stream to add the string to
@return implicitly req: instream with the JServ request part appended
FILL
*/
func ajpv12_gen_jserv_get_part (req)
{
stream_append_byte(req, 3);
ajpv12_append_entry(req, "Host");
entry = getenv("HOST");
entry = (isnull(entry)? "n/a:": entry + ":");
entry = entry + (isnull(server_port)? "n/a": server_port);
ajpv12_append_entry(req, entry);
stream_append_byte(req, 3);
ajpv12_append_entry(req, "Pragma");
entry = (isnull(env.HTTP_PRAGMA)? "no-cache": env.HTTP_PRAGMA);;
ajpv12_append_entry(req, entry);
stream_append_byte(req, 3);
ajpv12_append_entry(req, "User-Agent");
entry = env.HTTP_USER_AGENT;
entry = (isnull(entry)? "n/a": entry);
ajpv12_append_entry(req, entry);
stream_append_byte(req, 4); /*end of request header*/
}/*ajpv12_gen_jserv_get_part()*/
/* PROCEDURE
Append POST part of JServ part of request to stream
NOFILL
@param req: stream to add the string to
@param request_entity: request parameters, encoded in #param
content_type
@param content_type: mime type of request_entity
@param server_port: port of the server sending the request
@param http_prefix: "http" or "https"; default is "http"
@return implicitly req: instream with the JServ request part appended
FILL
*/
func ajpv12_gen_jserv_post_part (req, request_entity, content_type,
server_port, http_prefix)
{
/*if no request parameters are given a "=' must be appended*/
lrequest_entity = (isnull(request_entity)? "=": request_entity);
lserver_name_port = "";
lserver_name_port = lserver_name_port +
(isnull(h = getenv("HOST"))? "n/a:": h + ":");
lserver_name_port = lserver_name_port
+ (isnull(server_port)? "n/a": server_port);
printf("ajpv12_gen_jserv_post_part: entering\n");
stream_append_byte(req, 3);
ajpv12_append_entry(req, "Content-length");
ajpv12_append_entry(req, string(length(lrequest_entity)));
stream_append_byte(req, 3);
ajpv12_append_entry(req, "Content-type");
entry = (isnull(content_type)? "application/x-www-form-urlencoded": content_type);
ajpv12_append_entry(req, entry);
stream_append_byte(req, 3);
ajpv12_append_entry(req, "Host");
ajpv12_append_entry(req, lserver_name_port);
stream_append_byte(req, 3);
ajpv12_append_entry(req, "Referer");
entry = (isnull(http_prefix)? "http://": http_prefix + "://");
entry = entry + lserver_name_port;
ajpv12_append_entry(req, entry);
stream_append_byte(req, 3);
ajpv12_append_entry(req, "User-Agent");
entry = env.HTTP_USER_AGENT;
entry = (isnull(entry)? "n/a": entry);
ajpv12_append_entry(req, entry);
stream_append_byte(req, 4); /*end of request header*/
stream_append_string(req, lrequest_entity); /*no start||end byte!*/
}/*ajpv12_gen_jserv_post_part()*/
/* PROCEDURE
Adds a nullbyte, the length of the entry and the entry to
the stream
NOFILL
@param req: stream to add the string to
@param entry: string to add to the stream
@return req + nullbyte + length(binary) + entry
FILL
*/
func ajpv12_append_entry (req, entry)
{
stream_append_byte(req, 0);
stream_append_string(req, int_to_hex_bin(length(entry)));
stream_append_string(req, entry);
}
--
--------------------------------------------------------------
Please read the FAQ! <http://java.apache.org/faq/>
To subscribe: [EMAIL PROTECTED]
To unsubscribe: [EMAIL PROTECTED]
Archives and Other: <http://java.apache.org/main/mail.html>
Problems?: [EMAIL PROTECTED]