Read/Write cookies for Apache Module
lazarus / 38-Networking and Web Programming
----------------------------------------------------------------------
motaz · 2012-07-01 13:15
I get mod_hello example from this site:
http://wiki.freepascal.org/FPC_and_Apache_Modules
I've expanded it to show more information from the client, but I need
to read and write cookies and custom header.
Any one can help, please
This is my modified example source:
Code: [Select]{*******************************************************
************
* Test library of the Apache Pascal Headers
*******************************************************************}
library mod_hello;
{*******************************************************************
* The mode must be objfpc on this unit because the unix code uses
* some extensions introduced on Free Pascal
*******************************************************************}
{$ifdef fpc}
{$mode objfpc}{$H+}
{$endif}
{$IFDEF WIN32}
{$DEFINE WINDOWS}
{$ENDIF}
{$define Apache2_0}
uses SysUtils, httpd {$ifndef Apache1_3}, apr{$endif};
var
test_module: module; {$ifdef Unix} public name 'test_module';
{$endif}
default_module_ptr: Pmodule;
const
MODULE_NAME = 'mod_hello.so';
{*******************************************************************
* Free Pascal only supports exporting variables on Windows
*******************************************************************}
{-$ifdef WINDOWS}
exports
test_module name 'test_module';
{-$endif}
{*******************************************************************
* Handles apache requests
*******************************************************************}
function DefaultHandler(r: Prequest_rec): Integer; cdecl;
var
RequestedHandler: string;
Buf: PChar;
NumRead: Integer;
Line: string;
Head: Papr_array_header_t;
Access: Phtaccess_result;
begin
RequestedHandler := r^.handler;
{ We decline to handle a request if hello-handler is not the value
of r->handler }
if not SameText(RequestedHandler, 'testapache-handler') then
begin
Result := DECLINED;
Exit;
end;
{ The following line just prints a message to the errorlog }
ap_log_error(MODULE_NAME, 54, APLOG_NOERRNO or APLOG_NOTICE,
{$ifndef Apache1_3}0,{$endif} r^.server,
'mod_hello: %s', [PChar('Before content is output')]);
{ We set the content type before doing anything else }
{$ifdef Apache1_3}
r^.content_type := 'text/html';
// ap_send_http_header(r);
{$else}
ap_set_content_type(r, 'text/html');
{$endif}
{ If the request is for a header only, and not a request for
the whole content, then return OK now. We don't have to do
anything else. }
if (r^.header_only <> 0) then
begin
Result := OK;
Exit;
end;
{ Now we just print the contents of the document using the
ap_rputs and ap_rprintf functions. More information about
the use of these can be found in http_protocol.inc }
ap_rputs('' + LineEnding, r);
ap_rputs('
' + LineEnding, r);
ap_rputs('Hello There' + LineEnding, r);
ap_rputs('' + LineEnding, r);
ap_rputs('' + LineEnding ,r);
ap_rputs('Hello world
' + LineEnding, r);
ap_rputs('This is the first Apache Module working with the new
binding from Free Pascal' + LineEnding, r);
ap_rputs(PChar('
Time: ' + TimeToStr(Now) +
''), r);
ap_rputs(PChar('
' + IntToStr(Random(100)) +
''), r);
// ap_rprintf(r, '
A sample line generated by ap_rprintf
' +
LineEnding, []);
ap_rputs(PChar('
Server version : ' + ap_get_server_version +
'
'), r);
ap_rputs(PChar('query=' + r^.args + ''), r);
ap_rputs(PChar('
Hostname=' + r^.hostname +
''), r);
ap_rputs(PChar('
Method=' + r^.method +
''), r);
ap_rputs(PChar('
the request=' +
r^.the_request + ''), r);
ap_rputs(PChar('
Protocol=' + r^.protocol +
''), r);
ap_rputs(PChar('
Content Type=' +
r^.content_encoding + ''), r);
ap_rputs(PChar('
Encoding=' +
r^.content_encoding + ''), r);
ap_rputs(PChar('
Auth type=' + r^.ap_auth_type
+ ''), r);
ap_rputs(PChar('
User=' + r^.user +
''), r);
ap_rputs(PChar('
Status Line=' +
r^.status_line + ''), r);
ap_rputs(PChar('
VList Validator=' +
r^.vlist_validator + ''), r);
ap_rputs(PChar('
URI=' + r^.uri+ ''),
r);
ap_rputs(PChar('
Range=' + r^.range+
''), r);
ap_rputs(PChar('
Path Info=' + r^.path_info+
''), r);
ap_rputs(PChar('
Canonical Filename=' +
r^.canonical_filename+ ''), r);
ap_rputs(PChar('
Handler=' + r^.handler +
''), r);
ap_rputs(PChar('
show_mpm=' + ap_show_mpm +
''), r);
ap_rputs(PChar('
auth_type=' + ap_auth_type(r)
+ ''), r);
ap_rputs(PChar('
auth_name=' + ap_auth_name(r)
+ ''), r);
ap_rputs(PChar('
server description ' +
ap_get_server_description + ''), r);
ap_rputs(PChar('
remote longname=' +
ap_get_remote_logname(r) + ''), r);
ap_rputs(PChar('
psignature=' +
ap_psignature('', r) + ''), r);
ap_rputs(PChar('
make etag=' + ap_make_etag(r,
1) + ''), r);
ap_rputs(PChar('
Status=' +
IntToStr(r^.status) + ''), r);
head:= apr_table_elts(r^.subprocess_env);
ap_rputs(PChar('
Header=' + Copy(head^.elts,
1, head^.elt_size) + ''), r);
// Retrieve posted data
if (r^.method = 'POST') then
begin
ap_setup_client_block(r, REQUEST_CHUNKED_ERROR);
ap_rputs('contents:', r);
Buf:= StrAlloc(1024);
repeat
NumRead:= ap_get_client_block(r, Buf, 1024);
ap_rputs(PChar(Copy(Buf, 0, NumRead)), r);
until NumRead = 0;
end;
{ We can either return OK or DECLINED at this point. If we return
* OK, then no other modules will attempt to process this
request }
ap_rputs('' + LineEnding, r);
Result := OK;
end;
{*******************************************************************
* Registers the hooks
*******************************************************************}
{$ifdef apache1_3}
procedure hw_init(s: PServer_rec; p: PPool); cdecl;
begin
end;
var
hw_handlers: array[0..0] of handler_rec =
(
(content_type: 'hw_app'; handler: @DefaultHandler)
);
{$else}
procedure RegisterHooks(p: Papr_pool_t); cdecl;
begin
ap_hook_handler(@DefaultHandler, nil, nil, APR_HOOK_MIDDLE);
end;
{$endif}
{*******************************************************************
* Library initialization code
*******************************************************************}
begin
default_module_ptr := @test_module;
FillChar(default_module_ptr^, SizeOf(default_module_ptr^), 0);
{$ifdef apache1_3}
STANDARD_MODULE_STUFF(test_module);
with test_module do
begin
name := MODULE_NAME;
init := @hw_init;
handlers := hw_handlers;
end;
{$else}
STANDARD20_MODULE_STUFF(test_module);
with test_module do
begin
name := MODULE_NAME;
register_hooks := @RegisterHooks;
end;
{$endif}
end.
----------------------------------------------------------------------
Zaher · 2012-07-01 21:36
cookies is part of http header, you can send it when send the header
to set it you can add to the header Set-Cookie
you can use apr_table_set(r->headers_out, "Set-Cookie", 'your
values');
also you read it by apr_table_get(r->headers_in <- notice it in not
out
look at fpapache.pas and find this functions
http://en.wikipedia.org/wiki/HTTP_cookie
----------------------------------------------------------------------
motaz · 2012-07-02 06:43
Thank you very much, finally it works. I spent a lot of time trying to
read/read cookies.
Here are the tested procedures:
Code: [Select] // Read cookies:
ap_rputs(PChar('
Cookies: ' +
apr_table_get(r^.headers_in, 'COOKIE') + ''), r);
// Set cookies:
apr_table_set(r^.headers_out, 'Set-Cookie', 'sessionid=120');
I also can read/write FreeSpider's CGI cookies in the same server from
this Apache Module sample
Another question: how to read user agent, example of reading user
agent in FreeSpider:
Code: [Select]Your browser is: Mozilla/5.0 (X11; Ubuntu; Linux i686;
rv:13.0) Gecko/20100101 Firefox/13.0.1
----------------------------------------------------------------------
motaz · 2012-07-02 07:39
I encounters apache crash in Ubuntu 12.04 at the first call sometimes
for that module. Ubuntu displays Bug report message, but apache is
working fine after that, I didn't get this error again until I
rebooted my computer. This error seems like access violation. Ubuntu
12.04 has this problem with a lot of applications.
Is it something that I should worry about?
I'm using FPC 2.6.0, Lazarus 0.9.31
Complete sample library project is attached
----------------------------------------------------------------------
Zaher · 2012-07-02 15:56
User agent same behavior
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
for crash, idk, but look at bottom of fpapache.pas
Code: [Select]Initialization
BeginThread(@__dummythread);//crash prevention for simultaneous
requests
InitApache;