Skip to content
This repository
Browse code

Import with fixes, rake cleanup, and working test suite

  • Loading branch information...
commit adb3a3ac26315cd9851096600c575b4fe03ebbe2 0 parents
James Tucker authored December 19, 2008
7  .gitignore
... ...
@@ -0,0 +1,7 @@
  1
+*.gem
  2
+ext/Makefile
  3
+ext/*.log
  4
+ext/*.o
  5
+ext/*.dll
  6
+ext/*.bundle
  7
+ext/*.so
92  Rakefile
... ...
@@ -0,0 +1,92 @@
  1
+# $Id: Rakefile 3546 2006-12-31 21:01:27Z francis $
  2
+
  3
+require 'rake/gempackagetask'
  4
+require 'rake/clean'
  5
+require 'rake/testtask'
  6
+
  7
+Rake::TestTask.new do |t|
  8
+  t.libs += %w(ext)
  9
+  t.test_files = FileList['test/test_*.rb']
  10
+  t.verbose = true
  11
+end
  12
+
  13
+namespace :build do
  14
+  sources = FileList['ext/*.{cpp,c,h}']
  15
+
  16
+  file 'ext/Makefile' => 'ext/extconf.rb' do
  17
+    Dir.chdir 'ext' do
  18
+      ruby 'extconf.rb'
  19
+    end
  20
+  end
  21
+  CLEAN.include('ext/Makefile')
  22
+  CLEAN.include('ext/*.log')
  23
+  
  24
+  libfile = "ext/eventmachine_httpserver.#{Config::CONFIG['DLEXT']}"
  25
+  file libfile => ['ext/Makefile', *sources] do
  26
+    Dir.chdir 'ext' do
  27
+      make = case RUBY_PLATFORM
  28
+      when /mswin32/
  29
+        'nmake'
  30
+      else
  31
+        # typical gcc stack, might need a case for gmake on some
  32
+        'make'
  33
+      end
  34
+      sh make
  35
+    end
  36
+  end
  37
+  CLEAN.include(libfile)
  38
+  
  39
+  task :makefile => 'ext/Makefile'
  40
+  
  41
+  task :extension => libfile
  42
+end
  43
+
  44
+desc "Build the extension inside the ext dir"
  45
+task :build => :"build:extension"
  46
+
  47
+desc "Build as necessary, then run tests"
  48
+task :test => :build
  49
+
  50
+namespace :gem do
  51
+  # TODO : use rake-compiler (github.com/luislavena/rake-compiler) for this!
  52
+  # specbinary = eval(File.read("eventmachine_httpserver-binary.gemspec"))
  53
+  # specbinary.version = $version
  54
+  # desc "Build a binary RubyGem for EventMachine HTTP Server"
  55
+  # task :gembinary => ["pkg/eventmachine_httpserver-binary-#{$version}.gem"]
  56
+  # Rake::GemPackageTask.new(specbinary)
  57
+
  58
+  def gemspec
  59
+    # The template executes some ruby code to make a manifest, so we just eval 
  60
+    # it. Later you could fill it with an ERB processor or whatever. It must 
  61
+    # return a valid gemspec object.
  62
+    @gemspec ||= eval(File.read("eventmachine_httpserver.gemspec.tmpl"))
  63
+  end
  64
+
  65
+  def version
  66
+    gemspec.version
  67
+  end
  68
+
  69
+  file "eventmachine_httpserver.gemspec" => 'eventmachine_httpserver.gemspec.tmpl' do |t|
  70
+    open(t.name, 'w') { |f| f.write gemspec.to_ruby }
  71
+  end
  72
+
  73
+  desc "Generate the gemspec from template"
  74
+  task :spec => "eventmachine_httpserver.gemspec"
  75
+
  76
+  file "eventmachine_httpserver-#{version}.gem" => :"gem:spec" do
  77
+    sh "gem build eventmachine_httpserver.gemspec"
  78
+  end
  79
+
  80
+  desc "Build the RubyGem for EventMachine HTTP Server"
  81
+  task :build => "eventmachine_httpserver-#{version}.gem"
  82
+
  83
+  desc "run gem install on the built gem"
  84
+  task :install => :build do
  85
+    sh 'gem inst eventmachine_httpserver*.gem'
  86
+  end
  87
+
  88
+  CLOBBER.include("eventmachine_httpserver.gemspec")
  89
+  CLEAN.include("eventmachine_httpserver-#{version}.gem")
  90
+end
  91
+
  92
+task :default => :test
281  docs/COPYING
... ...
@@ -0,0 +1,281 @@
  1
+.
  2
+
  3
+		    GNU GENERAL PUBLIC LICENSE
  4
+		       Version 2, June 1991
  5
+
  6
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
  7
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  8
+ Everyone is permitted to copy and distribute verbatim copies
  9
+ of this license document, but changing it is not allowed.
  10
+
  11
+			    Preamble
  12
+
  13
+  The licenses for most software are designed to take away your
  14
+ freedom to share and change it.  By contrast, the GNU General Public
  15
+ License is intended to guarantee your freedom to share and change free
  16
+ software--to make sure the software is free for all its users.  This
  17
+ General Public License applies to most of the Free Software
  18
+ Foundation's software and to any other program whose authors commit to
  19
+ using it.  (Some other Free Software Foundation software is covered by
  20
+ the GNU Lesser General Public License instead.)  You can apply it to
  21
+ your programs, too.
  22
+
  23
+  When we speak of free software, we are referring to freedom, not
  24
+ price.  Our General Public Licenses are designed to make sure that you
  25
+ have the freedom to distribute copies of free software (and charge for
  26
+ this service if you wish), that you receive source code or can get it
  27
+ if you want it, that you can change the software or use pieces of it
  28
+ in new free programs; and that you know you can do these things.
  29
+
  30
+  To protect your rights, we need to make restrictions that forbid
  31
+ anyone to deny you these rights or to ask you to surrender the rights.
  32
+ These restrictions translate to certain responsibilities for you if you
  33
+ distribute copies of the software, or if you modify it.
  34
+
  35
+  For example, if you distribute copies of such a program, whether
  36
+ gratis or for a fee, you must give the recipients all the rights that
  37
+ you have.  You must make sure that they, too, receive or can get the
  38
+ source code.  And you must show them these terms so they know their
  39
+ rights.
  40
+
  41
+  We protect your rights with two steps: (1) copyright the software, and
  42
+ (2) offer you this license which gives you legal permission to copy,
  43
+ distribute and/or modify the software.
  44
+
  45
+  Also, for each author's protection and ours, we want to make certain
  46
+ that everyone understands that there is no warranty for this free
  47
+ software.  If the software is modified by someone else and passed on, we
  48
+ want its recipients to know that what they have is not the original, so
  49
+ that any problems introduced by others will not reflect on the original
  50
+ authors' reputations.
  51
+
  52
+  Finally, any free program is threatened constantly by software
  53
+ patents.  We wish to avoid the danger that redistributors of a free
  54
+ program will individually obtain patent licenses, in effect making the
  55
+ program proprietary.  To prevent this, we have made it clear that any
  56
+ patent must be licensed for everyone's free use or not licensed at all.
  57
+
  58
+  The precise terms and conditions for copying, distribution and
  59
+ modification follow.
  60
+
  61
+		    GNU GENERAL PUBLIC LICENSE
  62
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  63
+
  64
+  0. This License applies to any program or other work which contains
  65
+ a notice placed by the copyright holder saying it may be distributed
  66
+ under the terms of this General Public License.  The "Program", below,
  67
+ refers to any such program or work, and a "work based on the Program"
  68
+ means either the Program or any derivative work under copyright law:
  69
+ that is to say, a work containing the Program or a portion of it,
  70
+ either verbatim or with modifications and/or translated into another
  71
+ language.  (Hereinafter, translation is included without limitation in
  72
+ the term "modification".)  Each licensee is addressed as "you".
  73
+
  74
+ Activities other than copying, distribution and modification are not
  75
+ covered by this License; they are outside its scope.  The act of
  76
+ running the Program is not restricted, and the output from the Program
  77
+ is covered only if its contents constitute a work based on the
  78
+ Program (independent of having been made by running the Program).
  79
+ Whether that is true depends on what the Program does.
  80
+
  81
+  1. You may copy and distribute verbatim copies of the Program's
  82
+ source code as you receive it, in any medium, provided that you
  83
+ conspicuously and appropriately publish on each copy an appropriate
  84
+ copyright notice and disclaimer of warranty; keep intact all the
  85
+ notices that refer to this License and to the absence of any warranty;
  86
+ and give any other recipients of the Program a copy of this License
  87
+ along with the Program.
  88
+
  89
+ You may charge a fee for the physical act of transferring a copy, and
  90
+ you may at your option offer warranty protection in exchange for a fee.
  91
+
  92
+  2. You may modify your copy or copies of the Program or any portion
  93
+ of it, thus forming a work based on the Program, and copy and
  94
+ distribute such modifications or work under the terms of Section 1
  95
+ above, provided that you also meet all of these conditions:
  96
+
  97
+    a) You must cause the modified files to carry prominent notices
  98
+    stating that you changed the files and the date of any change.
  99
+
  100
+    b) You must cause any work that you distribute or publish, that in
  101
+    whole or in part contains or is derived from the Program or any
  102
+    part thereof, to be licensed as a whole at no charge to all third
  103
+    parties under the terms of this License.
  104
+
  105
+    c) If the modified program normally reads commands interactively
  106
+    when run, you must cause it, when started running for such
  107
+    interactive use in the most ordinary way, to print or display an
  108
+    announcement including an appropriate copyright notice and a
  109
+    notice that there is no warranty (or else, saying that you provide
  110
+    a warranty) and that users may redistribute the program under
  111
+    these conditions, and telling the user how to view a copy of this
  112
+    License.  (Exception: if the Program itself is interactive but
  113
+    does not normally print such an announcement, your work based on
  114
+    the Program is not required to print an announcement.)
  115
+
  116
+ These requirements apply to the modified work as a whole.  If
  117
+ identifiable sections of that work are not derived from the Program,
  118
+ and can be reasonably considered independent and separate works in
  119
+ themselves, then this License, and its terms, do not apply to those
  120
+ sections when you distribute them as separate works.  But when you
  121
+ distribute the same sections as part of a whole which is a work based
  122
+ on the Program, the distribution of the whole must be on the terms of
  123
+ this License, whose permissions for other licensees extend to the
  124
+ entire whole, and thus to each and every part regardless of who wrote it.
  125
+
  126
+ Thus, it is not the intent of this section to claim rights or contest
  127
+ your rights to work written entirely by you; rather, the intent is to
  128
+ exercise the right to control the distribution of derivative or
  129
+ collective works based on the Program.
  130
+
  131
+ In addition, mere aggregation of another work not based on the Program
  132
+ with the Program (or with a work based on the Program) on a volume of
  133
+ a storage or distribution medium does not bring the other work under
  134
+ the scope of this License.
  135
+
  136
+  3. You may copy and distribute the Program (or a work based on it,
  137
+ under Section 2) in object code or executable form under the terms of
  138
+ Sections 1 and 2 above provided that you also do one of the following:
  139
+
  140
+    a) Accompany it with the complete corresponding machine-readable
  141
+    source code, which must be distributed under the terms of Sections
  142
+    1 and 2 above on a medium customarily used for software interchange; or,
  143
+
  144
+    b) Accompany it with a written offer, valid for at least three
  145
+    years, to give any third party, for a charge no more than your
  146
+    cost of physically performing source distribution, a complete
  147
+    machine-readable copy of the corresponding source code, to be
  148
+    distributed under the terms of Sections 1 and 2 above on a medium
  149
+    customarily used for software interchange; or,
  150
+
  151
+    c) Accompany it with the information you received as to the offer
  152
+    to distribute corresponding source code.  (This alternative is
  153
+    allowed only for noncommercial distribution and only if you
  154
+    received the program in object code or executable form with such
  155
+    an offer, in accord with Subsection b above.)
  156
+
  157
+ The source code for a work means the preferred form of the work for
  158
+ making modifications to it.  For an executable work, complete source
  159
+ code means all the source code for all modules it contains, plus any
  160
+ associated interface definition files, plus the scripts used to
  161
+ control compilation and installation of the executable.  However, as a
  162
+ special exception, the source code distributed need not include
  163
+ anything that is normally distributed (in either source or binary
  164
+ form) with the major components (compiler, kernel, and so on) of the
  165
+ operating system on which the executable runs, unless that component
  166
+ itself accompanies the executable.
  167
+
  168
+ If distribution of executable or object code is made by offering
  169
+ access to copy from a designated place, then offering equivalent
  170
+ access to copy the source code from the same place counts as
  171
+ distribution of the source code, even though third parties are not
  172
+ compelled to copy the source along with the object code.
  173
+
  174
+  4. You may not copy, modify, sublicense, or distribute the Program
  175
+ except as expressly provided under this License.  Any attempt
  176
+ otherwise to copy, modify, sublicense or distribute the Program is
  177
+ void, and will automatically terminate your rights under this License.
  178
+ However, parties who have received copies, or rights, from you under
  179
+ this License will not have their licenses terminated so long as such
  180
+ parties remain in full compliance.
  181
+
  182
+  5. You are not required to accept this License, since you have not
  183
+ signed it.  However, nothing else grants you permission to modify or
  184
+ distribute the Program or its derivative works.  These actions are
  185
+ prohibited by law if you do not accept this License.  Therefore, by
  186
+ modifying or distributing the Program (or any work based on the
  187
+ Program), you indicate your acceptance of this License to do so, and
  188
+ all its terms and conditions for copying, distributing or modifying
  189
+ the Program or works based on it.
  190
+
  191
+  6. Each time you redistribute the Program (or any work based on the
  192
+ Program), the recipient automatically receives a license from the
  193
+ original licensor to copy, distribute or modify the Program subject to
  194
+ these terms and conditions.  You may not impose any further
  195
+ restrictions on the recipients' exercise of the rights granted herein.
  196
+ You are not responsible for enforcing compliance by third parties to
  197
+ this License.
  198
+
  199
+  7. If, as a consequence of a court judgment or allegation of patent
  200
+ infringement or for any other reason (not limited to patent issues),
  201
+ conditions are imposed on you (whether by court order, agreement or
  202
+ otherwise) that contradict the conditions of this License, they do not
  203
+ excuse you from the conditions of this License.  If you cannot
  204
+ distribute so as to satisfy simultaneously your obligations under this
  205
+ License and any other pertinent obligations, then as a consequence you
  206
+ may not distribute the Program at all.  For example, if a patent
  207
+ license would not permit royalty-free redistribution of the Program by
  208
+ all those who receive copies directly or indirectly through you, then
  209
+ the only way you could satisfy both it and this License would be to
  210
+ refrain entirely from distribution of the Program.
  211
+
  212
+ If any portion of this section is held invalid or unenforceable under
  213
+ any particular circumstance, the balance of the section is intended to
  214
+ apply and the section as a whole is intended to apply in other
  215
+ circumstances.
  216
+
  217
+ It is not the purpose of this section to induce you to infringe any
  218
+ patents or other property right claims or to contest validity of any
  219
+ such claims; this section has the sole purpose of protecting the
  220
+ integrity of the free software distribution system, which is
  221
+ implemented by public license practices.  Many people have made
  222
+ generous contributions to the wide range of software distributed
  223
+ through that system in reliance on consistent application of that
  224
+ system; it is up to the author/donor to decide if he or she is willing
  225
+ to distribute software through any other system and a licensee cannot
  226
+ impose that choice.
  227
+
  228
+ This section is intended to make thoroughly clear what is believed to
  229
+ be a consequence of the rest of this License.
  230
+
  231
+  8. If the distribution and/or use of the Program is restricted in
  232
+ certain countries either by patents or by copyrighted interfaces, the
  233
+ original copyright holder who places the Program under this License
  234
+ may add an explicit geographical distribution limitation excluding
  235
+ those countries, so that distribution is permitted only in or among
  236
+ countries not thus excluded.  In such case, this License incorporates
  237
+ the limitation as if written in the body of this License.
  238
+
  239
+  9. The Free Software Foundation may publish revised and/or new versions
  240
+ of the General Public License from time to time.  Such new versions will
  241
+ be similar in spirit to the present version, but may differ in detail to
  242
+ address new problems or concerns.
  243
+
  244
+ Each version is given a distinguishing version number.  If the Program
  245
+ specifies a version number of this License which applies to it and "any
  246
+ later version", you have the option of following the terms and conditions
  247
+ either of that version or of any later version published by the Free
  248
+ Software Foundation.  If the Program does not specify a version number of
  249
+ this License, you may choose any version ever published by the Free Software
  250
+ Foundation.
  251
+
  252
+  10. If you wish to incorporate parts of the Program into other free
  253
+ programs whose distribution conditions are different, write to the author
  254
+ to ask for permission.  For software which is copyrighted by the Free
  255
+ Software Foundation, write to the Free Software Foundation; we sometimes
  256
+ make exceptions for this.  Our decision will be guided by the two goals
  257
+ of preserving the free status of all derivatives of our free software and
  258
+ of promoting the sharing and reuse of software generally.
  259
+
  260
+			    NO WARRANTY
  261
+
  262
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  263
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
  264
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  265
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  266
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  267
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
  268
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
  269
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  270
+ REPAIR OR CORRECTION.
  271
+
  272
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  273
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  274
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  275
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  276
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  277
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  278
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  279
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  280
+ POSSIBILITY OF SUCH DAMAGES.
  281
+
8  docs/README
... ...
@@ -0,0 +1,8 @@
  1
+$Id: README 3895 2007-03-06 20:16:36Z francis $
  2
+
  3
+Homepage::  http://rubyeventmachine.com
  4
+Copyright:: (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
  5
+Email:: gmail address: garbagecat10
  6
+
  7
+This program is made available under the terms of the Lesser-GPL version 2.
  8
+See the file COPYING in this distribution for more information.
3  docs/RELEASE_NOTES
... ...
@@ -0,0 +1,3 @@
  1
+$Id: RELEASE_NOTES 3539 2006-12-31 03:05:56Z francis $
  2
+
  3
+
23  eventmachine_httpserver.gemspec.tmpl
... ...
@@ -0,0 +1,23 @@
  1
+Gem::Specification.new do |s|
  2
+  s.name = %q{eventmachine_httpserver}
  3
+  s.version = "0.0.1"
  4
+
  5
+  s.specification_version = 1 if s.respond_to? :specification_version=
  6
+
  7
+  s.required_rubygems_version = nil if s.respond_to? :required_rubygems_version=
  8
+  s.authors = ["Francis Cianfrocca"]
  9
+  s.cert_chain = nil
  10
+  s.date = %q{2007-03-16}
  11
+  s.description = %q{}
  12
+  s.email = %q{garbagecat10@gmail.com}
  13
+  s.extensions = ["ext/extconf.rb"]
  14
+  s.extra_rdoc_files = `git ls-files docs`.split
  15
+  s.files = `git ls-files`.split
  16
+  s.has_rdoc = true
  17
+  s.homepage = %q{http://rubyeventmachine.com}
  18
+  s.rdoc_options = ["--title", "EventMachine_HttpServer", "--main", "docs/README", "--line-numbers"]
  19
+  s.require_paths = ["lib"]
  20
+  s.required_ruby_version = Gem::Requirement.new("> 0.0.0")
  21
+  s.rubygems_version = %q{1.1.1}
  22
+  s.summary = %q{EventMachine HTTP Server}
  23
+end
128  ext/extconf.rb
... ...
@@ -0,0 +1,128 @@
  1
+# $Id: extconf.rb 3896 2007-03-06 20:21:01Z francis $
  2
+#
  3
+#----------------------------------------------------------------------------
  4
+#
  5
+# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
  6
+#
  7
+# Gmail: garbagecat10
  8
+#
  9
+# This program is free software; you can redistribute it and/or modify
  10
+# it under the terms of the GNU General Public License as published by
  11
+# the Free Software Foundation; either version 2 of the License, or
  12
+# (at your option) any later version.
  13
+#
  14
+# This program is distributed in the hope that it will be useful,
  15
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
  16
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17
+# GNU General Public License for more details.
  18
+#
  19
+# You should have received a copy of the GNU General Public License
  20
+# along with this program; if not, write to the Free Software
  21
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  22
+#
  23
+#---------------------------------------------------------------------------
  24
+#
  25
+# extconf.rb for Ruby/EventMachine
  26
+# We have to munge LDSHARED because this code needs a C++ link.
  27
+#
  28
+
  29
+require 'mkmf'
  30
+
  31
+flags = []
  32
+
  33
+case RUBY_PLATFORM.split('-',2)[1]
  34
+when 'mswin32', 'mingw32', 'bccwin32'
  35
+  unless have_header('windows.h') and
  36
+      have_header('winsock.h') and
  37
+      have_library('kernel32') and
  38
+      have_library('rpcrt4') and
  39
+      have_library('gdi32')
  40
+    exit
  41
+  end
  42
+
  43
+  flags << "-D OS_WIN32"
  44
+  flags << '-D BUILD_FOR_RUBY'
  45
+  flags << "-EHs"
  46
+  flags << "-GR"
  47
+
  48
+  dir_config('ssl')
  49
+  if have_library('ssleay32') and
  50
+	  have_library('libeay32') and
  51
+	  have_header('openssl/ssl.h') and
  52
+	  have_header('openssl/err.h')
  53
+    flags << '-D WITH_SSL'
  54
+  else
  55
+    flags << '-D WITHOUT_SSL'
  56
+  end
  57
+
  58
+when /solaris/
  59
+  unless have_library('pthread') and
  60
+	have_library('nsl') and
  61
+	have_library('socket')
  62
+	  exit
  63
+  end
  64
+
  65
+  flags << '-D OS_UNIX'
  66
+  flags << '-D OS_SOLARIS8'
  67
+  flags << '-D BUILD_FOR_RUBY'
  68
+
  69
+  dir_config('ssl')
  70
+  if have_library('ssl') and
  71
+	  have_library('crypto') and
  72
+	  have_header('openssl/ssl.h') and
  73
+	  have_header('openssl/err.h')
  74
+    flags << '-D WITH_SSL'
  75
+  else
  76
+    flags << '-D WITHOUT_SSL'
  77
+  end
  78
+
  79
+  # on Unix we need a g++ link, not gcc.
  80
+  CONFIG['LDSHARED'] = "$(CXX) -shared"
  81
+
  82
+when /darwin/
  83
+  flags << '-DOS_UNIX'
  84
+  flags << '-DBUILD_FOR_RUBY'
  85
+
  86
+  dir_config('ssl')
  87
+  if have_library('ssl') and
  88
+	  have_library('crypto') and
  89
+	  have_library('C') and
  90
+	  have_header('openssl/ssl.h') and
  91
+	  have_header('openssl/err.h')
  92
+    flags << '-DWITH_SSL'
  93
+  else
  94
+    flags << '-DWITHOUT_SSL'
  95
+  end
  96
+  # on Unix we need a g++ link, not gcc.
  97
+  # Ff line contributed by Daniel Harple.
  98
+  CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ')
  99
+
  100
+else
  101
+  unless have_library('pthread')
  102
+	  exit
  103
+  end
  104
+
  105
+  flags << '-DOS_UNIX'
  106
+  flags << '-DBUILD_FOR_RUBY'
  107
+
  108
+  dir_config('ssl')
  109
+  if have_library('ssl') and
  110
+	  have_library('crypto') and
  111
+	  have_header('openssl/ssl.h') and
  112
+	  have_header('openssl/err.h')
  113
+    flags << '-DWITH_SSL'
  114
+  else
  115
+    flags << '-DWITHOUT_SSL'
  116
+  end
  117
+  # on Unix we need a g++ link, not gcc.
  118
+  CONFIG['LDSHARED'] = "$(CXX) -shared"
  119
+end
  120
+
  121
+if $CPPFLAGS
  122
+  $CPPFLAGS += ' ' + flags.join(' ')
  123
+else
  124
+  $CFLAGS += ' ' + flags.join(' ')
  125
+end
  126
+
  127
+
  128
+create_makefile "eventmachine_httpserver"
566  ext/http.cpp
... ...
@@ -0,0 +1,566 @@
  1
+/*****************************************************************************
  2
+
  3
+$Id: http.cpp 3967 2007-03-16 11:53:55Z francis $
  4
+
  5
+File:     http.cpp
  6
+Date:     21Apr06
  7
+
  8
+Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
  9
+Gmail: garbagecat10
  10
+
  11
+This program is free software; you can redistribute it and/or modify
  12
+it under the terms of the GNU General Public License as published by
  13
+the Free Software Foundation; either version 2 of the License, or
  14
+(at your option) any later version.
  15
+
  16
+This program is distributed in the hope that it will be useful,
  17
+but WITHOUT ANY WARRANTY; without even the implied warranty of
  18
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19
+GNU General Public License for more details.
  20
+
  21
+You should have received a copy of the GNU General Public License
  22
+along with this program; if not, write to the Free Software
  23
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  24
+
  25
+*****************************************************************************/
  26
+
  27
+
  28
+#include <iostream>
  29
+#include <string>
  30
+#include <sstream>
  31
+#include <stdexcept>
  32
+#include <stdio.h>
  33
+
  34
+#ifdef OS_WIN32
  35
+#include <windows.h>
  36
+#endif
  37
+
  38
+using namespace std;
  39
+
  40
+#include "http.h"
  41
+
  42
+
  43
+#ifdef OS_WIN32
  44
+#define strncasecmp _strnicmp
  45
+#define strcasecmp _stricmp
  46
+void setenv (const char *str, const char *value, bool replace)
  47
+{
  48
+	SetEnvironmentVariable (str, value);
  49
+}
  50
+void unsetenv (const char *str)
  51
+{
  52
+	SetEnvironmentVariable (str, NULL);
  53
+}
  54
+#endif
  55
+
  56
+
  57
+/**********************************
  58
+HttpConnection_t::HttpConnection_t
  59
+**********************************/
  60
+
  61
+HttpConnection_t::HttpConnection_t()
  62
+{
  63
+	ProtocolState = BaseState;
  64
+	_Content = NULL;
  65
+
  66
+	// By default, we set the standard CGI environment strings.
  67
+	// (This is primarily beneficial because it lets the caller use Ruby's CGI classes.)
  68
+	// The caller can switch this off in Ruby code, which greatly improves performance.
  69
+	bSetEnvironmentStrings = true;
  70
+
  71
+	// This flag was added by Kirk Haines (thanks, Kirk). It preserves the original
  72
+	// behavior with respect to POST content, which was to accumulate it in a buffer
  73
+	// allocated and managed in this class. Kirk's mods allow callers to specify that
  74
+	// POST content be submitted directly to user code piece by piece as we receive it,
  75
+	// instead of buffering it here. To get the latter behavior, user code must call
  76
+	// dont_accumulate_post.
  77
+	bAccumulatePost = true;
  78
+}
  79
+
  80
+
  81
+/***********************************
  82
+HttpConnection_t::~HttpConnection_t
  83
+***********************************/
  84
+
  85
+HttpConnection_t::~HttpConnection_t()
  86
+{
  87
+	if (_Content)
  88
+		free (_Content);
  89
+}
  90
+
  91
+
  92
+
  93
+/**************************
  94
+HttpConnection_t::SendData
  95
+**************************/
  96
+
  97
+void HttpConnection_t::SendData (const char *data, int length)
  98
+{
  99
+  cerr << "UNIMPLEMENTED SendData" << endl;
  100
+}
  101
+
  102
+
  103
+/*********************************
  104
+HttpConnection_t::CloseConnection
  105
+*********************************/
  106
+
  107
+void HttpConnection_t::CloseConnection (bool after_writing)
  108
+{
  109
+  cerr << "UNIMPLEMENTED CloseConnection" << endl;
  110
+}
  111
+
  112
+
  113
+/********************************
  114
+HttpConnection_t::ProcessRequest
  115
+********************************/
  116
+
  117
+void HttpConnection_t::ProcessRequest (const char *method,
  118
+		const char *cookie,
  119
+		const char *ifnonematch,
  120
+		const char *contenttype,
  121
+		const char *query_string,
  122
+		const char *path_info,
  123
+		const char *request_uri,
  124
+		const char *protocol,
  125
+		int post_length,
  126
+		const char *post_content,
  127
+		const char *hdrblock,
  128
+		int hdrblocksize)
  129
+{
  130
+  cerr << "UNIMPLEMENTED ProcessRequest" << endl;
  131
+}
  132
+
  133
+
  134
+/*********************************
  135
+HttpConnection_t::ReceivePostData
  136
+*********************************/
  137
+
  138
+void HttpConnection_t::ReceivePostData (const char *data, int len)
  139
+{
  140
+	cerr << "UNIMPLEMENTED ReceivePostData" << endl;
  141
+}
  142
+
  143
+/*****************************
  144
+HttpConnection_t::ConsumeData
  145
+*****************************/
  146
+
  147
+void HttpConnection_t::ConsumeData (const char *data, int length)
  148
+{
  149
+	if (ProtocolState == EndState)
  150
+		return;
  151
+
  152
+	if ((length > 0) && !data)
  153
+		throw std::runtime_error ("bad args consuming http data");
  154
+
  155
+	while (length > 0) {
  156
+		//----------------------------------- BaseState
  157
+		// Initialize for a new request. Don't consume any data.
  158
+		// For anal-retentive security we may want to bzero the header block.
  159
+		if (ProtocolState == BaseState) {
  160
+			ProtocolState = PreheaderState;
  161
+			nLeadingBlanks = 0;
  162
+			HeaderLinePos = 0;
  163
+			HeaderBlockPos = 0;
  164
+			ContentLength = 0;
  165
+			ContentPos = 0;
  166
+			bRequestSeen = false;
  167
+			bContentLengthSeen = false;
  168
+			if (_Content) {
  169
+				free ((void*)_Content);
  170
+				_Content = NULL;
  171
+			}
  172
+			RequestMethod = NULL;
  173
+			Cookie.clear();
  174
+			IfNoneMatch.clear();
  175
+			ContentType.clear();
  176
+			PathInfo.clear();
  177
+			RequestUri.clear();
  178
+			QueryString.clear();
  179
+			Protocol.clear();
  180
+
  181
+			if (bSetEnvironmentStrings) {
  182
+				unsetenv ("REQUEST_METHOD");
  183
+				unsetenv ("HTTP_COOKIE");
  184
+				unsetenv ("IF_NONE_MATCH");
  185
+				unsetenv ("CONTENT_TYPE");
  186
+				unsetenv ("PATH_INFO");
  187
+				unsetenv ("REQUEST_URI");
  188
+				unsetenv ("QUERY_STRING");
  189
+				unsetenv ("PROTOCOL");
  190
+			}
  191
+		}
  192
+
  193
+		//----------------------------------- PreheaderState
  194
+		// Consume blank lines (but not too many of them)
  195
+		while ((ProtocolState == PreheaderState) && (length > 0)) {
  196
+			if ((*data == '\r') || (*data == '\n')) {
  197
+				data++;
  198
+				length--;
  199
+				nLeadingBlanks++;
  200
+				if (nLeadingBlanks > MaxLeadingBlanks) {
  201
+					// TODO, log this.
  202
+					goto fail_connection;
  203
+				}
  204
+			}
  205
+			else
  206
+				ProtocolState = HeaderState;
  207
+		}
  208
+
  209
+		//----------------------------------- HeaderState
  210
+		// Read HTTP headers.
  211
+		// This processing depends on the fact that the end
  212
+		// of the data buffer we receive will have a null terminator
  213
+		// just after the last byte indicated by the length parameter.
  214
+		// Cf notes in ConnectionDescriptor::Read.
  215
+		while ((ProtocolState == HeaderState) && (length > 0)) {
  216
+			if (*data == '\n') {
  217
+				HeaderLine [HeaderLinePos] = 0;
  218
+				if (!_InterpretHeaderLine (HeaderLine))
  219
+					goto send_error;
  220
+				if (HeaderLinePos == 0) {
  221
+					if (ContentLength > 0) {
  222
+						if (_Content)
  223
+							free (_Content);
  224
+						_Content = NULL;
  225
+						if (bAccumulatePost) {
  226
+							_Content = (char*) malloc (ContentLength + 1);
  227
+							if (!_Content)
  228
+								throw std::runtime_error ("resource exhaustion");
  229
+						}
  230
+						ContentPos = 0;
  231
+						ProtocolState = ReadingContentState;
  232
+					}
  233
+					else
  234
+						ProtocolState = DispatchState;
  235
+				}
  236
+				HeaderLinePos = 0;
  237
+				data++;
  238
+				length--;
  239
+			}
  240
+			else if (*data == '\r') {
  241
+				// ignore \r
  242
+				data++;
  243
+				length--;
  244
+			}
  245
+			else {
  246
+				const char *nl = strpbrk (data, "\r\n");
  247
+				int len = nl ? (nl - data) : length;
  248
+				if ((size_t)(HeaderLinePos + len) >= sizeof(HeaderLine)) {
  249
+					// TODO, log this
  250
+					goto fail_connection;
  251
+				}
  252
+				memcpy (HeaderLine + HeaderLinePos, data, len);
  253
+				data += len;
  254
+				length -= len;
  255
+				HeaderLinePos += len;
  256
+			}
  257
+		}
  258
+
  259
+
  260
+		//----------------------------------- ReadingContentState
  261
+		// Read POST content.
  262
+		while ((ProtocolState == ReadingContentState) && (length > 0)) {
  263
+			int len = ContentLength - ContentPos;
  264
+			if (len > length)
  265
+				len = length;
  266
+
  267
+			if (bAccumulatePost)
  268
+				memcpy (_Content + ContentPos, data, len);
  269
+			else
  270
+				ReceivePostData (data, len);
  271
+
  272
+			data += len;
  273
+			length -= len;
  274
+			ContentPos += len;
  275
+			if (ContentPos == ContentLength) {
  276
+				if (bAccumulatePost)
  277
+					_Content[ContentPos] = 0;
  278
+				ProtocolState = DispatchState;
  279
+			}
  280
+		}
  281
+
  282
+
  283
+		//----------------------------------- DispatchState
  284
+		if (ProtocolState == DispatchState) {
  285
+			ProcessRequest (RequestMethod, Cookie.c_str(), IfNoneMatch.c_str(), ContentType.c_str(), QueryString.c_str(), PathInfo.c_str(), RequestUri.c_str(), Protocol.c_str(), ContentLength, _Content, HeaderBlock, HeaderBlockPos);
  286
+			ProtocolState = BaseState;
  287
+		}
  288
+	}
  289
+
  290
+	return;
  291
+
  292
+	fail_connection:
  293
+	// For protocol errors or security violations- kill the connection dead.
  294
+	CloseConnection (false);
  295
+	ProtocolState = EndState;
  296
+	return;
  297
+
  298
+	send_error:
  299
+	// for HTTP-level errors that will send back a response to the client.
  300
+	CloseConnection (true);
  301
+	ProtocolState = EndState;
  302
+	return;
  303
+
  304
+}
  305
+
  306
+
  307
+/**************************************
  308
+HttpConnection_t::_InterpretHeaderLine
  309
+**************************************/
  310
+
  311
+bool HttpConnection_t::_InterpretHeaderLine (const char *header)
  312
+{
  313
+	/* Return T/F to indicate whether we should continue processing
  314
+	 * this request. Return false to indicate that we detected a fatal
  315
+	 * error or other condition which should cause us to drop the
  316
+	 * connection.
  317
+	 * BY DEFINITION, this doesn't define any immediate fatal errors.
  318
+	 * That may need to change, in which case we'll have to return
  319
+	 * an error code rather than T/F, so the caller will know whether
  320
+	 * to drop the connection gracefully or not.
  321
+	 *
  322
+	 * There's something odd and possibly undesirable about how we're
  323
+	 * doing this. We fully process each header (including the request)
  324
+	 * _as we see it,_ and not at the end when all the headers have
  325
+	 * been seen. This saves us the trouble of keeping them all around
  326
+	 * and possibly parsing them twice, but it also means that when
  327
+	 * we emit errors from here (that generate HTTP responses other than
  328
+	 * 200 and therefore close the connection), we do so _immediately_
  329
+	 * and before looking at the rest of the headers. That might surprise
  330
+	 * and confuse some clients.
  331
+	 *
  332
+	 * Revised 27Sep06, we now store all the headers in one place, on a
  333
+	 * per-request basis, for the purpose of making them available to
  334
+	 * downstream users. At present this involves an undesirable extra
  335
+	 * memory copy. Eventually should rework the main header processing
  336
+	 * so it can be done in place.
  337
+	 */
  338
+
  339
+	if (!header) // an assert, really.
  340
+		throw std::runtime_error ("bad arg interpreting headers");
  341
+
  342
+	if (!bRequestSeen) {
  343
+		bRequestSeen = true;
  344
+		return _InterpretRequest (header);
  345
+	}
  346
+
  347
+	if (!strncasecmp (header, "content-length:", 15)) {
  348
+		if (bContentLengthSeen) {
  349
+			// TODO, log this. There are some attacks that depend
  350
+			// on sending more than one content-length header.
  351
+			_SendError (406);
  352
+			return false;
  353
+		}
  354
+		bContentLengthSeen = true;
  355
+		const char *s = header + 15;
  356
+		while (*s && ((*s==' ') || (*s=='\t')))
  357
+			s++;
  358
+		ContentLength = atoi (s);
  359
+		if (ContentLength > MaxContentLength) {
  360
+			// TODO, log this.
  361
+			_SendError (406);
  362
+			return false;
  363
+		}
  364
+	}
  365
+	else if (!strncasecmp (header, "cookie:", 7)) {
  366
+		const char *s = header + 7;
  367
+		while (*s && ((*s==' ') || (*s=='\t')))
  368
+			s++;
  369
+		Cookie = s;
  370
+		if (bSetEnvironmentStrings)
  371
+			setenv ("HTTP_COOKIE", s, true);
  372
+	}
  373
+	else if (!strncasecmp (header, "If-none-match:", 14)) {
  374
+		const char *s = header + 14;
  375
+		while (*s && ((*s==' ') || (*s=='\t')))
  376
+			s++;
  377
+		IfNoneMatch = s;
  378
+		if (bSetEnvironmentStrings)
  379
+			setenv ("IF_NONE_MATCH", s, true);
  380
+	}
  381
+	else if (!strncasecmp (header, "Content-type:", 13)) {
  382
+		const char *s = header + 13;
  383
+		while (*s && ((*s==' ') || (*s=='\t')))
  384
+			s++;
  385
+		ContentType = s;
  386
+		if (bSetEnvironmentStrings)
  387
+			setenv ("CONTENT_TYPE", s, true);
  388
+	}
  389
+
  390
+
  391
+	// Copy the incoming header into a block
  392
+	if ((HeaderBlockPos + strlen(header) + 1) < HeaderBlockSize) {
  393
+		int len = strlen(header);
  394
+		memcpy (HeaderBlock+HeaderBlockPos, header, len);
  395
+		HeaderBlockPos += len;
  396
+		HeaderBlock [HeaderBlockPos++] = 0;
  397
+	}
  398
+	else {
  399
+		// TODO, log this.
  400
+		_SendError (406);
  401
+		return false;
  402
+	}
  403
+
  404
+	return true;
  405
+}
  406
+
  407
+
  408
+/***********************************
  409
+HttpConnection_t::_InterpretRequest
  410
+***********************************/
  411
+
  412
+bool HttpConnection_t::_InterpretRequest (const char *header)
  413
+{
  414
+	/* Return T/F to indicate whether we should continue processing
  415
+	 * this request. Return false to indicate that we detected a fatal
  416
+	 * error or other condition which should cause us to drop the
  417
+	 * connection.
  418
+	 * Interpret the contents of the given line as an HTTP request string.
  419
+	 * WE ASSUME the passed-in header is not null.
  420
+	 *
  421
+	 * In preparation for a CGI-style call, we set the following
  422
+	 * environment strings here (other code will DEPEND ON ALL OF
  423
+	 * THESE BEING SET HERE in case there are no errors):
  424
+	 * REQUEST_METHOD, PATH_INFO, QUERY_STRING.
  425
+	 *
  426
+	 * Oh and by the way, this code sucks. It's reasonably fast
  427
+	 * but not terribly fast, and it's ugly. Refactor someday.
  428
+	 */
  429
+
  430
+	const char *blank = strchr (header, ' ');
  431
+	if (!blank) {
  432
+		_SendError (406);
  433
+		return false;
  434
+	}
  435
+
  436
+	if (!_DetectVerbAndSetEnvString (header, blank - header))
  437
+		return false;
  438
+
  439
+	blank++;
  440
+	if (*blank != '/') {
  441
+		_SendError (406);
  442
+		return false;
  443
+	}
  444
+
  445
+	const char *blank2 = strchr (blank, ' ');
  446
+	if (!blank2) {
  447
+		_SendError (406);
  448
+		return false;
  449
+	}
  450
+	if (strcasecmp (blank2 + 1, "HTTP/1.0") && strcasecmp (blank2 + 1, "HTTP/1.1")) {
  451
+		_SendError (505);
  452
+		return false;
  453
+	}
  454
+
  455
+	string prot (blank2+1);
  456
+	Protocol = prot.c_str();
  457
+
  458
+	// Here, the request starts at blank and ends just before blank2.
  459
+	// Find the query-string (?) and/or fragment (#,;), if either are present. 
  460
+	const char *questionmark = strchr (blank, '?');
  461
+	if (questionmark && (questionmark >= blank2))
  462
+		questionmark = NULL;
  463
+	const char *fragment = strpbrk ((questionmark ? (questionmark+1) : blank), "#;");
  464
+	if (fragment && (fragment >= blank2))
  465
+		fragment = NULL;
  466
+
  467
+	if (questionmark) {
  468
+		string req (blank, questionmark - blank);
  469
+		PathInfo = req.c_str();
  470
+		RequestUri = req.c_str();
  471
+		string qs (questionmark+1, fragment ? (fragment - (questionmark+1)) : (blank2 - (questionmark+1)));
  472
+		QueryString = qs.c_str();
  473
+
  474
+		if (bSetEnvironmentStrings) {
  475
+			setenv ("PATH_INFO", req.c_str(), true);
  476
+			setenv ("REQUEST_URI", req.c_str(), true);
  477
+			setenv ("QUERY_STRING", qs.c_str(), true);
  478
+			setenv ("PROTOCOL", prot.c_str(), true);
  479
+		}
  480
+	}
  481
+	else if (fragment) {
  482
+		string req (blank, fragment - blank);
  483
+		PathInfo = req.c_str();
  484
+		RequestUri = req.c_str();
  485
+		QueryString.clear();
  486
+		if (bSetEnvironmentStrings) {
  487
+			setenv ("PATH_INFO", req.c_str(), true);
  488
+			setenv ("REQUEST_URI", req.c_str(), true);
  489
+			setenv ("QUERY_STRING", "", true);
  490
+			setenv ("PROTOCOL", prot.c_str(), true);
  491
+		}
  492
+	}
  493
+	else {
  494
+		string req (blank, blank2 - blank);
  495
+		PathInfo = req.c_str();
  496
+		RequestUri = req.c_str();
  497
+		QueryString.clear();
  498
+		if (bSetEnvironmentStrings) {
  499
+			setenv ("PATH_INFO", req.c_str(), true);
  500
+			setenv ("REQUEST_URI", req.c_str(), true);
  501
+			setenv ("QUERY_STRING", "", true);
  502
+			setenv ("PROTOCOL", prot.c_str(), true);
  503
+		}
  504
+	}
  505
+	
  506
+	return true;
  507
+}
  508
+
  509
+
  510
+/********************************************
  511
+HttpConnection_t::_DetectVerbAndSetEnvString
  512
+********************************************/
  513
+
  514
+bool HttpConnection_t::_DetectVerbAndSetEnvString (const char *request, int verblength)
  515
+{
  516
+	/* Helper method for _InterpretRequest.
  517
+	 * WE MUST SET THE ENV STRING "REQUEST_METHOD" HERE
  518
+	 * unless there is an error.
  519
+	 * The hardcoded verbs MUST be static, as we'll carry around pointers to them.
  520
+	 */
  521
+
  522
+	static const char *verbs[] = {
  523
+		"GET",
  524
+		"POST",
  525
+		"PUT",
  526
+		"DELETE",
  527
+		"HEAD"
  528
+	};
  529
+
  530
+	int n_verbs = sizeof(verbs) / sizeof(const char*);
  531
+
  532
+	// Warning, this algorithm is vulnerable to head-matches,
  533
+	// so compare the longer head-matching strings first.
  534
+	// We could fix this if we included the blank in the search
  535
+	// string but then we'd have to lop it off in the env string.
  536
+	// ALSO NOTICE the early return on success.
  537
+	for (int i=0; i < n_verbs; i++) {
  538
+		if (!strncasecmp (request, verbs[i], verblength) && (strlen(verbs[i]) == (size_t)verblength)) {
  539
+			RequestMethod = verbs[i];
  540
+			if (bSetEnvironmentStrings)
  541
+				setenv ("REQUEST_METHOD", verbs[i], 1);
  542
+			return true;
  543
+		}
  544
+	}
  545
+
  546
+	_SendError (405);
  547
+	return false;
  548
+}
  549
+
  550
+
  551
+
  552
+/****************************
  553
+HttpConnection_t::_SendError
  554
+****************************/
  555
+
  556
+void HttpConnection_t::_SendError (int code)
  557
+{
  558
+	stringstream ss;
  559
+	ss << "HTTP/1.1 " << code << " ...\r\n";
  560
+	ss << "Connection: close\r\n";
  561
+	ss << "Content-type: text/plain\r\n";
  562
+	ss << "\r\n";
  563
+	ss << "Detected error: HTTP code " << code;
  564
+
  565
+	SendData (ss.str().c_str(), ss.str().length());
  566
+}
117  ext/http.h
... ...
@@ -0,0 +1,117 @@
  1
+/*****************************************************************************
  2
+
  3
+$Id: http.h 3966 2007-03-16 11:52:05Z francis $
  4
+
  5
+File:     http.h
  6
+Date:     21Apr06
  7
+
  8
+Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
  9
+Gmail: garbagecat10
  10
+
  11
+This program is free software; you can redistribute it and/or modify
  12
+it under the terms of the GNU General Public License as published by
  13
+the Free Software Foundation; either version 2 of the License, or
  14
+(at your option) any later version.
  15
+
  16
+This program is distributed in the hope that it will be useful,
  17
+but WITHOUT ANY WARRANTY; without even the implied warranty of
  18
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19
+GNU General Public License for more details.
  20
+
  21
+You should have received a copy of the GNU General Public License
  22
+along with this program; if not, write to the Free Software
  23
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  24
+
  25
+*****************************************************************************/
  26
+
  27
+
  28
+#ifndef __HttpPersonality__H_
  29
+#define __HttpPersonality__H_
  30
+
  31
+
  32
+
  33
+/**********************
  34
+class HttpConnection_t
  35
+**********************/
  36
+
  37
+class HttpConnection_t
  38
+{
  39
+	public:
  40
+		HttpConnection_t();
  41
+		virtual ~HttpConnection_t();
  42
+
  43
+		void ConsumeData (const char*, int);
  44
+
  45
+		virtual void SendData (const char*, int);
  46
+		virtual void CloseConnection (bool after_writing);
  47
+		virtual void ProcessRequest (const char *method,
  48
+				const char *cookie,
  49
+				const char *ifnonematch,
  50
+				const char *content_type,
  51
+				const char *query_string,
  52
+				const char *path_info,
  53
+				const char *request_uri,
  54
+				const char *protocol,
  55
+				int postlength,
  56
+				const char *postdata,
  57
+				const char* hdrblock,
  58
+				int hdrblksize);
  59
+
  60
+		virtual void ReceivePostData(const char *data, int len);
  61
+		virtual void SetNoEnvironmentStrings() {bSetEnvironmentStrings = false;}
  62
+		virtual void SetDontAccumulatePost() {bAccumulatePost = false;}
  63
+
  64
+  private:
  65
+
  66
+		enum {
  67
+			BaseState,
  68
+			PreheaderState,
  69
+			HeaderState,
  70
+			ReadingContentState,
  71
+			DispatchState,
  72
+			EndState
  73
+		} ProtocolState;
  74
+
  75
+		enum {
  76
+			MaxLeadingBlanks = 12,
  77
+			MaxHeaderLineLength = 8 * 1024,
  78
+			MaxContentLength = 20 * 1024 * 1024,
  79
+			HeaderBlockSize = 16 * 1024
  80
+		};
  81
+		int nLeadingBlanks;
  82
+