1 {
2  httpd.pas
3 
4  Copyright (C) 2006 Felipe Monteiro de Carvalho
5  (based on the Apache 2.0.58 headers)
6  Updated by Attila Borka in 2012 for the Apache 2.4.3 headers
7 
8  This unit is a pascal binding for the Apache 2.4.3 headers.
9  The headers were released under the following copyright:
10 }
11 { Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements.  See the NOTICE file distributed with
13  * this work for additional information regarding copyright ownership.
14  * The ASF licenses this file to You under the Apache License, Version 2.0
15  * (the "License"); you may not use this file except in compliance with
16  * the License.  You may obtain a copy of the License at
17  *
18  *     http://www.apache.org/licenses/LICENSE-2.0
19  *
20  * Unless required by applicable law or agreed to in writing, software
21  * distributed under the License is distributed on an "AS IS" BASIS,
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23  * See the License for the specific language governing permissions and
24  * limitations under the License.
25   }
26 
27 {*
28  * @file httpd.h
29  * @brief HTTP Daemon routines
30  *
31  * @defgroup APACHE Apache HTTP Server
32  *
33  * Top level group of which all other groups are a member
34  * @
35  *
36  * @defgroup APACHE_MODS Loadable modules
37  *           Top level group for modules
38  * @defgroup APACHE_OS Operating System Specific
39  * @defgroup APACHE_INTERNAL Internal interfaces
40  * @defgroup APACHE_CORE Core routines
41  * @
42  * @defgroup APACHE_CORE_DAEMON HTTP Daemon Routine
43  * @
44   }
45 unit httpd24;
46 
47 {$ifdef fpc}
48   {$mode delphi}{$H+}
49 {$endif}
50 {$ifdef Unix}
51   {$PACKRECORDS C}
52 {$endif}
53 
54 {$PACKENUM 4}
55 
56 {$IFDEF Apache1_3}
57   {$WARNING Apache1_3 is defined somewhere, but the HTTPD unit included is for Apache2_4}
58 {$ENDIF}
59 {$IFDEF Apache2_0}
60   {$WARNING Apache2_0 is defined somewhere, but the HTTPD unit included is for Apache2_4}
61 {$ENDIF}
62 {$IFDEF Apache2_2}
63   {$WARNING Apache2_2 is defined somewhere, but the HTTPD unit included is for Apache2_4}
64 {$ENDIF}
65 
66 {$IFDEF FPCAPACHE_1_3}
67   {$WARNING FPCAPACHE_1_3 is defined somewhere, but the HTTPD unit included is for FPCAPACHE_2_4}
68 {$ENDIF}
69 {$IFDEF FPCAPACHE_2_0}
70   {$WARNING FPCAPACHE_2_0 is defined somewhere, but the HTTPD unit included is for FPCAPACHE_2_4}
71 {$ENDIF}
72 {$IFDEF FPCAPACHE_2_2}
73   {$WARNING FPCAPACHE_2_2 is defined somewhere, but the HTTPD unit included is for FPCAPACHE_2_4}
74 {$ENDIF}
75 
76 {$DEFINE Apache2_4}
77 {$DEFINE FPCAPACHE_2_4}
78 
79 interface
80 
81 uses
82 {$ifdef WINDOWS}
83   Windows,
84 {$ELSE}
85   UnixType,
86 {$ENDIF}
87   ctypes, apr24;
88 
89 const
90 {$ifndef fpc}
91   LineEnding = #13#10;
92 {$endif}
93 
94 {$IFDEF WINDOWS}
95   LibHTTPD = 'libhttpd.dll';
96 {$ELSE}
97   LibHTTPD = '';
98 {$ENDIF}
99 
100 {$IFDEF WINDOWS}
101   LibAPRUtil = 'libaprutil-1.dll';
102 {$ELSE}
103   LibAPRUtil = '';
104 {$ENDIF}
105 
106 type
107   { configuration vector structure , moved from http_config.inc (http_config.h)}
108   ap_conf_vector_t = record end;
109   Pap_conf_vector_t = ^ap_conf_vector_t;
110   PPap_conf_vector_t = ^Pap_conf_vector_t;
111 
112   {*
113    Shortcuts for FPC, so no extra includes are needed.
114    It would require more of the header files from the Apache httpd, apr and apr-util
115    source code packages.
116    *}
117   {apr_thread_mutex_t is OS dependent, found in apr-X.X.X/include/arch/.../apr_arch_thread_mutex.h}
118   Papr_thread_mutex_t = Pointer;//^apr_thread_mutex_t;   used in http.inc -> request_rec record
119 
120   {from apr-X.X.X/include/apr_network_io.h  used in server_addr_rec record in httpd.inc}
121   Papr_sockaddr_t = Pointer;//^apr_sockaddr_t
122   apr_port_t = word;//apr_uint16_t
123   {end apr_network_io.h}
124 
125   { A structure to represent sockets }
126   apr_socket_t = record end;
127   Papr_socket_t = ^apr_socket_t;
128   PPapr_socket_t = ^Papr_socket_t;
129   {end apr_network_io.h}
130 
131   {from apr-X.X.X/include/apr_thread_proc.h , used in http_log.h (http_log.inc)}
132   apr_cmdtype_e = (
133       APR_SHELLCMD,           //**< use the shell to invoke the program */
134       APR_PROGRAM,            //**< invoke the program directly, no copied env */
135       APR_PROGRAM_ENV,        //**< invoke the program, replicating our environment */
136       APR_PROGRAM_PATH,       //**< find program on PATH, use our environment */
137       APR_SHELLCMD_ENV        {/**< use the shell to invoke the program,
138                                *   replicating our environment
139                                *}
140   );
141   {*
142    end Shortcuts for FPC
143    *}
144 {
145   Main httpd header files
146 
147   Note: There are more include files other then these, because some include files
148         include more files.
149 }
150 
151 //{$include ap_provider.inc}
152 {$include util_cfgtree.inc}
153 
154 {$include httpd.inc}
155 {$include http_config.inc}
156 {$include http_core.inc}
157 {$include http_log.inc}
158 //{$include http_main.inc}
159 {$include http_protocol.inc}
160 //{$include http_request.inc}
161 //{$include http_connection.inc}
162 //{$include http_vhost.inc}
163 
164 {$include util_script.inc}
165 //{$include util_time.inc}
166 //{$include util_md5.inc}
167 //{$include ap_mpm.inc}
168 
169 // APRUtil External Variables //
170 
171 var
172 
173   {/* All of the bucket types implemented by the core */
174   /**
175    * The flush bucket type.  This signifies that all data should be flushed to
176    * the next filter.  The flush bucket should be sent with the other buckets.
177    */}
178   apr_bucket_type_flush: apr_bucket_type_t external LibAPRUtil;
179   {/**
180    * The EOS bucket type.  This signifies that there will be no more data, ever.
181    * All filters MUST send all data to the next filter when they receive a
182    * bucket of this type
183    */}
184   apr_bucket_type_eos: apr_bucket_type_t external LibAPRUtil;
185   {/**
186    * The FILE bucket type.  This bucket represents a file on disk
187    */}
188   apr_bucket_type_file: apr_bucket_type_t external LibAPRUtil;
189   {/**
190    * The HEAP bucket type.  This bucket represents a data allocated from the
191    * heap.
192    */}
193   apr_bucket_type_heap: apr_bucket_type_t external LibAPRUtil;
194   {$IFDEF APR_HAS_MMAP}
195     {/**
196      * The MMAP bucket type.  This bucket represents an MMAP'ed file
197      */}
198     apr_bucket_type_mmap: apr_bucket_type_t external LibAPRUtil;
199   {$ENDIF}
200   {/**
201    * The POOL bucket type.  This bucket represents a data that was allocated
202    * from a pool.  IF this bucket is still available when the pool is cleared,
203    * the data is copied on to the heap.
204    */}
205   apr_bucket_type_pool: apr_bucket_type_t external LibAPRUtil;
206   {/**
207    * The PIPE bucket type.  This bucket represents a pipe to another program.
208    */}
209   apr_bucket_type_pipe: apr_bucket_type_t external LibAPRUtil;
210   {/**
211    * The IMMORTAL bucket type.  This bucket represents a segment of data that
212    * the creator is willing to take responsibility for.  The core will do
213    * nothing with the data in an immortal bucket
214    */}
215   apr_bucket_type_immortal: apr_bucket_type_t external LibAPRUtil;
216   {/**
217    * The TRANSIENT bucket type.  This bucket represents a data allocated off
218    * the stack.  When the setaside function is called, this data is copied on
219    * to the heap
220    */}
221   apr_bucket_type_transient: apr_bucket_type_t external LibAPRUtil;
222   {/**
223    * The SOCKET bucket type.  This bucket represents a socket to another machine
224    */}
225   apr_bucket_type_socket: apr_bucket_type_t external LibAPRUtil;
226 
227 //********************************************************************
228   { from apr_buckets.inc }
229 
APR_BRIGADE_SENTINELnull230   function APR_BRIGADE_SENTINEL(b: Papr_bucket_brigade): Papr_bucket;
APR_BRIGADE_FIRSTnull231   function APR_BRIGADE_FIRST(b: Papr_bucket_brigade): Papr_bucket;
APR_BRIGADE_LASTnull232   function APR_BRIGADE_LAST(b: Papr_bucket_brigade): Papr_bucket;
APR_BUCKET_NEXTnull233   function APR_BUCKET_NEXT(e: Papr_bucket): Papr_bucket;
APR_BUCKET_PREVnull234   function APR_BUCKET_PREV(e: Papr_bucket): Papr_bucket;
235   procedure APR_BUCKET_REMOVE(e: Papr_bucket);
APR_BUCKET_IS_METADATAnull236   function APR_BUCKET_IS_METADATA(e: Papr_bucket): boolean;
APR_BUCKET_IS_FLUSHnull237   function APR_BUCKET_IS_FLUSH(e: Papr_bucket): boolean;
APR_BUCKET_IS_EOSnull238   function APR_BUCKET_IS_EOS(e: Papr_bucket): boolean;
APR_BUCKET_IS_FILEnull239   function APR_BUCKET_IS_FILE(e: Papr_bucket): boolean;
APR_BUCKET_IS_PIPEnull240   function APR_BUCKET_IS_PIPE(e: Papr_bucket): boolean;
APR_BUCKET_IS_SOCKETnull241   function APR_BUCKET_IS_SOCKET(e: Papr_bucket): boolean;
APR_BUCKET_IS_HEAPnull242   function APR_BUCKET_IS_HEAP(e: Papr_bucket): boolean;
APR_BUCKET_IS_TRANSIENTnull243   function APR_BUCKET_IS_TRANSIENT(e: Papr_bucket): boolean;
APR_BUCKET_IS_IMMORTALnull244   function APR_BUCKET_IS_IMMORTAL(e: Papr_bucket): boolean;
245   {$IFDEF APR_HAS_MMAP}
APR_BUCKET_IS_MMAPnull246     function APR_BUCKET_IS_MMAP(e: Papr_bucket): boolean;
247   {$ENDIF}
APR_BUCKET_IS_POOLnull248   function APR_BUCKET_IS_POOL(e: Papr_bucket): boolean;
apr_bucket_readnull249   function apr_bucket_read(e: Papr_bucket; const str: PPChar; len: Papr_size_t;
250     block: apr_read_type_e): apr_status_t;
251 
AP_INIT_TAKE1null252   function AP_INIT_TAKE1(directive: Pchar; const take1func : ttake1func;
253     mconfig: Pointer; where: Integer; help: Pchar): command_rec;
AP_INIT_TAKE2null254   function AP_INIT_TAKE2(directive: Pchar; const take2func: ttake2func;
255     mconfig: Pointer; where: Integer; help: Pchar): command_rec;
AP_INIT_TAKE3null256   function AP_INIT_TAKE3(directive: Pchar; const take3func: ttake3func;
257     mconfig: Pointer; where: Integer; help: Pchar): command_rec;
258 
259 implementation
260   { Internal representation for a HTTP protocol number, e.g., HTTP/1.1 }
HTTP_VERSIONnull261   function HTTP_VERSION(major, minor: Integer): Integer;
262   begin
263     HTTP_VERSION := (1000 * major + minor);
264   end;
265 
266   { Major part of HTTP protocol }
HTTP_VERSION_MAJORnull267   function HTTP_VERSION_MAJOR(number: Integer): Integer;
268   begin
269     HTTP_VERSION_MAJOR := number div 1000;
270   end;
271 
272   { Minor part of HTTP protocol }
HTTP_VERSION_MINORnull273   function HTTP_VERSION_MINOR(number: Integer): Integer;
274   begin
275     HTTP_VERSION_MINOR := number mod 1000;
276   end;
277 
ap_is_HTTP_INFOnull278   function ap_is_HTTP_INFO(x : Integer): Boolean;
279   begin
280     ap_is_HTTP_INFO := ((x>=100) and (x<200));
281   end;
282 
ap_is_HTTP_SUCCESSnull283   function ap_is_HTTP_SUCCESS(x : Integer) : Boolean;
284   begin
285     ap_is_HTTP_SUCCESS := ((x>=200) and (x<300));
286   end;
287 
ap_is_HTTP_REDIRECTnull288   function ap_is_HTTP_REDIRECT(x : Integer) : Boolean;
289   begin
290     ap_is_HTTP_REDIRECT := ((x>=300) and (x<400));
291   end;
292 
ap_is_HTTP_ERRORnull293   function ap_is_HTTP_ERROR(x : Integer) : Boolean;
294   begin
295     ap_is_HTTP_ERROR := ((x>=400) and (x<600));
296   end;
297 
ap_is_HTTP_CLIENT_ERRORnull298   function ap_is_HTTP_CLIENT_ERROR(x : Integer) : Boolean;
299   begin
300     ap_is_HTTP_CLIENT_ERROR := ((x>=400) and (x<500));
301   end;
302 
ap_is_HTTP_SERVER_ERRORnull303   function ap_is_HTTP_SERVER_ERROR(x : Integer) : Boolean;
304   begin
305     ap_is_HTTP_SERVER_ERROR := ((x>=500) and (x<600));
306   end;
307 
ap_is_HTTP_VALID_RESPONSEnull308   function ap_is_HTTP_VALID_RESPONSE(x : Integer) : Boolean;
309   begin
310     ap_is_HTTP_VALID_RESPONSE := ((x>=100) and (x<600));
311   end;
312 
ap_status_drops_connectionnull313   function ap_status_drops_connection(x : Integer): Boolean;
314   begin
315     case x of
316       HTTP_BAD_REQUEST,
317       HTTP_REQUEST_TIME_OUT,
318       HTTP_LENGTH_REQUIRED,
319       HTTP_REQUEST_ENTITY_TOO_LARGE,
320       HTTP_REQUEST_URI_TOO_LARGE,
321       HTTP_INTERNAL_SERVER_ERROR,
322       HTTP_SERVICE_UNAVAILABLE,
323       HTTP_NOT_IMPLEMENTED:
324         Result := true;
325       else
326         Result := false;
327     end;
328   end;
329 
ap_escape_urinull330   function ap_escape_uri(ppool: Papr_pool_t; const path: PChar) : PChar;
331   begin
332     ap_escape_uri:=ap_os_escape_path(ppool,path,1);
333   end;
334 
ap_escape_htmlnull335   function ap_escape_html(p: Papr_pool_t; const s: PChar) : PChar;
336   begin
337     ap_escape_html:=ap_escape_html2(p,s,0);
338   end;
339 
340 //********************************************************************
341   { from apr_buckets.inc }
342 
APR_BRIGADE_FIRSTnull343   function APR_BRIGADE_FIRST(b: Papr_bucket_brigade): Papr_bucket; inline;
344   begin
345     APR_BRIGADE_FIRST := b^.list.next;
346   end;
347 
APR_BRIGADE_LASTnull348   function APR_BRIGADE_LAST(b: Papr_bucket_brigade): Papr_bucket; inline;
349   begin
350     APR_BRIGADE_LAST := b^.list.prev;
351   end;
352 
APR_BRIGADE_SENTINELnull353   function APR_BRIGADE_SENTINEL(b: Papr_bucket_brigade): Papr_bucket; inline;
354   var b_: apr_bucket; // This should technically be <type> and link shouldn't be hard-coded..
355   begin
356     APR_BRIGADE_SENTINEL := Papr_bucket(pointer(@b^.list.next) - (pointer(@b_.Link) - pointer(@b_) ) );
357   end;
358 
359   function APR_BUCKET_IS_METADATA(e: Papr_bucket): boolean; inline;
360   begin
361     APR_BUCKET_IS_METADATA := e^.type_^.is_metadata = APR_BUCKET_METADATA;
362   end;
363 
364   function APR_BUCKET_IS_FLUSH(e: Papr_bucket): boolean; inline;
365   begin
366     APR_BUCKET_IS_FLUSH := e^.type_ = @apr_bucket_type_flush;
367   end;
368 
369   function APR_BUCKET_IS_EOS(e: Papr_bucket): boolean; inline;
370   begin
371     APR_BUCKET_IS_EOS := e^.type_ = @apr_bucket_type_eos;
372   end;
373 
374   function APR_BUCKET_IS_FILE(e: Papr_bucket): boolean; inline;
375   begin
376     APR_BUCKET_IS_FILE := e^.type_ = @apr_bucket_type_file;
377   end;
378 
379   function APR_BUCKET_IS_PIPE(e: Papr_bucket): boolean; inline;
380   begin
381     APR_BUCKET_IS_PIPE := e^.type_ = @apr_bucket_type_pipe;
382   end;
383 
384   function APR_BUCKET_IS_SOCKET(e: Papr_bucket): boolean; inline;
385   begin
386     APR_BUCKET_IS_SOCKET := e^.type_ = @apr_bucket_type_socket;
387   end;
388 
389   function APR_BUCKET_IS_HEAP(e: Papr_bucket): boolean; inline;
390   begin
391     APR_BUCKET_IS_HEAP := e^.type_ = @apr_bucket_type_heap;
392   end;
393 
394   function APR_BUCKET_IS_TRANSIENT(e: Papr_bucket): boolean; inline;
395   begin
396     APR_BUCKET_IS_TRANSIENT := e^.type_ = @apr_bucket_type_transient;
397   end;
398 
399   function APR_BUCKET_IS_IMMORTAL(e: Papr_bucket): boolean; inline;
400   begin
401     APR_BUCKET_IS_IMMORTAL := e^.type_ = @apr_bucket_type_immortal;
402   end;
403 
404   {$IFDEF APR_HAS_MMAP}
405     function APR_BUCKET_IS_MMAP(e: Papr_bucket): boolean; inline;
406     begin
407       APR_BUCKET_IS_MMAP := e^.type_ = @apr_bucket_type_mmap;
408     end;
409   {$ENDIF}
410 
411   function APR_BUCKET_IS_POOL(e: Papr_bucket): boolean; inline;
412   begin
413     APR_BUCKET_IS_POOL := e^.type_ = @apr_bucket_type_pool;
414   end;
415 
416   function APR_BUCKET_NEXT(e: Papr_bucket): Papr_bucket; inline;
417   begin
418     APR_BUCKET_NEXT := e^.link.next;
419   end;
420 
421   function APR_BUCKET_PREV(e: Papr_bucket): Papr_bucket; inline;
422   begin
423     APR_BUCKET_PREV := e^.link.prev;
424   end;
425 
426   procedure APR_BUCKET_REMOVE(e: Papr_bucket); inline;
427   begin
428     APR_BUCKET_PREV(e)^.link.next := APR_BUCKET_NEXT(e);
429     APR_BUCKET_NEXT(e)^.link.prev := APR_BUCKET_PREV(e);
430   end;
431 
432   function apr_bucket_read(e: Papr_bucket; const str: PPChar; len: Papr_size_t;
433     block: apr_read_type_e): apr_status_t; inline;
434   begin
435     apr_bucket_read := e^.type_^.read(e, str, len, block);
436   end;
437 
438   function AP_INIT_TAKE1(directive: Pchar; const take1func: ttake1func;
439     mconfig: Pointer; where: Integer; help: Pchar): command_rec; inline;
440   begin
441     with result DO
442     begin
443       name         := directive;
444       func.take1   := take1func;
445       cmd_data     := mconfig;
446       req_override := where;
447       args_how     := TAKE1;
448       errmsg       := help;
449     end;
450   end;
451 
452   function AP_INIT_TAKE2(directive: Pchar; const take2func: ttake2func;
453     mconfig: Pointer; where: Integer; help: Pchar): command_rec; inline;
454   begin
455     with result DO
456     begin
457       name         := directive;
458       func.take2   := take2func;
459       cmd_data     := mconfig;
460       req_override := where;
461       args_how     := TAKE2;
462       errmsg       := help;
463     end;
464   end;
465 
466   function AP_INIT_TAKE3(directive: Pchar; const take3func: ttake3func;
467     mconfig: Pointer; where: Integer; help: Pchar): command_rec; inline;
468   begin
469     with result DO
470     begin
471       name         := directive;
472       func.take3   := take3func;
473       cmd_data     := mconfig;
474       req_override := where;
475       args_how     := TAKE3;
476       errmsg       := help;
477     end;
478   end;
479 
480 //********************************************************************
481   { from http_config.inc }
482 
483   { Use this in all standard modules }
484   procedure STANDARD20_MODULE_STUFF(var mod_: module);
485   begin
486     mod_.version := MODULE_MAGIC_NUMBER_MAJOR;
487     mod_.minor_version := MODULE_MAGIC_NUMBER_MINOR;
488     mod_.module_index := -1;
489   //  mod_.name: PChar;
490     mod_.dynamic_load_handle := nil;
491     mod_.next := nil;
492     mod_.magic := MODULE_MAGIC_COOKIE;
493     mod_.rewrite_args := nil;
494   end;
495 
496   { Use this only in MPMs }
497   procedure MPM20_MODULE_STUFF(var mod_: module);
498   begin
499     mod_.version := MODULE_MAGIC_NUMBER_MAJOR;
500     mod_.minor_version := MODULE_MAGIC_NUMBER_MINOR;
501     mod_.module_index := -1;
502   //  mod_.name: PChar;
503     mod_.dynamic_load_handle := nil;
504     mod_.next := nil;
505     mod_.magic := MODULE_MAGIC_COOKIE;
506   end;
507 
508 end.
509