<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>src/iserve_socket.hrl</filename>
    </added>
    <added>
      <filename>test/iserve_test3.erl</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -2,13 +2,13 @@
 ERL=erl
 
 .PHONY: all src test clean
-all: src
+all: src test
 
 src:
 	cd src &amp;&amp; $(ERL) -make all
 
 test:
-	cd test &amp;&amp; $(ERL) -make all
+	cd test &amp;&amp; $(ERL) -pa ./ebin -make all
 
 clean:
 	cd ebin &amp;&amp; rm -f *.beam</diff>
      <filename>Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -3,13 +3,15 @@
 
 % This record characterises the connection from the browser to our server
 % it is intended to be a consistent view derived from a bunch of different headers
--record(req, {connection=keep_alive,	        % keep_alive | close
-	      content_length,                   % Integer
-	      vsn,                              % {Maj,Min}
-	      method,                           % 'GET'|'POST'
-	      uri,				% Truncated URI /index.html
-              args=&quot;&quot;,                          % Part of URI after ?
-	      headers,				% [{Tag, Val}]
-	      body = &lt;&lt;&gt;&gt;}).			% Content Body
+-record(req, {
+          connection=keep_alive,	    % keep_alive | close
+          content_length,                   % Integer
+          vsn,                              % {Maj,Min}
+          method,                           % 'GET'|'POST'
+          uri,				    % Truncated URI /index.html
+          args=&quot;&quot;,                          % Part of URI after ?
+          headers,			    % [{Tag, Val}]
+          body = &lt;&lt;&gt;&gt; 			    % Content Body
+         }).
 
 -endif.</diff>
      <filename>include/iserve.hrl</filename>
    </modified>
    <modified>
      <diff>@@ -6,15 +6,41 @@
 -module(iserve).
 
 -include(&quot;../include/iserve.hrl&quot;).
+-include(&quot;iserve_socket.hrl&quot;).
+
+-export([behaviour_info/1]).
 
 %% API to use from iserver_socket-behavior-callback modules.
 -export([reply_ok/2, reply_not_modified/1, 
 	 reply_not_found/2, reply_redirect/2, 
-	 reply_raw/3]).
+	 reply_raw/3, no_reply/0,
+         send_reply/3, send_reply/4,
+         status_code/1]).
+
 -export([req_method/1, req_content_length/1, 
 	 req_uri/1, req_headers/1, 
 	 req_body/1, req_http_version/1]).
 
+-export([c_sock/1, c_port/1, c_peer_addr/1,
+         c_peer_port/1, c_cb_mod/1, c_cb_data/1]).
+
+     
+behaviour_info(callbacks) -&gt;
+    [{iserve_request,2}];
+behaviour_info(_Other) -&gt;
+    undefined.
+
+
+send_reply(C, StatusCode, Headers) -&gt;
+    iserve_socket:send_reply(C, StatusCode, Headers).
+
+send_reply(C, StatusCode, Headers, Body) -&gt;
+    iserve_socket:send_reply(C, StatusCode, Headers, Body).
+
+
+no_reply() -&gt;
+    no_reply.
+
 reply_ok(Headers, Body)                              -&gt;
     response(ok, Headers, Body).
 reply_not_modified(Headers)                          -&gt;
@@ -49,15 +75,18 @@ status_code(internal_server_error) -&gt; 500;
 status_code(service_unavailable)   -&gt; 503.
 
 
-req_method(#req{method=Method}) -&gt;
-    Method.
-req_content_length(#req{content_length=Len}) -&gt;
-    Len.
-req_uri(#req{uri=URI}) -&gt;
-    URI.
-req_headers(#req{headers=Hs}) -&gt;
-    Hs.
-req_body(#req{body=Data}) -&gt;
-    Data.
-req_http_version(#req{vsn=Version}) -&gt;
-    Version.
+req_method(#req{method=Method})              -&gt;    Method.
+req_content_length(#req{content_length=Len}) -&gt;    Len.
+req_uri(#req{uri=URI})                       -&gt;    URI.
+req_headers(#req{headers=Hs})                -&gt;    Hs.
+req_body(#req{body=Data})                    -&gt;    Data.
+req_http_version(#req{vsn=Version})          -&gt;    Version.
+
+
+c_sock(#c{sock = Sock})               -&gt; Sock.
+c_port(#c{port = Port})               -&gt; Port.
+c_peer_addr(#c{peer_addr = PeerAddr}) -&gt; PeerAddr.
+c_peer_port(#c{peer_port = PeerPort}) -&gt; PeerPort.
+c_cb_mod(#c{cb_mod = CbMod})          -&gt; CbMod.
+c_cb_data(#c{cb_data = CbData})       -&gt; CbData.
+     </diff>
      <filename>src/iserve.erl</filename>
    </modified>
    <modified>
      <diff>@@ -2,27 +2,37 @@
 
 -behaviour(gen_server).
 
--export([start/2, 
-         start_link/2, 
-         create/2]).
+-export([start/2, start/3
+         ,start_link/2, start_link/3
+         ,create/2
+        ]).
 
 %% gen_server callbacks
 -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
          code_change/3]).
 
--record(state, {listen_socket,
-                port,
-                acceptor,
-                cb_mod}).
+-record(state, {
+          listen_socket,
+          port,
+          acceptor,
+          cb_mod,
+          cb_data 
+         }).
 
 %%--------------------------------------------------------------------
 start(Port, CbMod) when is_integer(Port), is_atom(CbMod) -&gt;
+    start(Port, CbMod, undef).
+
+start(Port, CbMod, CbData) when is_integer(Port), is_atom(CbMod) -&gt;
     Name = list_to_atom(lists:flatten(io_lib:format(&quot;iserve_~w&quot;, [Port]))),
-    gen_server:start({local, Name}, ?MODULE, [Port,CbMod], []).
+    gen_server:start({local, Name}, ?MODULE, [Port,CbMod,CbData], []).
 
 start_link(Port, CbMod) when is_integer(Port), is_atom(CbMod) -&gt;
+    start_link(Port, CbMod, undef).
+
+start_link(Port, CbMod, CbData) when is_integer(Port), is_atom(CbMod) -&gt;
     Name = list_to_atom(lists:flatten(io_lib:format(&quot;iserve_~w&quot;, [Port]))),
-    gen_server:start_link({local, Name}, ?MODULE, [Port,CbMod], []).
+    gen_server:start_link({local, Name}, ?MODULE, [Port,CbMod,CbData], []).
 
 %% Send message to cause a new acceptor to be created
 create(ServerPid, Pid) -&gt;
@@ -30,7 +40,7 @@ create(ServerPid, Pid) -&gt;
 
 
 %% Called by gen_server framework at process startup. Create listening socket
-init([Port,CbMod]) -&gt;
+init([Port,CbMod,CbData]) -&gt;
     process_flag(trap_exit, true),
     case gen_tcp:listen(Port,[binary, {packet, http},
                               {reuseaddr, true},
@@ -38,11 +48,12 @@ init([Port,CbMod]) -&gt;
                               {backlog, 30}]) of
 	{ok, Listen_socket} -&gt;
             %%Create first accepting process
-	    Pid = iserve_socket:start_link(CbMod, self(), Listen_socket, Port),
+	    Pid = iserve_socket:start_link(CbMod, CbData, self(), Listen_socket, Port),
 	    {ok, #state{listen_socket = Listen_socket,
                         port          = Port,
 			acceptor      = Pid,
-                        cb_mod        = CbMod}};
+                        cb_mod        = CbMod,
+                        cb_data       = CbData}};
 	{error, Reason} -&gt;
 	    {stop, Reason}
     end.
@@ -54,8 +65,11 @@ handle_call(_Request, _From, State) -&gt;
 
 %% Called by gen_server framework when the cast message from create/2 is received
 handle_cast({create, _Pid}, #state{listen_socket = Listen_socket} = State) -&gt;
-    New_pid = iserve_socket:start_link(State#state.cb_mod, self(), 
-                                       Listen_socket, State#state.port),
+    New_pid = iserve_socket:start_link(State#state.cb_mod,
+                                       State#state.cb_data, 
+                                       self(), 
+                                       Listen_socket, 
+                                       State#state.port),
     {noreply, State#state{acceptor=New_pid}};
 
 handle_cast(_Msg, State) -&gt;
@@ -68,8 +82,11 @@ handle_info({'EXIT', Pid, normal}, #state{acceptor=Pid} = State) -&gt;
 %% The current acceptor has died, wait a little and try again
 handle_info({'EXIT', Pid, _Abnormal}, #state{acceptor=Pid} = State) -&gt;
     timer:sleep(2000),
-    iserve_socket:start_link(State#state.cb_mod, self(), 
-                             State#state.listen_socket, State#state.port),
+    iserve_socket:start_link(State#state.cb_mod, 
+                             State#state.cb_data, 
+                             self(), 
+                             State#state.listen_socket, 
+                             State#state.port),
     {noreply, State};
 
 handle_info(_Info, State) -&gt;</diff>
      <filename>src/iserve_server.erl</filename>
    </modified>
    <modified>
      <diff>@@ -1,32 +1,29 @@
 -module(iserve_socket).
 
--export([start_link/4]).
+-export([start_link/5
+         ,send_reply/3, send_reply/4
+        ]).
 
 -export([init/1]).
 
 %% TODO: Remove me
--compile(export_all).
+%%-compile(export_all).
 
 -include(&quot;../include/iserve.hrl&quot;).
+-include(&quot;iserve_socket.hrl&quot;).
 
 -define(not_implemented_501, &quot;HTTP/1.1 501 Not Implemented\r\n\r\n&quot;).
 -define(forbidden_403, &quot;HTTP/1.1 403 Forbidden\r\n\r\n&quot;).
 -define(not_found_404, &quot;HTTP/1.1 404 Not Found\r\n\r\n&quot;).
 
--record(c,  {sock,
-             port,
-             peer_addr,
-             peer_port,
-             cb_mod      % callback module M:iserve_request(#req{})
-	     }).
 
 -define(server_idle_timeout, 30*1000).
 
-start_link(CbMod, ListenPid, ListenSocket, ListenPort) -&gt;
+start_link(CbMod, CbData, ListenPid, ListenSocket, ListenPort) -&gt;
     proc_lib:spawn_link(?MODULE, init, 
-                        [{CbMod, ListenPid, ListenSocket, ListenPort}]).
+                        [{CbMod, CbData, ListenPid, ListenSocket, ListenPort}]).
 
-init({CbMod, Listen_pid, Listen_socket, ListenPort}) -&gt;
+init({CbMod, CbData, Listen_pid, Listen_socket, ListenPort}) -&gt;
     case catch gen_tcp:accept(Listen_socket) of
 	{ok, Socket} -&gt;
             %% Send the cast message to the listener process to create a new acceptor
@@ -36,7 +33,8 @@ init({CbMod, Listen_pid, Listen_socket, ListenPort}) -&gt;
                    port      = ListenPort,
                    peer_addr = Addr,
                    peer_port = Port,
-                   cb_mod    = CbMod},
+                   cb_mod    = CbMod,
+                   cb_data   = CbData},
 	    request(C, #req{}); %% Jump to state 'request'
 
 	Else -&gt;
@@ -163,7 +161,10 @@ handle_post(C, #req{connection = Conn} = Req) -&gt;
 
 call_mfa(C, Req) -&gt;
     Mod = C#c.cb_mod,
-    case catch Mod:iserve_request(Req) of
+    case catch Mod:iserve_request(C, Req) of
+        no_reply -&gt;
+            ok;
+
         {'EXIT', Reason} -&gt;
             io:format(&quot;Worker Crash = ~p~n&quot;,[Reason]),
             exit(normal);
@@ -175,26 +176,29 @@ call_mfa(C, Req) -&gt;
 	%% A basic identity http response.
         {respond, StatusCode, Headers0, Body} -&gt;
             Headers = add_content_length(Headers0, Body),
-            Enc_headers = enc_headers(Headers),
-	    Enc_status = enc_status(StatusCode),
-            Resp = [&lt;&lt;&quot;HTTP/1.1 &quot;&gt;&gt;, Enc_status, &lt;&lt;&quot;\r\n&quot;&gt;&gt;,
-                    Enc_headers,
-                    &lt;&lt;&quot;\r\n&quot;&gt;&gt;,
-                    Body],
-            send(C, Resp);
+            send_reply(C, StatusCode, Headers, Body);
 	
 	%% Chunked transfer-encoding for streaming output
 	{stream, StatusCode, Headers0, Pid, Subscribe} -&gt;
 	    TE = {'Transfer-Encoding', &quot;chunked&quot;},
 	    Headers1 = [TE |Headers0],
-            Enc_headers = enc_headers(Headers1),
-	    Enc_status = enc_status(StatusCode),
-            Resp = [&lt;&lt;&quot;HTTP/1.1 &quot;&gt;&gt;, Enc_status, &lt;&lt;&quot;\r\n&quot;&gt;&gt;,
-                    Enc_headers,
-                    &lt;&lt;&quot;\r\n&quot;&gt;&gt;],
-	    send(C, Resp),
+            send_reply(C, StatusCode, Headers1),
 	    send_chunked(C, Pid, Subscribe)
     end.
+
+%%% Part of the exported API.
+send_reply(C, StatusCode, Headers) -&gt;
+    send_reply(C, StatusCode, Headers, &quot;&quot;).
+
+send_reply(C, StatusCode, Headers, Body) -&gt;
+    Enc_headers = enc_headers(Headers),
+    Enc_status = enc_status(StatusCode),
+    Resp = [&lt;&lt;&quot;HTTP/1.1 &quot;&gt;&gt;, Enc_status, &lt;&lt;&quot;\r\n&quot;&gt;&gt;,
+            Enc_headers,
+            &lt;&lt;&quot;\r\n&quot;&gt;&gt;,
+            Body],
+    send(C, Resp).
+
        
 add_content_length(Headers, Body) -&gt;
     case lists:keysearch('Content-Length', 1, Headers) of</diff>
      <filename>src/iserve_socket.erl</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-{['iserve_test', 'iserve_test2'],
- [{outdir,&quot;../ebin&quot;},debug_info]}.
+{['iserve_test', 'iserve_test2', 'iserve_test3'],
+ [{outdir,&quot;../ebin&quot;},{pa,&quot;../ebin&quot;},debug_info]}.
 
 </diff>
      <filename>test/Emakefile</filename>
    </modified>
    <modified>
      <diff>@@ -3,7 +3,7 @@ ERL=erl
 
 .PHONY: all src clean
 all:
-	$(ERL) -make all
+	$(ERL) -pa ../ebin -make all
 
 clean:
 	rm -f ../ebin/*.beam</diff>
      <filename>test/Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,13 +1,15 @@
 -module(iserve_test).
--export([start/1, iserve_request/1]).
+-export([start/1, iserve_request/2]).
 -include(&quot;../include/iserve.hrl&quot;).
 
+-behaviour(iserve).
+
 
 start(Port) -&gt;
     iserve_server:start(Port, ?MODULE).
 
 
-iserve_request(Req) -&gt;
+iserve_request(_C, Req) -&gt;
     error_logger:info_report(
       lists:zip(record_info(fields, req), tl(tuple_to_list(Req)))),
     </diff>
      <filename>test/iserve_test.erl</filename>
    </modified>
    <modified>
      <diff>@@ -1,13 +1,15 @@
 -module(iserve_test2).
--export([start/1, iserve_request/1]).
+-export([start/1, iserve_request/2]).
 -include(&quot;../include/iserve.hrl&quot;).
 
+-behaviour(iserve).
+
 
 start(Port) -&gt;
     iserve_server:start(Port, ?MODULE).
 
 
-iserve_request(Req) -&gt;
+iserve_request(_C, Req) -&gt;
     error_logger:info_report(
       lists:zip(
 	record_info(fields, req), </diff>
      <filename>test/iserve_test2.erl</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>9f87781d2fac11f541a3dac7a1110fa1a37cf810</id>
    </parent>
  </parents>
  <author>
    <name>Torbjorn Tornkvist</name>
    <email>tobbe@tornkvist.org</email>
  </author>
  <url>http://github.com/noss/iserve/commit/31f06af72bc9a86c0d9d884b064262889016dceb</url>
  <id>31f06af72bc9a86c0d9d884b064262889016dceb</id>
  <committed-date>2007-11-07T14:30:54-08:00</committed-date>
  <authored-date>2007-11-07T14:30:54-08:00</authored-date>
  <message>Modifying iserve so that use of ifile:sendfile is possible.</message>
  <tree>4567d4d060c16012f2f4b0069c184cd4d2db6183</tree>
  <committer>
    <name>Torbjorn Tornkvist</name>
    <email>tobbe@tornkvist.org</email>
  </committer>
</commit>
